jdbctemplate查询⼤批量数据_JdbcTemplate浅学
@[TOC]
JdbcTemplate浅学
前⾯我们学习了有关JDBC的封装,如何让JDBC使⽤更加灵活。⽤到的技术⼿段简单应⽤有很多。现在⼩结如下: + 利⽤反射
利⽤反射,得到结果
模板设计模式,只需要sql语句和占位符参数,可以实现不只⼀个ORM对象的增删改操作 + 策略模
策略模集的参数,从⽽实现查询更加灵活。 + 模板设计模式
代理模式,实现了数据库连接池等操作,静态代理、动态代理(结合反射) +
ORM + 代理模式
DAO、ORM
式,⼤⼤提⾼了增删改的功能差异修改 + DAO
⼯⼚模式 + Apache的开源项⽬DBCP数据库连接池的使⽤
⼯⼚模式
那么,上⾯的这些对JDBC的封装优化等,spring-Jdbc已经做好了。更加的强⼤!
1、什么是spring-jdbc
1.1、简介
Spring对数据库的操作在jdbc上⾯做了深层次的封装,使⽤spring的注⼊功能,可以把DataSource注册到JdbcTemplate之中。JdbcTemplate其全限定命名:org.JdbcTemplate。要使⽤JdbcTemlate还需⼀个这个包,其包含了⼀下事务和异常控制
Spring JDBC – 框架和应⽤开发者各⾃分⼯
也就是说Spring-JDBC帮你屏蔽了很多JDBC底层繁琐的API操作、让你更⽅便的开发
1.2、spring-jdbc层级包
org. 包含JdbcTemplate 类和它各种回调接⼝、外加⼀些相关的类。它的⼀个⼦包
org.simple包含SimpleJdbcInsert和SimpleJdbcCall等类。另⼀个叫
org.amedparam的⼦包包含NamedParameterJdbcTemplate及它的⼀些⼯具类。
org.springframework.jdbc.datasource 包含DataSource数据源访问的⼯具类,以及⼀些简单的DataSource实现⽤于测试和脱离JavaEE容器运⾏的JDBC代码。⼦包org.springfamework.bedded提供Java内置数据库例如HSQL, H2, 和Derby的⽀持。
org.springframework.jdbc.object 包含⽤于在RDBMS查询、更新和存储过程中创建线程安全及可重⽤的对象类。这种⽅式类似于JDO
的查询⽅式,不过查询返回的对象是与数据库脱离的。此包针对JDBC做了很多上层封装、⽽底层依赖于org. 包。
org.springframework.jdbc.support
包含SQLException的转换类和⼀些⼯具类。JDBC处理过程中抛出的异常会被转换成org.springframework.dao⾥⾯定义的异常类。
也就是说,凡是使⽤Spring的JDBC封装层的代码⽆需实现任何JDBC或者RDBMS相关的异常处理。所有的这些被转化的异常都是unchecked异常,因⽽也给了你⼀种额外的选择,你可以抓住这些异常,从⽽转化成其他类型的异常被允许调⽤者传播。
1.3、Jdbc-Template
JdbcTemplate
JdbcTemplate是JDBC core包⾥⾯的核⼼类。它封装了对资源的创建和释放,可以帮你避免忘记关闭连接等常见错误。它也包含了核⼼JDBC⼯作流的⼀些基础⼯作、例如执⾏和声明语句,⽽把SQL语句的⽣成以及查询结果的提取⼯作留给应⽤代码。JdbcTemplate执⾏查询、更新SQL语句和调⽤存储过程,运⾏结果集迭代和抽取返回参数值。它也可以捕获JDBC异常并把它们转换成更加通⽤、解释性更强的异常层次结构、这些异常都定义在org.springframework.dao包⾥⾯。
当你在代码中使⽤了JdbcTemplate类,你只需要实现回调接⼝。PreparedStatementCreator回调接⼝通过传⼊的Connection类(该类包含SQL和任何必要的参数)创建已声明的语句。CallableStatement
Creator也提供类似的⽅式、该接⼝⽤于创建回调语句。RowCallbackHandler⽤于获取结果集每⼀⾏的值。
可以在DAO实现类中通过传⼊DataSource引⽤来完成JdbcTemplate的初始化;也可以在Spring IOC容器⾥⾯配置、作为DAO bean的依赖Bean配置。
DataSource最好在Spring IOC容器⾥作为Bean配置起来。在上⾯第⼀种情况下,DataSource bean直接传给相关的服务;第⼆种情况下DataSource bean传递给JdbcTemplate bean。
JdbcTemplate中使⽤的所有SQL以“DEBUG”级别记⼊⽇志(⼀般情况下⽇志的归类是JdbcTemplate对应的全限定类名,不过如果需要对JdbcTemplate进⾏定制的话,可能是它的⼦类名)
1.4、JdbcTemplate提供的⽅法
JdbcTemplate主要提供以下五类⽅法:
execute⽅法:可以⽤于执⾏任何SQL语句,⼀般⽤于执⾏DDL语句;
update⽅法及batchUpdate⽅法:update⽅法⽤于执⾏新增、修改、删除等语句;batchUpdate⽅法⽤于执⾏批处理相关语句;
query⽅法及queryForXXX⽅法:⽤于执⾏查询相关语句;
call⽅法:⽤于执⾏存储过程、函数相关语句。
JdbcTemplate实例⼀旦配置之后是线程安全的。这点很重要因为这样你就能够配置JdbcTemplate的单例,然后安全的将其注⼊到多个DAO中(或者repositories)。JdbcTemplate是有状态的,内部存在对DataSource的引⽤,但是这种状态不是会话状态。
使⽤JdbcTemplate类的常⽤做法是在你的Spring配置⽂件⾥配置好⼀个DataSource,然后将其依赖注⼊进你的DAO类中
1.5、 JdbcTemplate与其他访问JDBC⽅案
JdbcTemplate - 这是经典的也是最常⽤的Spring对于JDBC访问的⽅案。这也是最低级别的封装, 其他的⼯作模式事实上在底层使JdbcTemplate
⽤了JdbcTemplate作为其底层的实现基础。JdbcTemplate在JDK 1.4以上的环境上⼯作得很好。
NamedParameterJdbcTemplate - 对JdbcTemplate做了封装,提供了更加便捷的基于命名参数的使⽤⽅式⽽不是传统的JDBC所NamedParameterJdbcTemplate
使⽤的“?”作为参数的占位符。这种⽅式在你需要为某个SQL指定许多个参数时,显得更加直观⽽易⽤。该特性必须⼯作在JDK 1.4以上。
SimpleJdbcTemplate - 这个类结合了JdbcTemplate和NamedParameterJdbcTemplate的最常⽤的功能,同时它也利⽤了⼀些Java SimpleJdbcTemplate
5的特性所带来的优势,例如泛型、varargs和autoboxing等,从⽽提供了更加简便的API访问⽅式。需要⼯作在Java 5以上的环境中。
SimpleJdbcInsert 和 SimpleJdbcCall - 这两个类可以充分利⽤数据库元数据的特性来简化配置。通过使⽤这两个类进⾏编程,SimpleJdbcInsert 和 SimpleJdbcCall
你可以仅仅提供数据库表名或者存储过程的名称以及⼀个Map作为参数。其中Map的key需要与数据库表中的字段保持⼀致。这两个类通常和SimpleJdbcTemplate配合使⽤。这两个类需要⼯作在JDK 5以上,同时数据库需要提供⾜够的元数据信息。
RDBMS 对象包括MappingSqlQuery, SqlUpdate and StoredProcedure - 这种⽅式允许你在初始化你的数据访问层时创建可重⽤RDBMS 对象
并且线程安全的对象。该对象在你定义了你的查询语句,声明查询参数并编译相应的Query之后被模
型化。⼀旦模型化完成,任何执⾏函数就可以传⼊不同的参数对之进⾏多次调⽤。这种⽅式需要⼯作在JDK 1.4以上。
2、使⽤JdbcTemplate实现CRUD操作
1、数据源
datasource = ateDataSource(properties);
2、实现CRUD
/**
* 使⽤JdbcTemplate实现对数据的增删改查。
* 1、什么是JdbcTemplate?
* + JdbcTemplate是Spring提供的访问数据库的⽅式之⼀,是Spring中最基本、最底层的访问数据库的实现⽅式。
* + 通过使⽤JdbcTemplate,开发者⽆需关⼼数据库连接的创建和关闭细节,只需要专注于实现业务
逻辑即可。
* + 在使⽤JdbcTemplate的时候,只需要声明即可,⽆需⾃⼰初始化,因为Spring在初始化数据源datasource的时候会
* ⾃⼰创建JdbcTemplate的实例。
*/
public class JdbcTemplateTest implements Dao {
//使⽤数据源连接池来注册JDBC
private JdbcTemplate jdbc = new Datasource());
批量更新sql语句public static void main(String[] args) {
JdbcTemplateTest jdbcTest = new JdbcTemplateTest();
User user = new User();
user.setName("李⼀平");
user.setMoney(500f);
jdbcTest.addUser(user);
System.out.println("插⼊user: " + user);
}
@Override
public void addUser(User user) {
final String sql = "insert into bank(name,money) values(?,?)";
final Object[] args = new Object[]{Name(), Money()};
//获取刚插⼊的主键并返回
KeyHolder holder = new GeneratedKeyHolder();
jdbc.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
return ps;
}
}, holder);
int id = Key()).intValue();
user.setId(id);
}
@Override
public void deleteUser(String userName) {//删除操作
String sql = "delete from bank where name=?";
Object[] args = new Object[]{userName};
jdbc.update(sql, args);
}
@Override
@Override
public void updateUser(User user) {//更新操作
String sql = "update bank set name=? set money=? where id=?";
Object[] args = new Object[]{Name(), Money(), Id()};
jdbc.update(sql, args);//返回影响的记录条数
}
@Override
public User findUser(String userName) {//查询
String sql = "select * from bank where name=?";
Object[] args = new Object[]{userName};
//我们原本的实现是创建⼀个结果集处理接⼝,实现处理⽅法。JdbcTemplate类似,只不过是利⽤了结果集参数反射获取属性值。
User user = (User) jdbc.queryForObject(sql, args, new BeanPropertyRowMapper<User>(User.class));
if (user != null)
return user;
else throw new NullPointerException("空异常!");
}
public String findUserById(int id) {
String sql = "select name from bank where id=?";
Object[] args = new Object[]{id};
return jdbc.queryForObject(sql, args, String.class);
}
@Override
public boolean toUser(User user, User toUser, float money) {
if (money > 0.0001) {
user.Money() - money);
toUser.Money() + money);
updateUser(user);
updateUser(toUser);
return true;
} else
throw new RuntimeException("转账⾦额不能为负数!");
}
}
3、JdbcTemplate常⽤⽅法和其他⼀些类
我们在IDEA⾥⾯点击该类,然后点击View-》ToolWindows-》Structure
3.1、查询
queryForObject spring 3.2.2 版本之后jdbcTemplate.queryForInt()和jdbcTemplate.queryForLong() 就取消了,全部⽤queryForObject代替了
queryForObject(sql, requiredType) 本质上和queryForInt相同,只是可以返回不同的对象,例如返回⼀个String对象 2个参数——sql语句 、期待返回来的对象类型
queryForObject(sql, ) 第三个参数是个可变参数
queryForObject(sql, args[],requiredType) 第⼆个参数是个参数数组
queryForObject(sql, rowMapper) 注意,这⾥查询必须保证只能查询⼀条数据,否则会报错。
queryForList
返回⼀个装有map的list,每⼀个map是⼀条记录,map⾥⾯的key是字段名
List> rows= jdbcTemplate.queryForList("SELECT * FROM user");
queryForMap 这个查询只能是查询⼀条记录的查询,返回⼀个map,key的值是column的值
queryForRowSet
返回⼀个结果集然后调⽤.getString或者getInt等去取值
query()⽅法
3.2、更新
execute 执⾏sql语句,⽆返回执,⽤于更新操作(增、删、改)
update 更新操作,返回受影响的⾏数
batchUpdate 执⾏批量更新,参数为string数组
3.3、get⽅法
3.4、RowMapper
sping中的RowMapper可以将数据中的每⼀⾏数据封装成⽤户定义的类。
我们在数据库查询中,如果返回的类型是⽤户⾃定义的类型(其实我们在数据库查询中⼤部分返回的都是⾃定义的类)则需要包装,如果是Java⾃定义的类型,如:String则不需要。
如果sping与hibernate 相结合了,基本上是⽤不到,⼤多数都是在spring单独使⽤时⽤到,常见的情况就是与JdbcTemplate⼀起使⽤。
可以通过建⽴内部类实现RowMapper接⼝,RowMapper中有⼀个mapRow⽅法,所以实现RowMapper接⼝⼀定要实现mapRow⽅法,⽽对⾃定义类的包装就在mapRow⽅法中实现。
3.5、BeanPropertyRowMapper
BeanPropertyRowMapper是RowMapper将表⾏转换为指定映射⽬标类的新实例的实现。映射的⽬标类必须是顶级类,并且必须具有默认或⽆参数构造函数。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。