Spring数据库相关

2019-06-12

Spring整合JDBC配置

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





            
                  
                   
                  



    

JdbcTemplate类

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

主要方法:

  • queryForMap:将查询结果封装为Map对象返回
  • queryForList:将查询结果封装为List>返回
  • queryForObject:将查询结果封装为对象返回。可以使用RowMapper映射器将查询结果集映射到用户自定义类中。映射器通过名称匹配的方式,自动将一行数据映射到指定类的实例中,并支持下划线到驼峰的转换
  • query:将查询结果封装为List集合返回。可以使用RowMapper映射器将查询结果集映射到用户自定义类中
  • update:执行增、删、改,返回更新行数
  • batchUpdate(sql, List:可以批量插入记录
//实例化JdbcTemplate类,传入dataSource对象
JdbcTemplate template = new JdbcTemplate(dataSource);

/********************** 查询单条数据,返回Map *************************/
String sql = "SELECT * FROM DEPT WHERE DEPTNO = ?";
Map result = template.queryForMap(sql,10);

/*********************** 查询多条数据,返回List*********************/
String sql = "SELECT * FROM DEPT";
List> lists = template.queryForList(sql);
/************************查询单条数据,返回实体对象************************/
String sql = "SELECT * FROM DEPT WHERE DEPTNO = ?";
//指定数据表所对应的实体类
RowMapper rowMapper = new BeanPropertyRowMapper(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 rowMapper = new BeanPropertyRowMapper(Dept.class);
List 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事务管理






      

    

 

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 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数据库相关)