Spring本身有一个统一的异常体系,它是一套与实现技术无关,面向DAO语义的异常体系,Spring为不同持久化技术提供了模板类,所以 许多持久化技术本身底层的异常,在通过模板类进行处理时,都会转换为Spring DAO的异常体系,可以进行统一的处理。
ORM持久化技术 | 模板类 |
JDBC | org.springframework.jdbc.core.JdbcTemplate |
Hibernate | org.springframework.orm.hibernate4.HibernateTemplate |
iBatis | org.springframework.orm.ibatis.SqlMapClientTemplate |
JPA | org.springframework.orm.jpa.JpaTemplate |
JDO | org.springframework.orm.jdo.JdoTemplate |
TopLink | org.springframework.orm.jpa.JpaTemplate |
有了模板类,spring也提供了一套支持类,为我们完成了定义相应的模板和数据资源的工作。如JdbcDaoSupport.
下面用一个简单的例子介绍JdbcTemplate的配置与使用
@Repository public class ForumDao { @Autowired private JdbcTemplate jdbcTemplate; public void initDb() { final String sql = "create table t_user(user_id int primary key,user_name varchar(60))"; jdbcTemplate.execute(sql); } public void addForum(Forum forum){ String sql="insert into t_forum(froum_name,forum_desc) values(?,?)"; Object[] paramsObjects=new Object[]{forum.getForumName(),forum.getForumDesc()}; jdbcTemplate.update(sql, paramsObjects); } public void addForums(final List<Forum> forums) { final String addForum="insert into t_forum(forum_name,forum_desc) values(?,?)"; jdbcTemplate.batchUpdate(addForum, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int index) throws SQLException { Forum forum=forums.get(index); ps.setString(1,forum.getForumName()); ps.setString(2,forum.getForumDesc()); } @Override public int getBatchSize() { return forums.size(); } }); } public Forum getForum(final int forumId){ String sql="select forum_name,forum_desc form t_forum where forum_id=?"; final Forum forum=new Forum(); jdbcTemplate.query(sql, new Object[]{forumId},new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { forum.setForumId(forumId); forum.setForumName(rs.getString("forum_name")); forum.setForumDesc(rs.getString("forum_desc")); } }); return forum; } public List<Forum> getForums(final int forumId,final int toldId){ String sql="select forum_name,forum_desc form t_forum where forum_id between ? and ?"; final List<Forum> forums=new ArrayList<Forum>(); jdbcTemplate.query(sql, new Object[]{forumId,toldId}, new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { Forum forum=new Forum(); forum.setForumId(forumId); forum.setForumName(rs.getString("forum_name")); forum.setForumDesc(rs.getString("forum_desc")); forums.add(forum); } }); return forums; } public List<Forum> getForumsByRowMapper(final int forumId,final int toldId){ String sql="select forum_name,forum_desc form t_forum where forum_id between ? and ?"; final List<Forum> forums=new ArrayList<Forum>(); jdbcTemplate.query(sql, new Object[]{forumId,toldId},new RowMapper<Forum>() { @Override public Forum mapRow(ResultSet rs, int index) throws SQLException { Forum forum=new Forum(); forum.setForumId(forumId); forum.setForumName(rs.getString("forum_name")); forum.setForumDesc(rs.getString("forum_desc")); return forum; } }); return forums; } }
<?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:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="com.test"/> <context:property-placeholder location="classpath:srping/jdbc.properties"/> <bean id="dataSource" class="org.apche.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> <bean id="jdbcTemplate" class="com.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"/> </beans>
jdbcTemplate封装了许多方法,满足了许多基本需求。
jdbcTemplate#execute(String sql)
jdbcTemplate#update(String sql,Object[]params);
jdbcTemplate#update(String sql,Object[]params,int[] argTypes);
jdbcTempate#update(String sql,PrepareStatmentSetter pss)
PrepareStatmentSetter是一个回调接口,定义了一个void setValues(PrepareStatement ps)方法用来执行绑定参数操作
jdbcTempate#update(PrepareStatmentCreator psc)
PrepareStatmentCreator也是一个回调接口,该接口定义了一个PreparedStatement createPreparedStatement(Connection conn)方法。
jdbcTempate#update(PrepareStatmentCreator psc,PrepareStatmentSetter pss)
返回数据库表自增主键(JdbcTemplate)
int update(PreparedStatementCreator psc,KeyHolder generatedKeyHodler)
KeyHodler为一个回调接口,Spring使用它保存新增记录对应主键,接口方法
Number getKey()throws InvalidDataAccessApiUsageException
Map<String,Object> getKeys()throws InvalidDataAccessApiUsageException
List<Map<String,Object>> getKeyList()
Spring提供了KeyHolder接口的一个通用实现类GeneratedKeyHolder
jdbcTemplate批量更新数据
public int[] batchUpdate(String [] sql);
int[] batchUpdate(String sql,BatchPreparedStatmentSetter pss)
BatchPreparedStatmentSetter接口定义了两个方法:
int getBatchSize();
void setValues(PreparedStatment ps,int i);
jdbcTemplate查询数据结果集处理
jdbcTemplate#query(String sql,Object[] params,RowCallbackHandler handler)
RowCallbackHandler 接口有一个
void processRow(ResultSet rs)throws SQLException
对结果集中的每一行都调用RowCallbackHandler回调接口处理数据。
使用RowMapper<T>处理结果集。接口方法 T mapRow(ResultSet rs,int rowNum);
程序实例在加载spring容器后就可以使用实例了。可以用ClassPathXmlApplicationContext等加载配置文件获取Spring容器上下文环境使用,也可以配置web.xml讲Spring容器和web容器关联起来,具体看项目情况使用。