美文网首页
Spring数据库相关

Spring数据库相关

作者: Mr_J316 | 来源:发表于2019-06-13 10:00 被阅读0次

    2019-06-12

    Spring整合JDBC配置

    Spring提供了对持久层的整合功能,包括对JDBC以及各种ORM映射工具(如Hibernate、MyBatis)的整合封装。Spring对JDBC的封装使用的是模板设计模式。原来直接使用JDBC所需要的重复性代码都可以在模板类中完成,极大地简化JDBC的使用。

    <!--引入property配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--初始化数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
         <property name="driverClassName" value="${driver}" />       
         <property name="url" value="${url}" />             
         <property name="username" value="${user}" />              
         <property name="password" value="${password}" />             
    </bean>
    <!--初始化操作模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg><ref bean="dataSource"/></constructor-arg>
    </bean>
    

    JdbcTemplate类

    org.springframework.jdbc.core.JdbcTemplate类是Spring提供的JDBC操作模板类,该类是线程安全的(使用ThreadLocal机制保证数据库连接或会话对象的线程安全),可以方便地执行CRUD操作。

    主要方法:

    • queryForMap:将查询结果封装为Map<String,Object>对象返回
    • queryForList:将查询结果封装为List<Map<String, Object>>返回
    • queryForObject:将查询结果封装为对象返回。可以使用RowMapper映射器将查询结果集映射到用户自定义类中。映射器通过名称匹配的方式,自动将一行数据映射到指定类的实例中,并支持下划线到驼峰的转换
    • query:将查询结果封装为List集合返回。可以使用RowMapper映射器将查询结果集映射到用户自定义类中
    • update:执行增、删、改,返回更新行数
    • batchUpdate(sql, List<Object[]>:可以批量插入记录
    //实例化JdbcTemplate类,传入dataSource对象
    JdbcTemplate template = new JdbcTemplate(dataSource);
    
    /********************** 查询单条数据,返回Map *************************/
    String sql = "SELECT * FROM DEPT WHERE DEPTNO = ?";
    Map<String, Object> result = template.queryForMap(sql,10);
    
    /*********************** 查询多条数据,返回List<Map>*********************/
    String sql = "SELECT * FROM DEPT";
    List<Map<String, Object>> lists = template.queryForList(sql);
    /************************查询单条数据,返回实体对象************************/
    String sql = "SELECT * FROM DEPT WHERE DEPTNO = ?";
    //指定数据表所对应的实体类
    RowMapper<Dept> rowMapper = new BeanPropertyRowMapper<Dept>(Dept.class);
    Dept dept = template.queryForObject(sql, rowMapper, 10);
    if (dept != null) {
        System.out.println(dept.getDeptno() + "\t" + dept.getDname() 
            + "\t" + dept.getLoc());
    }
    /**************** 查询多条数据,返回List,泛型为实体对象 ************************/
    String sql = "SELECT * FROM DEPT";
    RowMapper<Dept> rowMapper = new BeanPropertyRowMapper<Dept>(Dept.class);
    List<Dept> lists = template.query(sql, rowMapper);
    if (lists != null) {
        for (Dept item : lists)
            System.out.println(item.getDeptno() + "\t" + item.getDname() 
               + "\t" + item.getLoc());
    }
    /********************** 统计记录数量 ************************/
    String sql = "SELECT COUNT(*) as 人数  FROM DEPT";
    int result = template.queryForObject(sql, Integer.class);
    System.out.println(result);
    
    /************************ 增加操作 *****************************/
    String sql = "INSERT INTO DEPT(DEPTNO, DNAME, LOC) VALUES( ?, ?, ? )";
    int cnt = template.update(sql, new Object[] { 50, "中国分部", "中国" });
    
    /************************ 删除操作 ****************************/
    String sql = "DELETE FROM DEPT WHERE DEPTNO = ?";
    cnt = template.update(sql, new Object[] { 50 });
    

    注意事项:

    • 使用BeanProperytRowMapper要求sql数据查询出来的列和实体属性需要一一对应。如果数据中列明和属性名不一致,在sql语句中需要用as重新取一个别名
    • 使用JdbcTemplate对象不能获取关联对象
    • 查询结果为空时,Spring不会返回null,而是抛出org.springframework.dao.EmptyResultDataAccessException异常

    JdbcDaoSupport类

    
    public class GenericDaoImpl extends JdbcDaoSupport implements GenericDao {
        @Autowired
        public void setDataSource(DriverManagerDataSource dataSource) {
            super.setDataSource(dataSource);
        }
    }
    ------------------------------------------------------------------------------------------------
    //使自己的dao类直接或间接继承JdbcDaoSupport类,传入dataSource对象
    @Repository("deptDao")
    public class DeptDaoImpl extends GenericDaoImpl implements DeptDao {
        //可直接使用该方法获取JdbcTemplate对象
        this.getJdbcTemplate();
    }
    

    注:Autowired注解可以实现对方法形参的自动装配。

    @Autowired将查找被标注的方法的入参类型的Bean,并调用方法自动注入

    Spring事务管理

    Spring的声明式事务管理策略

    Spring的事务管理建立在AOP基础之上,其本质是对目标方法执行前后进行拦截,在目标方法开始执行之前加入事务,在执行完目标方法之后根据执行情况(执行成功则提交,收到异常信息则回滚)处理事务。事务管理本身就是一个典型的AOP切面。

    优点:代码耦合程度低,复用性强。

    注意:实施事务的方法的修饰符必须是public,其它private、static、final均不可,否则不能使用AOP动态代理启动事务

    1.配置Spring事务管理

    <aop:aspectj-autoproxy />
    <context:component-scan base-package="com" />
    
    <!--配置事务管理器-->
    <bean id="txManager"     
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"/>
    </bean>
        
    <!—为事务管理器注册注解驱动器-->
    <tx:annotation-driven transaction-manager="txManager"/> 
    

    2.在service中加入事务控制

    @Service("deptService")
    //加入开启事务注解
    @Transactional
    public class DeptServiceImpl extends GenericServiceImpl implements DeptService {
        @Autowired
        private DeptDao deptDao;
        public DeptDao getDeptDao() {
            return deptDao;
        }
        public void setDeptDao(DeptDao deptDao) {
            this.deptDao = deptDao;
        }
        //对不涉及写数据库写入操作的方法,可加入只读属性以提高速度
        @Transactional(readOnly = true)
        public List<Dept> findAll() {
            return this.deptDao.findAll();
        }
        public void add() {
            Dept d1 = new Dept(50, "中国销售部", "济南");
            Dept d2 = new Dept(50, "中国研发部", "北京");
            this.deptDao.insert(d1);
            this.deptDao.insert(d2);
        }
    }
    

    @Transactional注解常用属性

    属性 类型 默认值 说明
    propagation Propagation枚举 REQUIRED 事务传播属性
    isolation isolation枚举 DEFAULT 指定事务隔离级别。取值有ISOLATION_DEFAULT(默认值,使用数据库默认的事务隔离级别)、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE。
    readOnly boolean false 是否只读。”只读事务”提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,JDBC驱动程序和数据库可以根据这种情况对该事务进行一些特定的优化,不启动数据库锁。
    timeout int -1 指定事务超时时间(以秒为单位),-1意味着不超时。
    rollbackFor Class[] {} 指定触发事务回滚的异常类(应使用全限定类名),该属性可指定多个异常类,多个异常类之间以英文逗号隔开。
    rollbackForClassName String[] {} 需要回滚的异常类名
    noRollbackFor Class[] {} 指定不触发事务回滚的异常类(应使用全限定类名),该属性可指定多个异常类,多个异常类之间以英文逗号隔开。
    noRollbackForClassName String[] {} 不需要回滚的异常类名

    事务传播属性

    REQUIRED 业务方法需要在一个事务中运行,如果方法运行时,已处在一个事务中,那么就加入该事务,否则自己创建一个新的事务.这是****spring****默认的传播行为****.
    SUPPORTS 如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分,如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行.
    MANDATORY 只能在一个已存在事务中执行,业务方法不能发起自己的事务,如果业务方法在没有事务的环境下调用,就抛异常
    REQUIRES_NEW 业务方法总是会为自己发起一个新的事务,如果方法已运行在一个事务中,则原有事务被挂起,新的事务被创建,直到方法结束,新事务才结束,原先的事务才会恢复执行.
    NOT_SUPPORTED 声明方法需要事务,如果方法没有关联到一个事务,容器不会为它开启事务.如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行.
    NEVER 声明方法绝对不能在事务范围内执行,如果方法在某个事务范围内执行,容器就抛异常.只有没关联到事务,才正常执行.
    NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保证点.内部事务回滚不会对外部事务造成影响, 它只对DataSourceTransactionManager 事务管理器起效.

    相关文章

      网友评论

          本文标题:Spring数据库相关

          本文链接:https://www.haomeiwen.com/subject/tjqjfctx.html