我们在 Spring Boot 整合 Mybatis 中提到了
myabtis-spring-boot-starter
中引入了spring-boot-starter-jdbc
依赖。而使用 JdbcTemplate 我们只需要在项目中引入spring-boot-starter-jdbc
就可以使用了。
1. 添加依赖
在项目中我们依然使用 Druid 连接池,故添加 Druid 相关依赖:
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
2. 配置文件
与配置 Mybatis 不同的是,在 application.yml 中不需要对 mybatis 进行配置,其他的完全一致,这里去除了 druid 的监控相关功能,只配置数据连接。
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
## 数据库连接
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: demo
password: demo
## 连接池配置
## 初始化大小
initial-size: 5
## 最小连接数
min-idle: 1
## 最大连接数
max-active: 20
## 连接等待超时时间 30s
max-wait: 30000
## 检测可以关闭的空闲连接间隔时间 60s
time-between-eviction-runs-millis: 60000
## 连接池中连接的最小生存时间 30s
min-evictable-idle-time-millis: 30000
validation-query: SELECT '1'
test-while-idle: true
test-on-borrow: false
test-on-return: false
## 打开 PSCache,指定每个连接的 PSCache 大小
pool-prepared-statements: true
max-open-prepared-statements: 20
max-pool-prepared-statement-per-connection-size: 20
3. 编写 Dao
基于 SOA 模型架构,首先提供一个 Dao 接口:
public interface IStudentDao {
/**
* 新增学生信息
* @param student 学生信息
* @return
*/
int add(Student student);
/**
* 删除学生信息
* @param studentId 学生id
* @return
*/
int delete(String studentId);
/**
* 更新学生信息
* @param student 学生信息
* @return
*/
int update(Student student);
/**
* 查询学生信息
* @param studentId 学生id
* @return
*/
Student queryById(String studentId);
/**
* 查询所有学生信息的学生类列表
* @return
*/
List<Student> queryList();
}
Dao 接口实现:
@Repository
public class StudentDaoImpl implements IStudentDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public int add(Student student) {
String sql = "insert into tb_student (S_ID, S_NAME, SEX) values (?, ?, ?)";
Object[] args = {student.getStudentId(), student.getName(), student.getSex()};
int[] argTypes = {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR};
return jdbcTemplate.update(sql, args, argTypes);
// String sql = "insert into tb_student(S_ID,S_NAME,SEX) values(:studentId,:name,:sex)";
// NamedParameterJdbcTemplate namedParameterJdbcTemplate =
// new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
// return namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(student));
}
@Override
public int delete(String studentId) {
String sql = "delete from tb_student where S_ID = ?";
Object[] args = {studentId};
int[] argTypes = {Types.VARCHAR};
return jdbcTemplate.update(sql, args, argTypes);
}
@Override
public int update(Student student) {
String sql = "update tb_student set S_NAME = ?, SEX = ? where S_ID = ?";
Object[] args = {student.getName(), student.getSex(), student.getStudentId()};
int[] argTypes = {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR};
return jdbcTemplate.update(sql, args, argTypes);
}
@Override
public Student queryById(String studentId) {
String sql = "select * from tb_student where S_ID = ?";
Object[] args = {studentId};
int[] argTypes = {Types.VARCHAR};
return jdbcTemplate.queryForObject(sql, args, argTypes, new StudentMapper());
}
@Override
public List<Student> queryList() {
String sql = "select * from tb_student";
return jdbcTemplate.query(sql, new StudentMapper());
}
}
可见使用 JdbcTemplate 与我们最开始接触的 JDBC 的使用方法一模一样:编写原生 sql 语句,通过 JdbcTemplate 执行 sql 语句返回结果。
在插入数据的时候可以用两种方式:
JdbcTemplate
的update
方法。NamedParameterJdbcTemplate
的update
方法。这两种方式的主要区别是:
NamedParameterJdbcTemplate
传入的 sql 语句中不使用 ?占位符,直接使用实体类的字段名称。所以在插入的字段较多时候,使用
NamedParameterJdbcTemplate
的update
方法可以起到缩减代码量的效果。
在执行查询语句后,需要将查询结果封装为对应的实体类之后再返回给调用者。作为 Spring 提供的 ORM 持久化技术之一, JdbcTemplate 当然也能通过添加映射关系来获取指定的实体类对象。
RowMapper 接口源码:
@FunctionalInterface
public interface RowMapper<T> {
/**
* Implementations must implement this method to map each row of data
* in the ResultSet. This method should not call {@code next()} on
* the ResultSet; it is only supposed to map values of the current row.
* @param rs the ResultSet to map (pre-initialized for the current row)
* @param rowNum the number of the current row
* @return the result object for the current row (may be {@code null})
* @throws SQLException if a SQLException is encountered getting
* column values (that is, there's no need to catch SQLException)
*/
@Nullable
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
该接口为配置映射关系的关键接口,我们通过实现 mapRow 方法即可配置映射关系:
public class StudentMapper implements RowMapper<Student> {
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setStudentId(rs.getString("S_ID"));
student.setName(rs.getString("S_NAME"));
student.setSex(rs.getString("SEX"));
return student;
}
}
4. 测试
新增数据:
@Test
public void addStudent() {
Student student = new Student();
student.setStudentId("004");
student.setName("Mark");
student.setSex("M");
int count = studentService.add(student);
System.out.println(count > 0 ? "add success" : "add fail");
}
通过 ID 查询:
@Test
public void queryStudent() {
Student student = studentService.queryById("004");
System.out.println(student);
}
Student{studentId='004', name='Mark', sex='M'}
更新数据:
@Test
public void updateStudent() {
Student student = studentService.queryById("004");
student.setName("Jane");
student.setSex("F");
int update = studentService.update(student);
System.out.println(update > 0 ? "update success" : "update fail");
}
查询列表:
@Test
public void delete() {
int delete = studentService.delete("004");
System.out.println(delete > 0 ? "delete success" : "delete fail");
}
Student{studentId='001', name='Jack', sex='M '}
Student{studentId='002', name='Jim', sex='M '}
Student{studentId='003', name='Julia', sex='F '}
Student{studentId='004', name='Jane', sex='F'}
源码地址:https://github.com/NekoChips/SpringDemo/tree/master/04.springboot-JdbcTemplate
关于作者:NekoChips
本文地址:https://chenyangjie.com.cn/articles/2020/04/25/1587791589614.html
版权声明:本篇所有文章仅用于学习和技术交流,本作品采用 BY-NC-SA 4.0 许可协议,如需转载请注明出处!
许可协议:
