• [其他] 【故障】jdbc执行语句报错:prepared statement "S_x" already exists
    jdbc执行语句报错:prepared statement "S_x" already exists规避方式:可通过设置preparethreashold=0规避
  • [其他] 【性能】批量绑定执行PBE形式语句性能分析
    基本功能介绍在客户端执行批量的插入和更新的时候可以使用PEB的批量绑定功能。在服务端通过support_batch_bind参数进行控制。在ODBC端通过配置 odbc.ini文件中 UseBatchProtocol=1来开启这个功能。在JDBC端通过通过调用addBatch和executeBatch接口来使用该功能。代码调用示例(完整代码参考产品手册基于JDBC开发章节):批量插入性能通过执行上面的测试用例,插入3W条语句耗时,20S左右。通过后台日志和元组信息,可以看到该语句的执行过程是做了一次prepare, 一次批量执行完成插入的,对比早期的版本,性能要提升三倍以上。通过观察上面的事务信息,可以发现是在同一个事务中完成的批量插入。对比C80的版本,没有实现批量插入功能,执行3W条语句的插入耗时80s左右。通过分析后台日志和元组信息发现是一条条执行的插入。因此性能要差一些。因此在支持批量绑定的版本上,在执行数据小批量的插入的时候要通过批量绑定的形式进行。这种情况下的执行流程:1次prepare  n次bind, 1次execute。当然如果需要大批量的数据导入还是要选用通过GDS导入。
  • [技术干货] RowBounds
    RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据,因为 MyBatis 是对 jdbc 的封装,在 jdbc 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在你执行 next()的时候,去查询更多的数据。就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,所以你要取 4 次才能把钱取完。只是对于 jdbc 来说,当你调用 next()的时候会自动帮你完成查询工作。这样做的好处可以有效的防止内存溢出。
  • [开发应用] 【DWS】【JDBC连接配置】时区配置
    JDBC的连接URL这么写有问题不,时区显示设置成PRC。同时如果集群是UTC的时区,但是库设置了PRC,那通过jdbc连接的时候,将mysql库内的时间字段通过代码映射到dws的对应字段进行数据导入是否会因为集群的时区是UTC的原因,使得dws内存放的时间数据与mysql源库的时间数据不一致?
  • [新手课堂] Spring 学习笔记
    Spring介绍Spring 是一个开源框架,是一个分层的 JavaEE 一站式框架。所谓一站式框架是指 Spring 有 JavaEE 开发的每一层解决方案。WEB层:SpringMVCService层:Spring的Bean管理,声明式事务DAO层:Spring的JDBC模板,ORM模板优点:IOC:方便解耦合AOP:对程序进行扩展轻量级框架方便与其他框架整合Spring使用Spring开发包解压后的目录介绍:docs: Spring 开发规范和APIlibs: Spring jar 包和源代码schema: Spring 配置文件的约束 DataAccess 用于数据访问,WEB 用于页面显示,核心容器也就是IOC部分。 控制反转(IOC)控制反转(Inversion of Control)是指将对象的创建权反转(交给)Spring。使用IOC就需要导入IOC相关的包,也就是上图中核心容器中的几个包:beans,context,core,expression四个包。 实现原理传统方式创建对象:UserDAO userDAO=new UserDAO();进一步面向接口编程,可以多态:UserDAO userDAO=new UserDAOImpl();这种方式的缺点是接口和实现类高耦合,切换底层实现类时,需要修改源代码。程序设计应该满足OCP元祖,在尽量不修改程序源代码的基础上对程序进行扩展。此时,可以使用工厂模式:class BeanFactory{    public static UserDAO getUserDAO(){        return new UserDAOImpl();    }}此种方式虽然在接口和实现类之间没有耦合,但是接口和工厂之间存在耦合。使用工厂+反射+配置文件的方式,实现解耦,这也是 Spring 框架 IOC 的底层实现。//xml配置文件//<bean id="userDAO" class="xxx.UserDAOImpl"></bean>class BeanFactory{    public static Object getBean(String id){        //解析XML        //反射        Class clazz=Class.forName();        return clazz.newInstance();    }}IOC XML 开发在 docs 文件中包含了 xsd-configuration.hmtl 文件。其中定义了 beans schema。<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    //在此配置bean    <bean id="userService" class="x.y.UserServiceImpl">    </bean></beans>调用类:ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService=(UserService)applicationContext.getBean("userService");userService.save();IOC 和 DIDI 指依赖注入,其前提是必须有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入进来。例如,在UserServiceImpl.java中:public class UserServiceImpl implements UserService{private String name;public void setName(String name){this.name=name;}public void save(){System.out.println("save "+name);}}在配置文件中:<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="userService" class="spring.demo1.UserServiceImpl">    <!--配置依赖的属性-->     <property name="name" value="tony"/>    </bean></beans>测试代码:@Testpublic void demo2(){//创建Spring工厂ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService=(UserService)applicationContext.getBean("userService");userService.save();}运行结果:save tony可以看到,在配置文件中配置的属性,在 Spring 管理该类的时候将其依赖的属性成功进行了设置。如果不使用依赖注入,则无法使用接口,只能使用实现类来进行设置,因为接口中没有该属性。Spring 的工厂类BeanFactory: 老版本的工厂类,在调用getBean()方法时,才会生成类的实例。ApplicationContext: 在加载配置文件的时候,就会将 Spring 管理的类都实例化。有两个实现类:ClassPathXmlApplicationContext: 加载类路径下的配置文件FileSystemXmlApplicationContext: 加载磁盘下的配置文件bean标签配置id: 唯一约束,不能出现特殊字符name: 理论上可以重复,但是开发中最好不要。可以出现特殊字符生命周期:init-method: bean被初始化的时候执行的方法destroy-method: bean被销毁的时候执行的方法作用范围:scope: bean的作用范围,有如下几种,常用的是前两种singleton: 默认使用单例模式创建prototype: 多例request: 在web项目中,spring 创建类后,将其存入到 request 范围中session: 在web项目中,spring 创建类后,将其存入到 session 范围中globalsession: 在web项目中,必须用在 porlet 环境属性注入设置构造方法方式的属性注入: Car 类在构造方法中有两个属性,分别为 name 和 price。<bean id="car" class="demo.Car">    <constructor-arg name="name" value="bmw">    <constructor-arg name="price" value="123"></bean>set 方法属性注入: Employee 类在有两个 set 方法,分别设置普通类型的 name 和引用类型的 Car (使用 ref 指向引用类型的 id 或  name)。<bean id="employee" class="demo.Employee">    <property name="name" value="xiaoming">    <property name="car" ref="car"></bean>P名称空间的属性注入: 首先需要引入p名称空间:<beans xmlns="http://www.springframework.org/schema/beans"    //引入p名称空间    xmlns:p="http://www.springframework.org/schema/p"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></beans>如果是普通属性:<bean id="car" class="demo.Car" p:name="bmv" p:price="123"></bean>如果是引用类型:<bean id="employee" class="demo.Employee" p:name="xiaoming" p:car-ref:"car"></bean>SpEL(Spring Expression Language)属性注入(Spring 3.x以上版本)<bean id="car" class="demo.Car">    <property name="name" value="#{'xiaoming'}">    <property name="car" ref="#{car}"></bean>集合类型属性注入:<bean id="car" class="demo.Car">    <property name="namelist">        <list>            <value>qirui</value>            <value>baoma</value>            <value>benchi</value>        </list>    </property></bean>多模块开发配置在加载配置文件的时候,加载多个配置文件在一个配置文件中引入多个配置文件,通过实现IOC 注解开发示例引入jar包: 除了要引入上述的四个包之外,还需要引入aop包。创建 applicationContext.xml ,使用注解开发引入 context 约束(xsd-configuration.html)<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">         <!-- bean definitions here --></beans>组件扫描: 使用IOC注解开发,需要配置组件扫描,也就是哪些包下的类使用IOC的注解。<context:component-scan base-package="demo1">在类上添加注解使用注解设置属性的值属性如果有set方法,将属性注入的注解添加到set方法属性没有set方法,将注解添加到属性上。@Component("UserDao")//相当于配置了一个<bean> 其id为UserDao,对应的类为该类public class UserDAOImpl implements UserDAO {@Overridepublic void save() {// TODO Auto-generated method stubSystem.out.println("save");} }注解详解@Component组件注解,用于修饰一个类,将这个类交给 Spring 管理。有三个衍生的注解,功能类似,也用来修饰类。@Controller:修饰 web 层类@Service:修饰 service 层类@Repository:修饰 dao 层类2.属性注入普通属性使用 @Value 来设置属性的值对象属性使用 @Autowired  ,这个注解是按照类型来进行属性注入的。如果希望按照 bean 的名称或id进行属性注入,需要用 @Autowired 和 @Qualifier 一起使用实际开发中,使用 @Resource(name=" ") 来进行按照对象的名称完成属性注入3.其他注解@PostConstruct 相当于 init-method,用于初始化函数的注解@PreDestroy 相当于 destroy-method,用于销毁函数的注解@Scope 作用范围的注解,常用的是默认单例,还有多例 @Scope("prototype")IOC 的 XML 和注解开发比较适用场景:XML 适用于任何场景;注解只适合自己写的类,不是自己提供的类无法添加注解。可以使用 XML 管理 bean,使用注解来进行属性注入AOP开发AOP 是 Aspect Oriented Programming 的缩写,意为面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,是OOP的延续。AOP 能够对程序进行增强,在不修改源码的情况下,可以进行权限校验,日志记录,性能监控,事务控制等。也就是说功能分为两大类,一类是核心业务功能,一类是辅助增强功能。两类功能彼此独立进行开发。比如登录功能是核心业务功能,日志功能是辅助增强功能,如果有需要,将日志和登录编制在一起。辅助功能就称为切面,这种能选择性的、低耦合的把切面和核心业务功能结合的编程思想称为切面编程。底层实现JDK 动态代理只能对实现了接口的类产生代理。Cglib 动态代理可以对没有实现接口的类产生代理对象,生成的是子类对象。使用 JDK 动态代理:public interface UserDao {public void insert();public void delete();public void update();public void query();}实现类:public class UserDaoImpl implements UserDao { @Override public void insert() { System.out.println("insert"); } @Override public void delete() { System.out.println("delete"); } @Override public void update() { System.out.println("update"); } @Override public void query() { System.out.println("query"); } }JDK 代理:public class JDKProxy implements InvocationHandler{private UserDao userDao;public JDKProxy(UserDao userDao){this.userDao=userDao;}public UserDao createProxy(){UserDao userDaoProxy=(UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(), this);return userDaoProxy;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if("update".equals(method.getName())){System.out.println("权限校验");return method.invoke(userDao, args);}return method.invoke(userDao, args);}}通过动态代理增强了 update 函数。 测试类:public class Demo1 {@Testpublic void demo1(){UserDao userDao=new UserDaoImpl();UserDao proxy=new JDKProxy(userDao).createProxy();proxy.insert();proxy.delete();proxy.update();proxy.query();}}运行结果为:insertdelete权限校验updatequeryCglibCglib 是第三方开源代码生成类库,可以动态添加类的属性和方法。与上边JDK代理不同,Cglib的使用方式如下:public class CglibProxy implements MethodInterceptor{//传入增强的对象private UserDao customerDao;public CglibProxy(UserDao userDao){this.userDao=userDao;}public UserDao createProxy(){Enhancer enhancer=new Enhancer();enhancer.setSuperclass(userDao.getClass());enhancer.setCallback(this);UserDao proxy=(UserDao)enhancer.create();return proxy;}@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {if("save".equals(method.getName())){System.out.println("enhance function");return methodProxy.invokeSuper(proxy, args);}return methodProxy.invokeSuper(proxy, args);}}如果实现了接口的类,底层采用JDK代理。如果不是实现了接口的类,底层采用 Cglib代理。IOC与传统方式的比较获取对象方式:传统通过 new 关键字主动创建一个对象。IOC 方式中,将对象的生命周期交给 Spring 管理,直接从 Spring 获取对象。也就是控制反转————将控制权从自己手中交到了 Spring 手中。Spring 的 AOP 开发(AspectJ 的 XML 方式)AspectJ 是一个 AOP 的框架,Spring 引入 AspectJ,基于 AspectJ 进行 AOP 的开发。相关术语Joinpoint: 连接点,可以被拦截到的点。也就是可以被增强的方法都是连接点。Pointcut: 切入点,真正被拦截到的点,也就是真正被增强的方法Advice: 通知,方法层面的增强。对某个方法进行增强的方法,比如对 save 方法进行权限校验,权限校验的方法称为通知。Introduction: 引介,类层面的增强。Target: 目标,被增强的对象(类)。Weaving: 织入,将 advice 应用到 target 的过程。Proxy: 代理对象,被增强的对象。Aspect: 切面,多个通知和多个切入点的组合。使用方法引入相关包引入配置文件<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --></beans>编写目标类并配置:public class ProductDaoImpl implements ProductDao {@Overridepublic void save() {System.out.println("save");}@Overridepublic void update() {System.out.println("update");}@Overridepublic void find() {System.out.println("find");}@Overridepublic void delete() {System.out.println("delete");}}<bean id="productDao" class="demo1.ProductDaoImpl"></bean>编写切面类,假设用于权限验证并配置public class MyAspectXML {public void checkPri(){System.out.println("check auth");}}<bean id="myAspect" class="demo1.MyAspectXML"></bean>通过AOP配置完成对目标类的增强<aop:config><aop:pointcut expression="execution(* demo1.ProductDaoImpl.save(..))" id="pointcut1"/><aop:aspect ref="myAspect"><aop:before method="chechPri" pointcut-ref="pointcut1"/></aop:aspect> </aop:config> 通知类型前置通知:在目标方法执行前操作,可以获得切入点信息<aop:before method="chechPri" pointcut-ref="pointcut1"/>public void checkPri(JoinPoint joinPoint){System.out.println("check auth "+joinPoint);}后置通知:在目标方法执行后操作,可以获得方法返回值<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>public void writeLog(Object result){    System.out.println("writeLog "+result);}环绕通知:在目标方法执行前和后操作,可以阻止目标方法执<aop:around method="around" pointcut-ref="pointcut3"/>public Object around(ProceedingJoinPoint joinPoint) throws Throwable{System.out.println("before");Object result=joinPoint.proceed();System.out.println("after");return result;}异常抛出通知:程序出现异常时操作<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>public void afterThrowing(Throwable ex){System.out.println("exception "+ex.getMessage());}最终通知:相当于finally块,无论代码是否有异常,都会执行<aop:after method="finallyFunc" pointcut-ref="pointcut4"/>public void finallyFunc(){System.out.println("finally");}引介通知:不常用Spring 切入点表达式基于 execution 函数完成语法:[访问修饰符] 方法返回值 包名.类名.方法名(参数)其中任意字段可以使用*代替表示任意值Spring 的 AOP 基于 AspectJ 注解开发开发步骤引入jar包设置配置文件:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"></beans>编写配置目标类<bean id="orderDao" class="demo1.OrderDao"></bean>public class OrderDao {public void save(){System.out.println("save order");}public void update(){System.out.println("update order");}public void delete(){System.out.println("delete order");}public void find(){System.out.println("find order");}}开启aop注解自动代理<aop:aspectj-autoproxy/>编写切面类并配置@Aspectpublic class MyAspectAnno {@Before(value="execution(* demo1.OrderDao.save(..))")public void before(){System.out.println("before");}}<bean id="myAspect" class="demo1.MyAspectAnno">注解通知类型@Before: 前置通知@AfterReturning: 后置通知@AfterReturning(value="execution(* demo1.OrderDao.save(..))",returning="result")public void after(Object result){System.out.println("after "+result);}@Around:环绕通知@Around(value="execution(* demo1.OrderDao.save(..))")public Object around(ProceedingJoinPoint joinPoint) throws Throwable{System.out.println("before");Object obj=joinPoint.proceed();System.out.println("after");return obj;}@AfterThrowing: 抛出异常@AfterThrowing(value="execution(* demo1.OrderDao.save(..))",throwing="e")public void afterThrowing(Throwable e){System.out.println("exception:"+e.getMessage();}@After: 最终通知@After(value="execution(* demo1.OrderDao.save(..))")public void after(){System.out.println("finally");}@PointCut:切入点注解@PointCut(value="execution(* demo1.OrderDao.save(..))")private void pointcut1(){}此时,在上述通知的注解中,value可以替换为该函数名,例如:@After(value="MyAspect.pointcut1()")public void after(){System.out.println("finally");}这个注解的好处是,只需要维护切入点即可,不用在修改时修改每个注解。Spring 的 JDBC 模板Spring 对持久层也提供了解决方案,也就是 ORM 模块和 JDBC 的模板。针对 JDBC ,提供了 org.springframework.jdbc.core.JdbcTemplate 作为模板类。使用 JDBC 模板引入jar包,数据库驱动,Spring 的 jdbc 相关包。基本使用:public void demo1(){    //创建连接池DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///spring4");dataSource.setUsername("root");dataSource.setPassword("123456");//创建JDBC模板 JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);jdbcTemplate.update("insert into account values (null,?,?)", "xiaoming",1000d);}将连接池和模板交给 Spring 管理配置文件:<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource;"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql:///spring4"></property><property name="username" value="root"></property><property name="password" value="123456"></property></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate;"> <property name="dataSource" ref="dataSource"></property></bean>测试文件: @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class JdbcDemo2 {@Resource(name="jdbcTemplate")private JdbcTemplate jdbcTemplate;@Testpublic void demo2(){jdbcTemplate.update("insert into account values (null,?,?)", "xiaolan",1000d);}}使用开源数据库连接池使用 DBCP 的配置:<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql://192.168.66.128/spring4"></property><property name="username" value="root"></property><property name="password" value="123456"></property>使用 C3P0 的配置:<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql://192.168.66.128/spring4"></property><property name="user" value="root"></property><property name="password" value="123456"></property></bean>引入外部属性文件首先建立外部属性文件:jdbc.driverClass=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://192.168.66.128/spring4jdbc.username=rootjdbc.password=123456然后对属性文件进行配置:<context:property-placeholder location="classpath:jdbc.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driverClass}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean>CRUD操作insert, update, delete 语句都借助模板的 update 方法进行操作。public void demo(){jdbcTemplate.update("insert into account values (null,?,?)", "xiaoda",1000d);jdbcTemplate.update("update account set name=?,money=? where id=?", "xiaoda",1000d,2);jdbcTemplate.update("delete from account where id=?", 6);}查询操作:public void demo3(){String name=jdbcTemplate.queryForObject("select name from account where id=?",String.class,5);long count=jdbcTemplate.queryForObject("select count(*) from account",Long.class);}将返回的结果封装成为类:public void demo4(){Account account=jdbcTemplate.queryForObject("select * from account where id=?", new MyRowMapper(),5);}其中:class MyRowMapper implements RowMapper<Account>{@Overridepublic Account mapRow(ResultSet rs, int rowNum) throws SQLException {Account account=new Account();account.setId(rs.getInt("id"));account.setName(rs.getString("name"));account.setMoney(rs.getDouble("money"));return account;}}Spring的事务管理事务事务是指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。具有四个特性:原子性:事务不可分一致性:事务执行前后数据完整性保持一致隔离性:一个事务的执行不应该受到其他事务干扰持久性:一旦事务结束,数据就持久化到数据库如果不考虑隔离性会引发安全性问题:读问题:脏读:一个事务读到另一个事务未提交的数据不可重复读:一个事务读到另一个事务已经提交的 update 数据,导致一个事务中多次查询结果不一致幻读:一个事务读到另一个事务已经提交的 insert 数据,导致一个事务中多次查询结果不一致写问题:丢失更新解决读问题:设置事务隔离级别Read uncommitted: 未提交读,无法解决任何读问题Read committed: 已提交读,解决脏读问题Repeatable read: 重复读,解决脏读和不可重复读问题Serializable:序列化,解决所有读问题事务管理APIPlatformTransactionManager: 平台事务管理器这是一个接口,拥有多个不同的实现类,如 DataSourceTransactionManager 底层使用了JDBC 管理事务; HibernateTransactionManager 底层使用了 Hibernate 管理事务。TransactionDefinition: 事务定义信息用于定义事务的相关信息,如隔离级别、超时信息、传播行为、是否只读等TransactionStatus: 事务的状态用于记录在事务管理过程中,事务的状态的对象。上述API的关系: Spring 在进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务管理,在事务管理过程当中,产生各种此状态,将这些状态信息记录到事务状态的对象当中。事务的传播行为事务的传播行为主要解决业务层(Service)方法相互调用的问题,也就是不同的业务中存在不同的事务时,如何操作。Spring 中提供了7种事务的传播行为,分为三类:保证多个操作在同一个事务中PROPAGATION_REQUIRED: B方法调用A方法,如果A中有事务,使用A中的事务并将B中的操作包含到该事务中;否则新建一个事务,将A和B中的操作包含进来。(默认)PROPAGATION_SUPPORTS:如果A中有事务,使用A的事务;否则不使用事务PROPAGATION_MANDATORY:如果A中有事务,使用A的事务;否则抛出异常保证多个操作不在同一个事务中PROPAGATION_REQUIRES_NEW:如果A中有事务,将其挂起,创建新事务,只包含自身操作。否则,新建一个事务,只包含自身操作。PROPAGATION_NOT_SUPPORTED:如果A中有事务,挂起,不使用事务。PROPAGATION_NEVER:如果A中有事务,抛出异常,也即不能用事务运行。嵌套事务PROPAGATION_NESTED:如果A有事务,按照A的事务执行,执行完成后,设置一个保存点,然后执行B的操作。如果出现异常,可以回滚到最初状态或保存点状态。实例以转账为例,业务层的DAO层类如下:public interface AccountDao {public void outMoney(String from,Double money);public void inMoney(String to,Double money);}public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{@Overridepublic void outMoney(String from, Double money) { this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,from);}@Overridepublic void inMoney(String to, Double money) {this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,to);}}public interface AccountService {public void transfer(String from,String to,Double money);}public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void transfer(String from, String to, Double money) {accountDao.outMoney(from, money);accountDao.inMoney(to, money);}}在xml中进行类的配置:<bean id="accountService" class="tx.demo.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="tx.demo.AccountDaoImpl"><property name="dataSource" ref="dataSource"/></bean> 
  • Jmeter系列(31)- 获取并使用 JDBC Request 返回的数据
    前言 Variable names + Foreach控制器线程组结构树 JDBC Request 调试取样器运行结果 ForEach控制器 循环运行的结果( mobile:${mobile} ) Variable names + 循环控制器和上面的栗子只是换了个控制器而已,没太大变化线程组结构树 循环控制器填写 100,是代表循环100次 计数器从 1 开始,递增加到 100为止,每次递增 1初始值=1每次增加 1最大的值=100(包含)新变量 num 循环控制器内的 Debug Sampler ${__V()} 是关联函数,后面讲到 循环运行的结果( mobile:${mobile} ) 
  • Jmeter系列(30)- 详解 JDBC Request
     JDBC Request JDBC Request 界面介绍 字段含义字段含义Variable Name Bound to Pool数据库连接池配置的名称Query Typesql 语句的类型SQL Querysql 语句语句结尾不需要添加 ; 变量用 ? 占位Parameter values需要传递的变量值,多个变量用 , 分隔Parameter types变量类型Variable Names保存sql语句返回的数据和返回数据的总行数用 , 分隔跳过列用空Result Variable Name一个 Object 变量存储所有返回值Query timeout(s)超时时间;默认0,代表无限时间Limit ResultSet和 limit 类似作用,限制 sql 语句返回结果集的行数Handle ResultSet如何定义 callable statements 返回的结果集;默认是存储为字符串后续通过各种栗子来深入理解常用字段的含义 举栗子的前提需要自己找一个有数据库的数据来练手哦!这里拿的表数据如下哈 只有 sql 语句的栗子JDBC Request没啥特别的,平时 sql 怎么写,这里就怎么写 运行结果 参数化的栗子JDBC Request 运行结果 知识点 参数化+变量的栗子JDBC Request 运行结果 知识点 使用 Variable Names 的栗子结构树 JDBC Request添加一个 Debug Sampler 就知道这个字段有什么作用了 JDBC Request 运行结果 调试取样器运行结果 知识点 使用 Result variable name 的栗子JDBC Request Debug Sampler  运行结果 知识点该变量是个数组,每一个元素代表一条记录 重点关于通过 Variable names、Result variable name 获取到的值如何提取,我们将在下一篇文章中详细讲解 使用 Limit ResultSet 的栗子JDBC Request  运行结果
  • Jmeter系列(29)- 详解 JDBC Connection Configuration
    前言发起 jdbc 请求前,需要有 JDBC 连接配置,即先连上数据库,才能查询数据库 JDBC Connection Configuration JDBC Connection Configuration 界面介绍 Variable Name for created poolJDBC Connection Configuration 算是一个数据库连接池配置Variable Name :数据库连接池的名称一个测试计划可以有多个 JDBC Connection,只要名称不重复就行 Connection pool Configuration连接池参数配置,基本保持默认就行了,可根据需要进行修改 字段含义Max Number of Connections最大连接数;做性能测试时,建议填 0如果填了10,则最大连接10个线程Max Wait(ms)在连接池中取回连接最大等待时间,单位毫秒Time Between Eviction Runs(ms)线程可空闲时间,单位毫秒如果当前连接池中某个连接在空闲了 time Between Eviction Runs Millis 时间后任然没有使用,则被物理性的关闭掉Auto Commit自动提交sql语句,如:修改数据库时,自动 commitTransaction isolation事务隔离级别Preinit Pool立即初始化连接池如果为 False,则第一个 JDBC 请求的响应时间会较长,因为包含了连接池建立的时间 Connection Validation by Pool验证连接池是否可响应字段含义Test While Idle当连接空闲时是否断开Soft Min Evictable Idle Time(ms)连接在池中处于空闲状态的最短时间Validation Query一个简单的查询,用于确定数据库是否仍在响应默认为jdbc驱动程序的 isValid() 方法,适用于许多数据库 Database Connection Configuration数据库连接配置字段含义Database URL数据库连接 URLJDBC Driver class数据库驱动Username数据库登录用户名Password数据库登录密码Connection Properties建立连接时要设置的连接属性 Database URL 举例jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=UTF8&autoReconnect=true&allowMultiQueries=true(允许执行多条 sql) 常见数据库的连接 URL和驱动数据库驱动URLMySQLcom.mysql.jdbc.Driverjdbc:mysql://host:port/{dbname}PostgreSQLorg.postgresql.Driverjdbc:postgresql:{dbname}Oracleoracle.jdbc.driver.OracleDriverjdbc:oracle:thin:user/pass@//host:port/servicesqlServercom.microsoft.sqlserver.jdbc.SQLServerDriverjdbc:sqlserver://host:port;databaseName=databaseName  
  • 注意JDBC数据库连接中资源关闭的顺序
    在JDBC连接数据库时首先要获得connection,再通过它获得相应的statement,最后获得结果集resultset.这些过程都会占用内存资源,所以我们常常会在方法调用结束后关闭相应的资源节约内存空间。这时如果关闭的顺序不对,像下面这样,有时就会出现异常。 public static void closeAllResource(Connection conn,Statement st,ResultSet rs) { if (conn!=null) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } if (st!=null) { try { st.close(); } catch (Exception e) { e.printStackTrace(); } } if (rs!=null) { try { rs.close(); } catch (Exception e) { e.printStackTrace(); } } }org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (Connection is closed) at org.sqlite.core.DB.newSQLException(DB.java:909) at org.sqlite.core.CoreStatement.internalClose(CoreStatement.java:115) at org.sqlite.jdbc3.JDBC3Statement.close(JDBC3Statement.java:35) at org.sqlite.jdbc4.JDBC4Statement.close(JDBC4Statement.java:27) at com.tools.JdbcUtils.close(JdbcUtils.java:94) at com.tools.BaseDao2.update(BaseDao2.java:38) at com.test.testjdbc.main(testjdbc.java:30)如果connection关闭了,后面Statement和ResultSet相关的操作就会受到影响。所以平时一定要注意关闭资源的先后顺序,先关闭ResultSet,然后是Statement,最后是Connetion,刚好与创建相应对象时的顺序相反。
  • 10个问题让你快速避开java中的jdbc常见坑
    Connection.setAutoCommit(boolean)用于事务提交。setAutoCommit(true), 则执行的所有sql执行都会作为单个事务直接提交并运行setAutoCommit(false), 则必须等调用conn.commit()才会提交运行Q: setAutoCommit默认是true还是falseA: 默认是true。Q: setAutoCommit(true)的缺点是什么?A: 如果一次性执行多个sql语句, 中间sql出错时,就会造成脏数据。Q: setAutoCommit(false)后,如果出了错却没有在catch中进行Connection的rollBack操作,会发生什么?A; 操作的表就会被锁住,造成数据库死锁fetchSizefetchSize 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数fetchSize越 大, 客户端内存占用越 大,读取数据库次数越 少,速度越 快。Q: Oracle和Mysql中的fetchSize有什么区别?A: Oracle会每次网络传输fetchSize条数据到客户端, MYSQL则会一次性全部传送到客户端,因此Mysql中的fetchSize是一种模拟游标。PreparedStatementQ:相比Statement的好处?A:PreparedStatement是预编译的,比Statement速度快,执行效率高,因此即使sql中不带参数也最好使用PreparedStatement代码的可读性和可维护性更好(相比于sql拼接)PreparedStatement可以防止SQL注入攻击,而Statement却不能Q:prepareStatement是statement接口的实现吗?A:prepareStatement不是实现,而是继承的接口CallableStatementCallableStatement继承自PreparedStatementCallableStatement接口添加了 调用存储过程 核函数以及处理输出参数(INOUT)的方法。即存储过程就用CallableStatementConnection Pool连接池优点:减少连接创建次数更快的系统整体响应速度统一连接管理,减少失误性的连接未关闭。ResultSet作用: 缓存数据结果集Statement st = conn. createStatement (int resultSetType, int resultSetConcurrency) ResultSet rs = st.executeQuery(sqlStr)滚动,就是指调用.next()或者.previous()或者移动到对应行resultSetType 是设置 ResultSet 对象的类型可滚动,或者是不可滚动。取值如下(见单词知意):ResultSet.TYPE_FORWARD_ONLY 只能向前滚动ResultSet.TYPE_SCROLL_INSENSITIVE, 支持前后滚动,对修改不敏感ResultSet.TYPE_SCROLL_SENSITIVE 支持前后滚动,对修改敏感resultSetConcurency 是设置 ResultSet 对象能够修改的,取值如下:ResultSet.CONCUR_READ_ONLY 设置为只读类型的参数。ResultSet.CONCUR_UPDATABLE 设置为可修改类型的参数。Q:Connection、statement、ResultSet的关闭顺序是?A:先ResultSet、再Statement、最后再connection。因为这种操作很麻烦,最好使用jdbc连接池,或者try-with-resource数据库知识Q:事务的ACID属性是什么?A:A是 atomicity原子性, 事务内的行为一次性执行完,要么就回退C是consistency一致性 有a+b=c的限制条件,然后a变化的同时,b也必须跟着变化I是isolation隔离性 事务隔离,即事务的中间执行过程,对另外一个事务不可见。D是durability持久性 提交i成功后,修改不会改变,也会被记录。Q: 脏读、不可重复读和幻读是什么?A:脏读:数据被更新了,但是还没提交, 然后另一个事务读到了更新后的数据,结果事务回滚了,导致读的数据其实是脏数据,不可重复读: 1个事务要读2次数据(注意是单条数据),结果第一次读和第二次读数据不一致了。幻读: 1个事务读了2次 数据,发现2次的记录数不一致(注意事项记录数)————————————————
  • 注意JDBC数据库连接中资源关闭的顺序
    在JDBC连接数据库时首先要获得connection,再通过它获得相应的statement,最后获得结果集resultset.这些过程都会占用内存资源,所以我们常常会在方法调用结束后关闭相应的资源节约内存空间。这时如果关闭的顺序不对,像下面这样,有时就会出现异常。    public static void closeAllResource(Connection conn,Statement st,ResultSet rs) {        if (conn!=null) {            try {                conn.close();            } catch (Exception e) {                e.printStackTrace();            }        }                if (st!=null) {            try {                st.close();            } catch (Exception e) {                e.printStackTrace();            }        }                if (rs!=null) {            try {                rs.close();            } catch (Exception e) {                e.printStackTrace();            }        }    }org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (Connection is closed) at org.sqlite.core.DB.newSQLException(DB.java:909) at org.sqlite.core.CoreStatement.internalClose(CoreStatement.java:115) at org.sqlite.jdbc3.JDBC3Statement.close(JDBC3Statement.java:35) at org.sqlite.jdbc4.JDBC4Statement.close(JDBC4Statement.java:27) at com.tools.JdbcUtils.close(JdbcUtils.java:94) at com.tools.BaseDao2.update(BaseDao2.java:38) at com.test.testjdbc.main(testjdbc.java:30)如果connection关闭了,后面Statement和ResultSet相关的操作就会受到影响。所以平时一定要注意关闭资源的先后顺序,先关闭ResultSet,然后是Statement,最后是Connetion,刚好与创建相应对象时的顺序相反。
  • 10个问题让你快速避开java中的jdbc常见坑
    Connection.setAutoCommit(boolean)用于事务提交。setAutoCommit(true), 则执行的所有sql执行都会作为单个事务直接提交并运行setAutoCommit(false), 则必须等调用conn.commit()才会提交运行Q: setAutoCommit默认是true还是falseA: 默认是true。Q: setAutoCommit(true)的缺点是什么?A: 如果一次性执行多个sql语句, 中间sql出错时,就会造成脏数据。Q: setAutoCommit(false)后,如果出了错却没有在catch中进行Connection的rollBack操作,会发生什么?A; 操作的表就会被锁住,造成数据库死锁fetchSizefetchSize 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数fetchSize越 大, 客户端内存占用越 大,读取数据库次数越 少,速度越 快。Q: Oracle和Mysql中的fetchSize有什么区别?A: Oracle会每次网络传输fetchSize条数据到客户端, MYSQL则会一次性全部传送到客户端,因此Mysql中的fetchSize是一种模拟游标。PreparedStatementQ:相比Statement的好处?A:PreparedStatement是预编译的,比Statement速度快,执行效率高,因此即使sql中不带参数也最好使用PreparedStatement代码的可读性和可维护性更好(相比于sql拼接)PreparedStatement可以防止SQL注入攻击,而Statement却不能Q:prepareStatement是statement接口的实现吗?A:prepareStatement不是实现,而是继承的接口CallableStatementCallableStatement继承自PreparedStatementCallableStatement接口添加了 调用存储过程 核函数以及处理输出参数(INOUT)的方法。即存储过程就用CallableStatementConnection Pool连接池优点:减少连接创建次数更快的系统整体响应速度统一连接管理,减少失误性的连接未关闭。ResultSet作用: 缓存数据结果集Statement st = conn. createStatement (int resultSetType, int resultSetConcurrency) ResultSet rs = st.executeQuery(sqlStr)滚动,就是指调用.next()或者.previous()或者移动到对应行resultSetType 是设置 ResultSet 对象的类型可滚动,或者是不可滚动。取值如下(见单词知意):ResultSet.TYPE_FORWARD_ONLY 只能向前滚动ResultSet.TYPE_SCROLL_INSENSITIVE, 支持前后滚动,对修改不敏感ResultSet.TYPE_SCROLL_SENSITIVE 支持前后滚动,对修改敏感resultSetConcurency 是设置 ResultSet 对象能够修改的,取值如下:ResultSet.CONCUR_READ_ONLY 设置为只读类型的参数。ResultSet.CONCUR_UPDATABLE 设置为可修改类型的参数。Q:Connection、statement、ResultSet的关闭顺序是?A:先ResultSet、再Statement、最后再connection。因为这种操作很麻烦,最好使用jdbc连接池,或者try-with-resource数据库知识Q:事务的ACID属性是什么?A:A是 atomicity原子性, 事务内的行为一次性执行完,要么就回退C是consistency一致性 有a+b=c的限制条件,然后a变化的同时,b也必须跟着变化I是isolation隔离性 事务隔离,即事务的中间执行过程,对另外一个事务不可见。D是durability持久性 提交i成功后,修改不会改变,也会被记录。Q: 脏读、不可重复读和幻读是什么?A:脏读:数据被更新了,但是还没提交, 然后另一个事务读到了更新后的数据,结果事务回滚了,导致读的数据其实是脏数据,不可重复读: 1个事务要读2次数据(注意是单条数据),结果第一次读和第二次读数据不一致了。幻读: 1个事务读了2次 数据,发现2次的记录数不一致(注意事项记录数)部分参考资料https://blog.csdn.net/u011543448/article/details/79441066
  • [其他] 【故障】客户使用JDBC执行sql报错:ERROR: insufficient data left in message
    问题描述:客户使用JDBC执行sql报错:ERROR:  insufficient data left in message排查方法:排查客户执行的sql中是否包含'\0'(在notepad++中查看时NUL的特殊字符),如图:原因:服务端无法处理字符串中的'\0'字符解决方式:去掉特殊字符,可以用空格代替参考链接:https://www.postgresql.org/message-id/alpine.BSO.2.00.0906031639270.2432@leary.csoft.net
  • [BI报表] PowerBI使用用户名密码方式对接FusionInsight HetuEngine
    前提条件:FusionInsight HD 集群安装完毕,集群状态健康已安装最新版本HetuEngine服务已在FusionInsight Hetu集群中创建“人机”用户Windows环境已安装PowerBI   说明:该方法仅适用于2021.3.30版本之后,3.30之前的版本不适用一、获取JDBC jar包  下载HetuEngine客户端。登录FusionInsight  Manager。选择“集群 > 待操作的集群名称 > 服务 > HetuEngine > 概览”。在页面右上角,选择“更多 > 下载客户端”,根据界面提示下载“完整客户端”文件到本地。解压HetuEngine客户端压缩包文件“FusionInsight_Cluster_集群ID_Services_Client.tar”获取jdbc文件,并存放在本地,例如D:\test   说明:jdbc文件在压缩包中的路径:FusionInsight_Cluster_集群ID_Services_Client \FusionInsight_Cluster_1_Services_ClientConfig\FusionInsight_Cluster_集群ID_Services_ClientConfig\HetuEngine\ presto-jdbc-316-hw-ei-*-SNAPSHOT二、PowerBI配置步骤1:采用ODBC登录方式访问HetuEngine,首先需要安装ODBC驱动程序。使用默认配置安装“hetu-odbc-win64.msi”驱动程序。下载地址:https://openlookeng.io/download.html。步骤2:配置数据源驱动执行以下命令停止自动启动的odbc服务。    cd C:\Program Files\openLooKeng\openLooKeng ODBC Driver 64-bit\odbc_gateway\mycat\bin    mycat.bat stop        2.替换jdbc驱动。    拷贝第一节中获取的jdbc jar包到“C:\Program Files\openLooKeng\openLooKeng ODBC Driver 64-bit\odbc_gateway\mycat\lib”目录下,并删除该目录下原始的“hetu-jdbc-1.0.1.jar”包。            3.编辑odbc的“server.xml”文件的协议前缀    将“C:\Program Files\openLooKeng\openLooKeng ODBC Driver 64-bit\odbc_gateway\mycat\conf”目录中的“server.xml”文件的属性值“<property name="jdbcUrlPrefix">jdbc:lk://</property>”修改为“<property name="jdbcUrlPrefix">jdbc:presto://</property>”    4.配置用户名/密码方式连接。    在自定义路径,如“C:\hetu”中新建“jdbc_param.properties”文件,添加如下内容:user=admintestpassword=admintest@123456    说明:    user:已创建的“人机”用户的用户名,如:admintest。    password:已创建的“人机”用户的用户密码,如:admintest@123456。    5.执行以下命令重启odbc服务    cd C:\Program Files\openLooKeng\openLooKeng ODBC Driver 64-bit\odbc_gateway\mycat\bin    mycat.bat restart    备注:每次修改配置时都需要停止odbc服务,修改完毕后再重启服务。步骤3:在window系统的控制面板中输入“odbc”搜索odbc的管理程序。步骤4:在应用程序中选择“添加 > openLookeng ODBC 1.1 Driver > 完成”步骤5:参考下图创建数据源名称和描述,单击“Next”步骤6:参考下图完成参数配置。 Connection URL:<HSBrokerIP1:port1>,<HSBrokerIP2:port2>,<HSBrokerIP3:port3>/hive/default?serviceDiscoveryMode=hsbroker;获取HSBroker节点及端口号:a.  登录FusionInsight Managerb.  选择“集群 -> 待操作的集群名称 –> 服务 -> HetuEngine –> 角色 -> HSBroker”获取HSBroker所有实例的业务IP选择“集群 -> 待操作的集群名称 –> 服务 -> HetuEngine -> 配置 -> 全部配置”,右侧搜索“server.port”,获取HSBroker的端口号样例:192.168.8.37:29860,192.168.8.38:29860, 192.168.8.39:29860/hive/default?serviceDiscoveryMode=hsbrokerConnection Config:选择步骤2准备好的“jdbc_param.properties”文件;User Name”是下载凭据的用户名称。步骤7:单击“Test DSN ”测试连接, 显示连接成功且“Catalog”和“Schema”中均有内容表示连接成功,单击“Next”。步骤8:单击“Finish”完成连接。步骤9:使用PowerBI对接,选择“获取数据 > 更多 > ODBC > 连接”。步骤10:选择步骤5中添加的数据源,单击“确定”完成数据源添加。步骤11:(可选)输入下载凭据用户的“用户名”及“密码”,单击“连接”。步骤12:连接成功后,显示所有表信息
  • [BI报表] 永洪BI使用用户名密码方式对接FusionInsight HetuEngine
    前提条件:FusionInsight HD 集群安装完毕,集群状态健康已安装最新版本HetuEngine服务已在FusionInsight Hetu集群中创建“人机”用户Windows环境已安装永洪BI   说明:该方法仅适用于2021.3.30版本之后,3.30之前的版本不适用一、获取JDBC jar包  下载HetuEngine客户端。登录FusionInsight  Manager。选择“集群 > 待操作的集群名称 > 服务 > HetuEngine > 概览”。在页面右上角,选择“更多 > 下载客户端”,根据界面提示下载“完整客户端”文件到本地。解压HetuEngine客户端压缩包文件“FusionInsight_Cluster_集群ID_Services_Client.tar”获取jdbc文件,并存放在本地,例如D:\test   说明:jdbc文件在压缩包中的路径:FusionInsight_Cluster_集群ID_Services_Client \FusionInsight_Cluster_1_Services_ClientConfig\FusionInsight_Cluster_集群ID_Services_ClientConfig\HetuEngine\ presto-jdbc-316-hw-ei-*-SNAPSHOT二、永洪BI配置步骤1:打开Yonghong Desktop,选择“添加数据源”->“presto”步骤2:在数据源配置页面参考下图完成参数配置,“用户名”和“密码”为已创建的“人机”用户的用户名和用户密码。配置完成后可以单击“测试连接”测试。驱动:选择“自定义 > 选择自定义驱动”,单击,编辑驱动名称,单击“上传文件”上传已获取的JDBC jar包,单击“确定”。URL格式:jdbc:presto://<HSBrokerIP1:port1>:<HSBrokerIP2:port2>:<HSBrokerIP3:port3>/hive/default?serviceDiscoveryMode=hsbroker获取HSBroker节点及端口号:a.  登录FusionInsight Managerb.  选择“集群 -> 待操作的集群名称 –> 服务 -> HetuEngine –> 角色 -> HSBroker”获取HSBroker所有实例的业务IPc.  选择“集群 -> 待操作的集群名称 –> 服务 -> HetuEngine -> 配置 -> 全部配置”,右侧搜索“server.port”,获取HSBroker的端口号样例:jdbc:presto:// 192.168.8.37:29860,192.168.8.38:29860, 192.168.8.39:29860/hive/default?serviceDiscoveryMode=hsbroker服务器登录:选择“用户名和密码”,并填写“人机”用户的用户名和密码。步骤3:单击“新建数据集”,在弹出的页面参考下图修改保存路径,单击“确定”保存路径,最后“测试连接”。步骤4:在数据源选择“hetu > hive > default > 视图”,在右侧“新建数据集”选择“SQL数据集”。步骤5:在“数据源”处选择步骤3新建的数据集,显示所有表信息,选中其中一个表,如“test”表,单击“刷新数据”,可在右侧“数据详情”中显示表的所有信息。
总条数:82 到第
上滑加载中