JdcbTemplate简介
在Java领域,数据持久化有几个常见的方案,有Spring自带的JdbcTemplate、MyBatis、JPA等,在这些方案中,最简单的就是Spring自带的JdbcTemplate了。JdbcTemplate 是在JDBC API基础上提供了更抽象的封装,通过模板设计模式帮助我们消除了冗长的代码,其缺点是移植性较差。
下面来看看如何在Spring Boot中使用JdcbTemplate
依赖引入
首先在项目中引入基本的Web依赖,Jdbc依赖,数据库驱动依赖(这里引入MySQL)。
我使用的Spring Boot版本–Spring Boot 2.2.4中默认的MySQL版本号为8.0.19,建议引入的MySQL依赖对应自己之前使用的版本,避免出现不兼容情况。
pom.xml中引入的依赖包:
<dependencies>
<!--jdbc依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.29</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
数据库配置
在application.properties中提供以下基本配置:
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=123456
这样就完成了JdcbTemplate的整合。
数据准备
我这里是在数据库springboot下创建student表,sql脚本如下:
create table student(
id int auto_increment PRIMARY KEY,
name VARCHAR(30)
);
insert into student(id,name) values(1,'张3');
insert into student(id,name) values(2,'张4');
insert into student(id,name) values(3,'张5');
insert into student(id,name) values(4,'张6');
然后在另一个数据库ssm中创建teacher表,sql脚本如下:
create table teacher(
id int auto_increment PRIMARY KEY,
name VARCHAR(30)
);
insert into teacher(id,name) values(1,'老师1');
insert into teacher(id,name) values(2,'老师2');
insert into teacher(id,name) values(3,'老师3');
insert into teacher(id,name) values(4,'老师4');
基本用法
首先创建一个Student类,如下:
public class Student {
private int id;
private String name;
//getter和setter方法省略
}
然后创建一个StudentService类,其中注入JdbcTemplate,如下;
@Service
public class StudentService {
@Autowired
JdbcTemplate jdbcTemplate;
}
JdbcTemplate中,除了查询有几个API之外,增删改统一都使用update方法来操作,自己传入SQL即可。update方法的返回值就是SQL执行受影响的行数。
下面是使用update方法进行增删改的例子:
//插入学生数据
public int addStudent(Student student){
return jdbcTemplate.update("insert into student(id,name) values(?,?)",student.getId(),student.getName());
}
//更新学生数据
public int updStudent(int id,String name){
return jdbcTemplate.update("update student set name=? where id=?",name,id);
}
//删除学生数据
public int delStudent(int id){
return jdbcTemplate.update("delete from student where id=?",id);
}
这里只是简单的使用update(String sql, Object… args)”来实现对预编译语句设值。
下面是进行查询的例子:
RowMapper作用:用于将结果集每行数据转换为需要的类型,用户需实现方法mapRow(ResultSet rs, int rowNum)来完成将每行数据转换为相应的类型。
查询的时候需要提供一个RowMapper,在RowMapper手动映射,将数据库中的字段和对象属性一一对应。
//查询学生数据
public List<Student> queryAllStudent(){
return jdbcTemplate.query("select * from student", new RowMapper<Student>() {
@Override
public Student mapRow(ResultSet resultSet, int i) throws SQLException {
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
Student student=new Student();
student.setId(id);
student.setName(name);
return student;
}
});
}
当我们定义的数据库中的字段和对象属性名本就一一对应时,就可以使用BeanPropertyRowMapper<>(Student.class)作为参数,无需使用RowMapper。如下:
//查询学生数据的第二种方式
public List<Student> queryAllStudent2(){
return jdbcTemplate.query("select * from student",new BeanPropertyRowMapper<>(Student.class));
}
在测试类中实现以下测试方法,调用service中的查询方法进行测试:
//测试查询
@Test
public void queryTest(){
List<Student> list=studentService.queryAllStudent();
for (Student student:list){
System.out.println("编号:"+student.getId()+" "+"姓名:"+student.getName());
}
}
//测试查询
@Test
public void queryTest2(){
List<Student> list=studentService.queryAllStudent2();
for (Student student:list){
System.out.println("编号:"+student.getId()+" "+"姓名:"+student.getName());
}
}
测试结果如下,两个方法都成功查询到了。
多数据源配置
多数据源配置是一个比较常见的开发需求,下面我们来看看在JdcbTemplate如何配置多数据源。
1.依赖引入
以上面使用到的项目为基础,添加以下依赖:
注意添加的是druid-spring-boot-starter依赖,而不是传统的druid依赖。它是为Spring Boot专门打造的。druid-spring-boot-starter依赖中提供了DruidDataSourceBuilder类,这个类可以用来构建一个DataSource实例,而传统的druid则没有该类。
<!--Druid数据库连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
2.数据源配置
在application.properties中配置数据源,这里以两个数据源为例:
#数据源1
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.one.username=root
spring.datasource.one.password=123456
#数据源2
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.url=jdbc:mysql://localhost:3306/ssm
spring.datasource.two.username=root
spring.datasource.two.password=123456
加了one和two区分不同数据源后,这里的配置就不能被Spring Boot自动加载,这就需要我们在新建一个配置类来加载这两个数据源。
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
DataSource dsOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource dsTwo(){
return DruidDataSourceBuilder.create().build();
}
}
这里提供了两个Bean,其中@ConfigurationProperties是Spring Boot提供的类型安全的属性绑定,以第一个Bean为例,@ConfigurationProperties(prefix = “spring.datasource.one”)表示使用spring.datasource.one前缀的数据库配置去创建一个DataSource。通过以上配置,我们就有了两个不同的DataSource。
接下来再用这两个不同的DataSource去创建两个不同的JdbcTemplate对象。
3.配置JdbcTemplate实例
创建一个类名为JdbcTemplateConfig,这里注意添加注解@Qualifier(“Bean的名称”)指定参数是哪个DataSource,如下:
@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean
JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
这里创建了两个JdbcTemplate实例,分别对应了两个DataSource。每一个JdbcTemplate的创建都需要一个DataSource,由于Spring容器中现在存在两个DataSource,默认使用类型查找,会报错,因此加上@Qualifier注解,表示按照名称查找。
4.测试
以上文使用的项目为基础,配置了多数据源后,因为Spring容器中有两个JdbcTemplate,而前面使用的@Autowired注解是按类型注入JdbcTemplate,此时需要加上@Qualifier注解声明JdbcTemplate的名字。如下:
@Autowired
@Qualifier("jdbcTemplateOne")
JdbcTemplate jdbcTemplate;
这样前面的方法就都不会受到影响。
添加Teacher类
public class Teacher {
private int id;
private String name;
//getter和setter方法省略
}
在测试类中添加以下方法来测试查询另一个数据库的teacher表数据。
这里使用另一种方式注入 JdbcTemplate:通过@Resource注解,直接通过byName的方式注入。
//连接另一个数据库
@Resource(name = "jdbcTemplateTwo")
JdbcTemplate jdbcTemplate;
@Test
public void queryTeacherTest(){
List<Teacher> list=jdbcTemplate.query("select * from teacher", new BeanPropertyRowMapper<>(Teacher.class));
for (Teacher teacher:list){
System.out.println("编号:"+teacher.getId()+" "+"姓名:"+teacher.getName());
}
}
启动该方法,测试结果如下:
详细学习JdcbTemplate:
【第七章】对JDBC的支持之7.2 JDBC模板类-跟我学spring3