JdbcTemplate
1.概述
前面我们已经学习了 Spring 中的**Core Container
核心部分和AOP
、Aspects
等面向切面编程部分,接下来就是Data Access/Integration
**即数据访问和集成部分
Spring 既可以单独使用,也可以集成其他框架,如Hibernate
、MyBatis
等。除此之外,其中对于JDBC
也做了封装,即本章节的JdbcTemplate
,用它可以比较方便地对数据库进行增删改查等操作
总结一下:
- JdbcTemplate就是 Spring 框架对JDBC技术进行的二次封装模板,能够简化对数据库的操作
2.准备工作
2.1 相关SQL
javascript
DROP TABLE IF EXISTS `t_book`;
CREATE TABLE `t_book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
`price` decimal(10, 2) ,
PRIMARY KEY (`id`)
);
2.2 步骤预览
-
1)引入相关
jar
包 -
2)Spring 配置文件配置
Druid
连接池信息 -
3)配置
JdbcTemplate
对象,注入dataSource
-
4)创建 Service 和 Dao 类,在 Dao 类中注入
JdbcTemplate
对象
2.3 详细操作
-
1)引入相关
jar
包(或依赖)-
druid
-
mysql-connector-java
-
spring-jdbc
-
spring-orm
-
spring-tx
-
-
2)Spring 配置文件配置
Druid
连接池信息javascript<!--加载外部属性文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${mysql.driverClassName}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </bean>
沿用之前章节的
Jdbc.properties
配置信息,但稍作修改javascriptmysql.driverClassName=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://127.0.0.1:3306/book_db mysql.username=root mysql.password=sasa
-
3)配置
JdbcTemplate
对象,注入dataSource
javascript<!--配置JdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!--属性注入dataSource--> <property name="dataSource" ref="dataSource"></property> </bean>
2.4 为何使用属性注入?
JdbcTemplate
虽然含有DataSource
的有参构造,但其调用了setDataSource()
方法
这个方法是在其父类中定义了的:
-
4)创建 Service 和 Dao 类,在 Dao 类中注入
JdbcTemplate
对象javascript<!--Dao 类--> public interface BookDao { } @Repository public class BookDaoImpl implements BookDao { @Autowired private JdbcTemplate jdbcTemplate; } <!--Service 类--> @Service public class BookServiceImpl implements BookService { @Autowired private BookDao bookDao; }
别忘了开启注解扫描
javascript<!--开启注解扫描--> <context:component-scan base-package="com.zking.spring"/>
2.5 配置文件整体结构
javascript
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.zking.spring"/>
<!--加载外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${mysql.driverClassName}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</bean>
<!--配置JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--属性注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
3.添加操作
3.1 步骤预览
-
1)创建数据库中
t_book
表对应的实体对象 -
2)编写 Service 和 Dao 代码,增加添加图书的功能逻辑
-
3)代码测试
3.2 详细操作
-
1)创建数据库中
t_book
表对应的实体对象javascriptpublic class Book { private Integer id; private String name; private Double price; //省略get/set方法 }
- 2)编写 Service 和 Dao 代码,增加添加图书的功能逻辑
Service 类:添加
addBook()
方法
javascript@Repository public class BookDaoImpl implements BookDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public int save(Book book) { String sql = "insert into t_book(id,name,price) values(null,?,?)"; Object[] params = {book.getName(),book.getPrice()}; return jdbcTemplate.update(sql,params); } }
Dao 类:通过操作
JdbcTemplate
对象的update()
方法可实现插入,其中两个参数分别是
第一个参数
sql
:编写插入数据对应的sql
语句,可使用通配符?
做占位符第二个参数
args
:可变参数列表,设置占位符对应的参数值
javascript@Service public class BookServiceImpl implements BookService { @Autowired private BookDao bookDao; @Override public int save(Book book) { return bookDao.save(book); } }
-
3)代码测试
javascript@Test public void testSave(){ //操作JdbcTemplate对象,使用update方法进行增删改操作 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookService bookService = ctx.getBean("bookServiceImpl",BookService.class); Book book = new Book(); book.setName("西游记"); book.setPrice(200.0); bookService.save(book); }
刷新数据库中
t_book
表数据,核验是否插入成功可以看到,表中成功新增了一条数据
4.修改和删除
修改、删除操作和添加操作代码逻辑基本一致
BookService 类:添加
updateBook()
和deleteBook()
方法
javascript/** * 修改 */ int update(Book book); /** * 删除 */ int delete(Integer id);
BookDao 类:添加
update()
和delete()
方法
javascript/** * 修改 */ int update(Book book); /** * 删除 */ int delete(Integer id);
BookDaoImpl 类:实现
update()
和delete()
方法
javascript@Override public int update(Book book) { String sql = "update t_book set name=?,price=? where id=?"; Object[] params={book.getName(),book.getPrice(),book.getId()}; return jdbcTemplate.update(sql,params); } @Override public int delete(Integer id) { String sql = "delete from t_book where id=?"; Object[] params={id}; return jdbcTemplate.update(sql,params); }
4.1 测试修改
javascript
@Test
public void testUpdate(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = ctx.getBean("bookServiceImpl",BookService.class);
Book book = new Book();
book.setId(19);
book.setName("西游记");
book.setPrice(250.0);
bookService.update(book);
}
4.2 测试删除
javascript
@Test
public void testDelete(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = ctx.getBean("bookServiceImpl",BookService.class);
bookService.delete(19);
}
5.查询操作
这里演示三种查询操作:
-
1)查询返回某个值
-
2)查询返回对象
-
3)查询返回集合
为了演示效果,需要先在数据库的t_book
表中添加两条数据
接着我们先将代码完成,最后再作进一步的分析说明
5.1 代码实现
BookService 类:添加
count()
、findById()
和list()
方法
javascript@Override public int count() { return bookDao.count(); } @Override public Book findById(Integer id) { return bookDao.findById(id); } @Override public List<Book> list() { return bookDao.list(); }
BookDao 类:添加
selectCount()
、selectById()
和selectAll()
方法
javascript/** * 查找返回一个值 */ int count(); /** * 查找返回对象 */ Book findById(Integer id); /** * 查找返回集合 */ List<Book> list();
BookDaoImpl 类:实现
count()
、findById()
和list()
方法
javascript@Override public int count() { String sql = "select count(0) from t_book"; return jdbcTemplate.queryForObject(sql,Integer.class); } @Override public Book findById(Integer id) { String sql = "select * from t_book where id=?"; return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Book.class),id); } @Override public List<Book> list() { String sql = "select * from t_book"; return jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Book.class)); }
测试代码
javascript@Test public void testQuery(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookService bookService = ctx.getBean("bookServiceImpl",BookService.class); int count = bookService.count(); System.out.println(count); Book book = bookService.findById(1); System.out.println(book); List<Book> list=bookService.list(); System.out.println(list); }
测试结果:
javascript1 Book{id=1, name='西游记', price=200.0} [Book{id=1, name='西游记', price=200.0}]
5.2 代码分析
上述代码逻辑中使用到了**
queryForObject()
和query()
**方法
javascriptjdbcTemplate.queryForObject(sql, Integer.class); jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Book.class), id); jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Book.class));
分别对应
JdbcTemplate
中的三个方法:
javascriptpublic <T> T queryForObject(String sql, Class<T> requiredType); public <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args); public <T> List<T> query(String sql, RowMapper<T> rowMapper);
其中,有两个参数值得关注,一个是Class<T> requiredType ,另一个是RowMapper<T> rowMapper
:
Class<T> requiredType
:返回值的Class
类型
RowMapper<T> rowMapper
:是一个接口,返回不同类型数据,可以使用其实现类进行数据的封装。其实现类有很多,因为我们需要返回一个数据库实体对象,所以可以选择使用BeanPropertyRowMapper
另外,
queryForObject(String sql, RowMapper<T> rowMapper, Object... args)
和query(String sql, RowMapper<T> rowMapper)
的区别在于:
queryForObject返回一个对象
query返回一个集合
6.小结
简单总结下JdbcTemplate
操作数据库的各个方法:
-
添加、修改、删除操作:
update()
方法 -
查询操作:
queryForObject()
和query()
方法,关注两个参数:-
Class<T> requiredType
:返回值的Class
类型 -
RowMapper<T> rowMapper
:接口,具体实现类BeanPropertyRowMapper
,封装对象实体
-
-
批量操作:
batchUpdate()
方法