JdbcTemplate简介
Java语言提供了jdbc来访问数据库,在jdbc api中需要手动的获取和释放连接等资源,使用起来需要做许多重复的工作。Spring在jdbc api的基础上做了抽象和深层次的封装,提供了JdbcTemplate来访问数据库。JdbcTemplate只是对jdbc api进行了抽象封装,并没有提供新的功能。
JdbcTemplate使用需要的依赖包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--spring-core相关的依赖包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--spring-beans依赖包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--spring-expression依赖包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.1.9.RELEASE</version> </dependency> <!--数据库相关的jdbc包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>
JdbcTemplate主要提供了4种方法
- execute:执行数据库的ddl语句。
- update和batchUpdate:update方法用于执行增、删、改,batchUpdate方法用于执行批处理。
- query和queryForXxx:改方法用于执行查询语句。
call:用于执行存储过程,这篇博客不讲解这部分。
JdbcTemplate的使用讲解
使用JdbcTemplate需要配置数据源以及将在Spring容器中注入JdbcTemplate的Bean。在applicationContext中配置如下
<!--配置数据源:驱动类、url数据库用户名和密码--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="username" value="root" /> <property name="password" value="root" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!--配置数据连接并设置是否使用unicode编码和编码格式为utf-8--> <property name="url" value="jdbc:mysql://localhost:3306/spring-demo?useUnicode=true&characterEncoding=utf-8" /> </bean> <!--将jdbctemplate注册到spring容器中,需要配置数据源--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean>
测试需要用到junit和spring与junit集成的包,依赖如下
<!--测试的依赖包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--spring测试的依赖包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.9.RELEASE</version> </dependency>
JdbcTemplate的测试代码
1. execute方法:执行ddl语句
@Test public void testExecute() { //测试JdbcTemplate的execute方法,该方法用于执行数据库的ddl语句。 String sql = "create table user1(id int not null auto_increment, name varchar(20), primary key(id))ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT '用户表1,测试ddl语句的执行'"; jdbcTemplate.execute(sql); }
2. update方法:执行增、删、改
jdbcTemplate对update方法进行了重载,方法分别是
- update(String sql, Object[] args);第二个参数是Object类型的数组。
- update(String sql, Object... args);第二个参数是可变参数。
执行新增语句
@Test public void testInsert() { //测试插入语句 String sql = "insert into student(id, name, sex) values(?, ?, ?)"; jdbcTemplate.update(sql, 1001, "刘备", "男"); }
执行更新语句
@Test public void testUpdate() { //根据id更新 String sql = "update student set name = ?, sex = ?, born = ? where id = ?"; Object[] student = new Object[]{"刘备", "男", "2000-05-03", 1001}; jdbcTemplate.update(sql, student); }
执行删除语句
@Test public void testDelete() { //根据id删除数据 String sql = "delete from student where id = ?"; jdbcTemplate.update(sql, 1006); }
3. batchUpdate:执行批量处理
batchUpdate也有两个常用的重载方法:
- batchUpdate(String[] sqls):参数是更新语句的数组,不能使用站位符。
@Test public void testBatchUpdate() { //批量执行更新表的语句,不能使用占位符。 String[] sqls = {"insert into student(name, sex, born) values('甘夫人','女','2000-10-03')", "update student set name = '孙尚香' where id = 1006",}; jdbcTemplate.batchUpdate(sqls); }
- batchUpdate(String sql, List<Object[]> args):第二个参数是Object数组的列表。
@Test public void testBatchInsert() { //批量执行插入语句,JdbcTemplate的参数为List<Object[]>类型。 String sql = "insert into student(id, name, sex, born) values(?, ?, ?, ?)"; List<Object[]> parameterList = new ArrayList<>(); parameterList.add(new Object[]{1004, "甘夫人", "女", "2000-08-03"}); parameterList.add(new Object[]{1005, "麋夫人", "女", "2000-09-03"}); jdbcTemplate.batchUpdate(sql, parameterList); }
4. queryForObject:查询单个对象
常用的重载方法如下:
- queryForObject(String sql, Class<T> requiredType, Object... args):该方法返回requiredType指定类型的返回值, 第三个参数为可变参数。
- queryForObject(String sql, Object[] args, Class<T> requiredType):该方法返回requiredType指定类型的返回值,第二个参数为占位符需要传的参数。
@Test public void testCount() { //测试查询返回一个参数 String sql = "select count(*) from student"; Integer count = jdbcTemplate.queryForObject(sql, Integer.class); System.out.println(count); } @Test public void testQueryOne() { String sql = "select name from student where id = ?"; String name = jdbcTemplate.queryForObject(sql, String.class, 1004); System.out.println(name); }
- queryForObject(String sql, Object[] args, RowMapper<T> rowMapper):该方法返回T类型的实体类,RowMapper的实现类定义返回结果与实体类之间的映射关系,第二个参数为占位符需要的参数。
- queryForObject(String sql, RowMapper<T> rowMapper, Object... args):该方法返回T类型的实体类,RowMapper的实现类定义返回结果与实体类之间的映射关系,第三个参数为可变参数。
@Test public void testEntity() { String sql = "select id, name, sex, born from student where id = ?"; Student student = jdbcTemplate.queryForObject(sql, new StudentRowMapper(), 1001); System.out.println(student); }
RowMapper的实现类如下
private class StudentRowMapper implements RowMapper<Student>{ @Override public Student mapRow(ResultSet resultSet, int i) throws SQLException { Student stud = new Student(); stud.setId(resultSet.getInt("id")); stud.setName(resultSet.getString("name")); stud.setSex(resultSet.getString("sex")); stud.setBorn(resultSet.getDate("born")); return stud; } }
5. queryForList:返回对象列表
常用的重载方式如下:
- queryForList(String sql):返回类型为List<Map<String, Object>>。
- queryForList(String sql, Object... args):返回类型为List<Map<String, Object>>。
- queryForList(String sql, Object[] args, Class<T> requiredType):返回指定类型的列表。
- queryForList(String sql, Class<T> requiredType, Object... args):返回指定类型的列表。
@Test public void testQueryList() { String sql = "select name from student"; List<String> nameList = jdbcTemplate.queryForList(sql, String.class); System.out.println(nameList); }
@Test
public void testQueryMapList() {
String sql = "select id, name from student where id between ? and ?";
List<Map<String, Object>> objList = jdbcTemplate.queryForList(sql, 1001, 1005);
System.out.println(objList);
}
6. queryForMap:返回Map对象
常用的重载方式
queryForMap(String sql):没有占位符。
queryForMap(String sql, Object... args):第二个参数为可变参数。
@Test public void testQueryMap() { String sql = "select id, name, born from student where id = ?"; Map<String, Object> studentMap = jdbcTemplate.queryForMap(sql, 1001); System.out.println(studentMap); }
7. query:返回对象列表
常用的重载方法:
- query(String sql, RowMapper<T> rowMapper):rowMapper定义结果集和实体对象之间的映射关系。
- query(String sql, Object[] args, RowMapper<T> rowMapper):第二个参数定义占位符,第三个参数定义结果集和对象之间的映射关系。
- query(String sql, RowMapper<T> rowMapper, Object... args):第二个参数定义结果集合对象之间的映射关系,第三个参数为可变参数,定义占位符的值。
@Test public void testEntityList() { String sql = "select id, name, sex, born from student "; List<Student> studentList = jdbcTemplate.query(sql, new StudentRowMapper()); System.out.println(studentList); }
总结
JdbcTemplate是在jdbc api的基础上进行了封装,提高了数据库访问的灵活性,但是Spring并没有对数据库访问做更多的事,而是留给专门的持久层框架来做这些事。所以JdbcTemplate也有一些jdbc api遗留的问题,如sql和java代码在一起编写。
在学习JdbcTemplate时,主要学习的是慕课网的视频,也参考了下面博客,非常感谢
https://blog.csdn.net/weixin_40001125/article/details/88538576