聊聊持久化。
------------------------Spring的平台无关持久化异常
下面是Spring提供的数据访问模板,分别适用于不同的持久化机制
模板类org.springframework.* 用途
jca.cci.core.CciTemplate JCA CCI连接
jdbc.core.JdbcTemplate JDBC连接
jdbc.core.namedparam.NamedParameterJdbcTemplate 支持命名参数的JDBC连接
jdbc.core.simple.SimpleJdbcTemplate 通过java5简化后的JDBC连接
orm.hibernate.HibernateTemplate Hibernate2.x的session
orm.hibernate3.HibernateTemplate Hibernate3.x的session
orm.ibatis.SqlMapClientTemplate iBATIS SqlMap客户端
orm.jdo.JdoTemplate Java数据对象(JAVA DATA OBJECT)实现
orm.jpa.JpaTemplate JAVA持久化API的实体管理器
---------------------------------------------------------------------------------------
Spring DAO支持类提供了便捷的方式来使用数据访问模板
DAO支持类(org.springframework.*) 为谁提供DAO支持
jca.cci.support.CciDaoSupport JCA CCI连接
jdbc.core.support.JdbcDaoSupport JDBC连接
jdbc.core.namedparam.NamedParameterJdbcDaoSupport 带有命名参数的JDBC连接
jdbc.core.simple.SimpleJdbcDaoSupport 用JAVA5进行了简化的JDBC连接
orm.hibernate.support.HibernateDaoSupport Hibernate2.x的session
orm.hibernate3.support.HibernateDaoSupport Hibernate3.x的session
orm.ibatis.support.SqlMapClientDaoSupport iBATIS SqlMap客户端
orm.jdo.support.JdoDaoSupport Java数据对象实现
orm.jpa.support.JpaDaoSupport Java持久化API的实现管理器
---------------------------------------配置数据源
兵马未动,粮草先行,先看看怎么配置数据源。
配置方式有:
1 通过JDBC驱动程序定义的数据源
不适合生产环境,不讲解
2 通过JNDI查找的数据源
<jee:jndi-lookup id="dataSource" jndi-name="/jdbc/SpitterDS" resource-ref="true" />
在java应用程序服务器中,需要将resource-ref="true",这样jndi-name会自动添加“java:comp/env/”前缀。
3 连接池的数据源 :生产环境中建议使用从连接池获取连接的数据源
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:hsql://localhost/spitter/spitter" />
<property name="username" value="xxx" />
<property name="password" value="" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
</bean>
其它属性
initialSize 池启动时创建的连接数量
maxActive 同一时间可从池中分配的最多连接数,为0则表示无限制
maxIdle 池中不会被释放的最多空闲连接数,0表示无限制
maxOpenPreparedStatements 同一时间能够从语句池中分配的预处理语句的最大数量,设置为0表示无限制。
maxWait 在抛出异常前,池等待连接回收的最大时间(当没有可用连接时),如果设置为-1,表示无限等待。
minEvictableIdleTimeMillis 连接在池中保持空闲而不被回收的最大时间
minIdle 在不创建新连接的情况下,池中保持空闲的最小连接数
poolPreparedStatements 是否对预处理语句进行池管理(布尔值)
-------------------------------------------------------------------------------------
在Spring中使用JDBC
持久化机制有很多,Hibernate,iBATIS和JPA只是其中的一部分而已。
还有最古老的JDBC(太冗繁)(但是可以使用数据库的所有特性)!
但是古老的JDBC有太多模板代码需要重复,所以可以使用JDBC模板来解决这个问题。
Spring为JDBC提供了3个模板类供使用:
1 JdbcTemplate:最基本的Spring JDBC模板,这个模板支持最简单的JDBC数据库访问功能以及简单的索引参数查询。
2 NamedParameterJdbcTemplate:使用该模板类执行查询时,可以将查询值以命名参数的形式绑定到SQL中,而不是使用简单的索引参数。
3 SimpleJdbcTemplate:该模板类利用java 5的一些特性,如自动装箱,泛型以及可变参数列表来简化JDBC模板的使用。
随便版本的推移,只关注SimpleJdbcTemplate
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
属性datasource可以是javax.sql.DataSource的任意实现,包括之前创建的。
public class JdbcSplitterDAO implements SpitterDAO{
...
private SimpleJdbcTemplate jdbcTemplate;
public void setJdbcTemplate(SimpleJdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
}
<bean id="splitterDao" class="com.habuma.spitter.persistence.SimpleJdbcTemplateSpitterDao">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
然后应用程序中就可以:
public void addSpitter(Spitter spitter){
jdbcTemplate.update(SQL_INSERT_SPITTER,
spitter.getUsername(),
spitter.getPassword(),
spitter.getFullName(),
spitter.getEmail(),
spitter.isUpdateByEmail()
);
spitter.setId(queryForIdentity());
}
SQL_INSERT_SPITTER是这么定义的
"insert into spitter(username,password,fullname) value(:username,:password,:fullname) ";
查询:
jdbcTemplate.queryForObject{
SQL_SELECT_SPITTER_BY_ID,
new ParameterizedRowMapper<Spitter>(){
public Spitter mapRow(ResultSet rs,int rowNum) throws SQLException{
Spitter spitter = new Spitter();
... rs.getLong(1) rs.getString(2)..
return spitter;
}
} ,
id
);
}
---
新版本
public void addSpitter(Spitter spitter){
Map<String,Object> params=new HashMap<String,Object>();
params.put("username",xxx);
params.put("password",xxx);
params.put("fullname",xxx);
jdbcTemplate.update(SQL_INSERT_SPITTER,params);
-------------
如果只有一个访问数据库的对象,那事情很简单,如果有多个呢?
1 父类存在jdbcTemplate对象,从父类获取此对象
spring提供了3个这样的类(JdbcDaoSupport,SimpleJdbcDaoSupport和NamedParameterJdbcDaoSupport)
每个类分别对应不同的spring JDBC模板。
要使用的话,首先让自己的类如下:
public class JdbcSpitterDao extends SimpleJdbcDaoSupport implements SpitterDao{
...
通过getSimpleJdbcTemplate()获取对象
}
<bean id="xxx" class="自己的类" >
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
但是这与之前并无本质区别!
另一种方法:
<bean id="xxx" class="自己的类" > 这个类extends SimpleJdbcDaoSupport
<property name="jdbcDatasource" ref="jdbcDatasource" />
</bean>
会内部自动创建一个SimpleJdbcTemplate实例。
但是仍然很不方便!
所以需要采用第三方框架.