在Java互联网编程中,数据大部分存储在数据库和NoSQL工具中;传统的JDBC在执行简单的SQL语句时也需要非常多的代码,包含打开关闭数据库、组装结果等,还有大量的try…catch…finally语句,虽然JDBC的性能是最好的,但代码的可读性和可维护性非常差;
在Spring出现后,Spring提供了JDBC模板模式,就是它自身的JdbcTemplate,可以简化许多代码的编程;但是实际工作中,这个模板也不常用;Spring还提供了支持事务的模板TransactionTemplate,支持Hibernate框架的模板HibernateTemplate,对于MyBatis框架由于版本原因,虽未支持,但MyBatis社区开发了介入Spring的开发包,该包提供了SqlSessionTemplate,且开发者还可以直接使用接口编程;
一、配置数据库资源
配置方式有XML配置或注解,对于项目的公共资源,建议采用XML配置;以XML为例介绍三种配置方式:
(1)使用spring内部提供的类:配置一个最简单的数据源,不支持连接池,一般用于测试;
(2)使用第三方数据库连接池
需下载对应的数据库连接池相关包,然后在spring中简单配置,示例为DBCP的数据库连接池:
(3)使用JNDI数据库连接池
二、使用JdbcTemplate模板
(1)配置JdbcTemplate:在spring配置文件spring-cfg.xml
(2)使用JdbcTemplate操作数据库
主要方法:
-execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句(DDL语句包括: create database,create table,alter table ,drop table,create view,alter view ,drop view 等);
-update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
-query方法及queryForXXX方法:用于执行查询相关语句;
-call方法:用于执行存储过程、函数相关语句;
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("spring-cfg.xml");
JdbcTemplate jt=ctx.getBean(JdbcTemplate.class);
//JDBC增删查改
//增、删、改:jt.update(...)
//查:jt.query(...)、queryForObject(...)
通过ConnectionCallback和StatementCallback接口可获得JdbcTemplate的Statement回调,使用原生的SQL命令,此时,同样可利用JdbcTemplate提供的系列优点,如一致的异常体系;
(PS:回调:定义一个方法A,使用接口作为A的参数,然后在调用此方法时,必须调用这个接口的实现类,在方法A中调用到实现类定义的同名方法时,就会自动执行实现类中自定义的同名方法)
//使用StatementCallback接口进行回调,这个接口只有一个方法需实现Object doInStatement(Statement stmt),
//在该方法的执行体内,可获得Statement的引用,从而完成数据库的操作
public Role getRoleByStatementCallback(JdbcTemplate jdbcTemplate, String id) {
Role role = null;
//这里写成Java 8的lambda表达式,如果你使用低版本的Java,需要使用StatementCallback的匿名类
role = jdbcTemplate.execute((Statement stmt) -> {
Role result = null;
String sql = "select id, role_name, note from t_role where id = " + id;
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
result = new Role();
result.setId(rs.getString("id"));
result.setNote(rs.getString("note"));
result.setName(rs.getString("role_name"));
}
return result;
});
return role;
}
注意,JdbcTemplate不支持事务,如果要支持需要引入对应的事务管理器;在spring中,会在内部判断是否事务交由事务管理器处理,是就从管理器中获取数据库连接,且JdbcTemplate的资源连接的请求关闭也由管理器决定,否数据库资源就有JdbcTemplate自身管理;
三、MyBatis-Spring
MyBatis-Spring项目由MyBatis社区开发,并不是Spring的子框架;
配置MyBatis-Spring项目(mybatis-spring-xxx.jar):
(1)配置数据源,前文已有
(2)配置SqlSessionFactory
MyBatis-Spring项目提供了SqlSessionFactoryBean支持SqlSessionFactory的配置,查看SqlSessionFactoryBean源码可知,其中可以配置几乎所有MyBatis的组件,因此Spring可以通过调用其中的setter方法进行配置;
sqlMapConfig.xml:
RoleMapper.xml:
insert into t_role(role_name, note) values (#{roleName}, #{note})
delete from t_role where id=#{id}
update t_role set role_name = #{roleName},note = #{roleName} where id = #{id}
定义命名空间下的接口:
public interface RoleMapper {
public int insertRole(Role role);
public Role getRole(@Param("id") String id);
public int updateRole(Role role);
public int deleteRole(@Param("id") String id);
}
(3)可选配置SqlSessionTemplate,如果SqlSessionFactory和SqlSessionTemplate都配配置,优先选择SqlSessionTemplate;SqlSessionTemplate的优点是线程安全,即确保每个线程使用的SqlSession唯一且不互相冲突,且提供了一系列的增删查改等功能;
配置SqlSessionTemplate:使用构造器创建对象,常用参数有SqlSessionFactory和MyBatis的执行器Executor类型(SIMPLE,REUSE,BATCH);
使用SqlSessionTemplate:运行时,每次使用SqlSessionTemplate都会产生一个新的SqlSession,即线程安全;
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cfg.xml");
SqlSessionTemplate template=ctx.getBean(SqlSessionTemplate.class);
......
template.insert("cn.infocore.mapper.RoleMapper.insertRole", role);
template.selectOne("cn.infocore.mapper.RoleMapper.getRole", id);
template.update("cn.infocore.mapper.RoleMapper.updateRole", role);
template.delete("cn.infocore.mapper.RoleMapper.deleteRole", id);
但由于SqlSessionTemplate需要通过字符串指定调用哪个SQL,不符合面向对象的规范,且IDE并不能检查这个字符串逻辑的正确性,所以,SqlSessionTemplate的运用也不是很多;
(4)配置Mapper:单个配置或者扫描生成Mapper;
MyBatis-Spring提供了一个MapperFactoryBean类作为中介,可以通过配置来实现我们想要的Mapper;使用Mapper接口式编程可以有效地在逻辑代码中擦除SqlSessionTemplate;
配置RoleMapper对象:mapperInterface:映射器的接口
RoleMapper role=ctx,getBean(RoleMappper.class);
MapperFactoryBean只能配置一个Mapper,如果Mapper很多就会造成配置量很大的问题,因此我们用MapperScannerConfigurer进行配置,用扫描的方式去生成对应的Mapper;
RoleMapper接口修改:
@Repository
public interface RoleMapper {...}
除了通过basePackage属性扫描Mapper,还可以使用扩展接口名的方式,由于这个需要定义一个接口,且所有Mapper都要扩展它,比较麻烦,因此不是很推荐,就不详述了;
(5)事务管理,这个见深入spring事务管理
综上所述,推荐使用Spring+MyBatis,配置如下:
其他需要的文件:xxxMapper.java接口及对应的xxxMapper.xml、sqlMapConfig.xml;