您的位置:首页 > 编程语言 > Java开发

学习《spring 3.x企业应用开发实战》之使用Spring JDBC访问数据库

2016-08-17 20:02 1016 查看
1、在DAO中使用JdbcTemplate
(1)在Spring配置文件中配置DAO一般分为4个步骤:

定义DataSource;
定义JdbcTemplate;
声明一个抽象的<bean/>,以便所有DAO复用配置JdbcTemplate属性的配置;
配置具体的DAO。

(2)为了避免每个DAO都引入JdbcTemplate,Spring提供了JdbcDaoSupport,JdbcDaoSupport在内部定义了JdbcTemplate,开发者可以通过扩展JdbcDaoSupport定义自己的Dao,这是早期的做法。但是随着注解配置逐渐成为潮流,通过扩展JdbcDaoSupport就显得不合时宜了。因为直接继承JdbcDaoSupport无法对JdbcTemplate成员变量使用@Autowired注解。
所以推荐做法是自己定义一个BaseDao,在BaseDao中定义JdbcTemplate成员,并打上@Autowired注解。

2、基本的数据操作
2.1、更改数据
(1)JdbcTemplate内部通过PreparedStatement执行SQL语句,所以我们可以使用绑定参数的SQL语句,而且我们也应该尽量使用可绑定参数的SQL语句,以便数据库可以复用SQL的执行计划。
示例如下:



(2)我们通过update(String  sql,Object[]  args)方法为SQL语句的占位符绑定参数时,并没有显示指定对应字段的数据类型,此时Spring直接让PreparedStatement根据参数的类型进行“猜测”。然而更好的一种做法是使用int  update(String
 sql,Object[]  args,int[]  argTypes)显式指定每个占位符所对应的字段数据类型。示例如下:



(3)除了以上2个update方法,还有以下几个方法:



PreparedStatement绑定参数时,参数索引从1开始,而不是0。



使用回调接口会显得臃肿,所以不推荐使用回调。

2.2、返回数据库表的自增主键值
(1)JDBC3.0允许将主键绑定至返回结果集,示例如下:



(2)不同数据库获取新增加的主键值



如果数据库的并发率很高,那么使用查询获取主键值将变得不可靠。所以有些数据库强制要求用户在新增记录前,先通过序列获取主键值。

2.3、批量更改数据
示例如下:



2.4、查询多行数据
(1)Spring使用RowCallbackHandler处理查询结果集。示例如下:



(2)Spring还提供了一个和RowCallbackHandler功能上类似的RowMapper<T>接口,使用RowMapper<T>映射多行结果的示例如下:



在返回多结果的场景下,使用RowMapper<T>比使用RowCallbackHandler更好的地方在于,创建List对象和将单条记录加入到List中的操作都由JdbcTemplate代劳了。
(3)RowCallbackHandler和RowMapper<T>的比较
    Spring中解释RowCallbackHandler的实现类是有状态的,而RowMapper<T>的实现类是无状态的。所以在多线程环境下,RowCallbackHandler不能复用,而RowMapper<T>可以复用。另外,通过JDBC查询返回ResultSet结果集时,JDBC不会一次性将所有匹配数据全部加载到JVM中,而是只返回一批次数据(返回的批次数据由JDBC驱动决定,如Oracle的JDBC驱动,默认返回10行)。当通过Result#next()游标滚动结果集超过数据范围时,JDBC再获取一批数据。这样以一种“批量化+串行化”的方式避免大结果集时JVM内存过大开销。
    当使用RowMapper<T>处理大结果集时,RowMapper<T>会一次性把所有结果集都封装进List<T>,占用大量JVM内存,引发内存溢出,这时应该使用RowCallbackHandler接口。

2.5、查询单值数据
(1)获取int、long类型的方法如下:

int  queryForInt(String  sql,Object[]  args,int[]  argTypes);
long  queryForLong(String  sql,Object[]  args,int[]  argTypes);

(2)其他类型单值查询接口如下:



(3)我们在编写SQL语句时,一般用大写字母表述关键字和函数,而用小写字母编写表名、字段名等非语义元素

2.6、操作Blob数据类型

3、自增键和行集
3.1、自增建的作用
(1)Spring运行用户在应用层产生主键值,为此定义了org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer接口,提供2种产生主键的方案:

通过序列产生主键;
通过表产生主键。

(2)DataFieldMaxValueIncrementer类继承图如下:



3.2、获取主键方式
(1)代码示例如下:



(2)通过Oracle中的序列获取主键
create  sequence  seq_post_id
increment  by  1
start  with  1;
调整Spring的配置,使用OracleSequenceMaxValueIncrementer作为主键产生器:
<bean    id="incre"    class="org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer"
        p:incrementerName="seq_post_id"
        p:dataSource-ref="dataSource">
(3)通过MySql表获取主键
在MySql中创建一张用户维护t_post主键的t_post_id表:
create  table  t_post_id(sequence_id  int)  type=MYISAM;
insert  into  t_post_id  values(0);
由于主键维护表的并发访问量很大,所以最好将其声明为MYISAM类型,Spring配置如下:
<bean    id="incre"    class="org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer"
        p:incrementerName="t_post_id"
        p:columnName="sequence_id"
        p:cacheSize="10"
        p:dataSource-ref="dataSource">
其中:cacheSize决定一次返回的主键个数,当调用MySQLMaxValueIncrementer#nextIntValue()时,第一次MySQLMaxValueIncrementer使t_post_id表的sequence_id字段递增10,后续的9次调用都是从缓存中获取主键值。

4、其他类型的JdbcTemplate
4.1、NamedParameterJdbcTemplate
(1)在低版本的Spring中,用户使用?占位符,需要指定索引,如果增加和减少必须维护索引位置,这种编程模式被认为是弱稳定的。NamedParameterJdbcTemplate模板类支持命名参数变量的SQL,它位于org.springframework.jdbc.core.namedparam包中,该包中还定义了一个用于承载命名参数的SqlParameterSource接口,该接口有2个实现类:



(2)代码示例如下:



在SQL语句中声明命名参数的格式是“:paramName”



4.2、SimpleJdbcTemplate
SimpleJdbcTemplate是特殊时期过渡性产物,以后可能会剔除,建议不要使用。

5、以OO方式访问数据库
除了通过JdbcTemplate完成访问数据库的操作,Spring还提供了把一个查询操作封装一个类。

5.1、使用MappingSqlQuery查询数据
(1)SqlQuery是一个可重用、线程安全的类,它封装了一个SQL查询。
(2)我们常使用其子类MappingSqlQuery,示例如下:



(3)使用MappingSqlQuery一般分为以下3个步骤:

定义子类,在子类中声明SQL语句并定义行数据映射逻辑。
声明子类的变量并实例化该类。
使用MappingSqlQuery的方法执行数据查询操作。

(4)父类SqlQuery的一些方法



5.2、使用SqlUpdate更新数据

5.3、使用StoredProcedure执行存储过程

5.4、使用SqlFunction类查询并返回一个单行结果集
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring