1. JdbcTemplate
1.1. 优势
1.1.1. 可以直接根据业务需求拼写sql,以及sql语句需要的参数,从而直接获取数据
1.1.2. 支持数据库分区
1.2. 劣势:sql语句直接写在java程序中,后期难以管理
2. Spring+JdbcTemplate框架整合的步骤
2.1. 添加jar包
2.2. 根据数据表编写实体类
2.3. 设计业务接口
2.4. 编写接口实现类
2.4.1. 将JdbcTemplate作为EmpDaoImpl的属性,并封装getter,setter方法
2.4.2. 调用JdbcTemplate.update(String sql,Object[] param);
2.5. 创建jdbc.properties,以键值对方式保存数据库连接的资源信息
2.6. 配置spring-common.xml
2.6.1. 注入PropertyPlaceholderConfigurer对象,加载jdbc.properties
2.6.2. 注入C3P0数据源框架ComboPooledDataSource对象,为JdbcTemplate提供数据库配置信息以及Connection的连接池技术
2.6.3. 注入JdbcTemplate对象,实现数据库增删改查
2.6.4. 注入EmpDaoImpl对象,将之前配置完毕JdbcTemplate对象自动装配
3. JdbcTemplate数据库操作
3.1. 增删改操作
int update(String sql,Object[] param);
3.2. 查询
3.2.1. 获取多行多列的数据:List<T> JdbcTemplate.query(String sql,Object[] param,RowMapper<T>)
3.2.2. 根据sql语句查询的结果,在接口实现类中定义内部类,统一处理数据表每一行的列值与实体类的属性的对应关系
// 定义内部类:统一处理获取的表数据与Emp类属性的对应关系
private class MyRowMapper implements RowMapper<Emp> {
@Override
public Emp mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println("行号:" + rowNum);
Dept dept=new Dept();
dept.setDeptid(rs.getInt(7));
Emp emp = new Emp(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getDate(4), rs.getDouble(5),
rs.getDouble(6), dept);
return emp;
}
}
3.2.3. 获取单行多列的数据
Emp emp= jdbcTemplate.query(sql, new Object[]{id}, new ResultSetExtractor<Emp>() {
@Override
public Emp extractData(ResultSet rs) throws SQLException, DataAccessException {
Emp emp=null;
Dept dept=null;
if (rs.next()) {
emp = new Emp();
emp.setEname(rs.getString("ename"));
emp.setHiredate(rs.getDate("hiredate"));
dept=new Dept();
dept.setDname(rs.getString("dname"));
emp.setDept(dept);
}
return emp;
}
});
3.2.4. 获取聚合查询的结果:使用分组或数据库函数的查询结果,例如统计每个部门的员工人数
需要在程序中定义帮助类,类的属性要与查询结果的所有列值对应
public class DeptUtil {
private String dname;
private Integer personNums;
}
String sql="SELECT d.dname,COUNT(1) as c from emp e "
+"LEFT JOIN dept d ON e.deptid=d.deptid "
+"GROUP BY d.dname";
List<DeptUtil> dus= jdbcTemplate.query(sql, new RowMapper<DeptUtil>(){
@Override
public DeptUtil mapRow(ResultSet rs, int rowNum) throws SQLException {
DeptUtil du=new DeptUtil(rs.getString("dname"), rs.getInt("c"));
return du;
}
});
3.2.5. 获取单行单列的数据,例如统计所有员工的人数
String sql="select count(1) from emp";
int i=jdbcTemplate.queryForObject(sql, new RowMapper<Integer>(){
@Override
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
int i= rs.getInt(1);
return i;
}
});
4. Spring事务
4.1. 数据库的事务: 事务是一组操作的执行单元,事务管理的是一组SQL指令,比如增加,修改,删除等
4.2. 事务一致性:事务内的所有操作必须全部成功,或者全部失败,不允许有部分成功的操作,否则导致业务操作不一致
4.3. 事务的四大特性
4.3.1. atomic(原子性):要么都发生,要么都不发生。
4.3.2. consistent(一致性):数据应该不被破坏。
4.3.3. isolate(隔离性):用户间操作不相混淆
4.3.4. durable(持久性):永久保存,例如保存到数据库中等
4.4. Spring的两种事务管理方式
4.4.1. 编程式事务:编写代码控制事务的回滚,比较繁琐
4.4.2. 声明式事务:通过xml文件配置或者注解的方式实现根据业务的需要,为指定范围的方法提供各种类型的事务
4.5. Spring控制事物的方式:spring控制事物是以bean组件的函数为单位的,如果一个函数正常执行完毕,该函数内的全部数据库操作按照一次事物提交,如果抛出异常,全部回滚
4.6. Spring事务处理的方法
4.7. 使用注解实现spring事务
//@Transactional 写在需要提供事务的方法上
//readOnly 是否设置为只读事务,为查询操作提供事务,
//如果当前进行增删改操作,建议设置readOnly=false
//propagation 设置事务传播行为
//Propagation.REQUIRED 单例模式的事务,如果之前存在事务对象,则该方法使用之前//的事务,如果之前没有事务对象,则spring提供一个新的事务对象
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
Spring配置文件需要开启注解功能
<!-- 开启注解实现事务管理的功能,并指定之前配置的事务管理器的id-->
<tx:annotation-driven transaction-manager="tx" />
<!-- 开启注解功能:让所有写有的注解的类生效 -->
<context:component-scan base-package="com"></context:component-scan>