Spring Boot 2系列(十九):Spring JDBC JdbcTemplate 集成与使用

  JdbcTemplate 是由 Spring Data JDBC 项目提供的,Spring Data JDBC 可以轻松实现基于 JDBC 的存储库,处理对基于 JDBC 的数据访问层的增强支持,

  Spring Boot 为使用 JDBC 提供了自动配置,将 JdbcTemplate 注册了为 Bean,自动配置了数据源,JDBC 自动配置类:org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration

  JdbcTemplate 类是 JDBC 核心包中的核心类,执行核心 JDBC 工作汉,简化了 JDBC 的使用。

  Spring Framework Documentation > Data Access with JDBCSpring Data JDBC 项目Spring Boot Using Jdbc Template

Spring Data JDBC

JdbcTemplate 提供的功能包括:运行 SQL 语句、更新、调用存储过程、对结果集执行迭代,并提取返回的参数值、捕包 JDBC 异常。

JdbcTemplate 方法

JdbcTemplate 主要提供操作的方法:

  • execute:可以执行任何 SQL 语句。
  • query:执行查询语句。
  • update:插入、更新、删除都在这一类方法里。
  • batchUpdate:执行批处理相关语句。
  • call:调用存储过程。

使用 JdbcTemplate

  1. Querying (SELECT)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    //统计行数
    int rowCount = this.jdbcTemplate.queryForObject("select count(*) from t_actor", Integer.class);

    //条件查询,绑定变量
    int countOfActorsNamedJoe = this.jdbcTemplate.queryForObject(
    "select count(*) from t_actor where first_name = ?", Integer.class, "Joe");

    //查询字符串
    String lastName = this.jdbcTemplate.queryForObject(
    "select last_name from t_actor where id = ?",
    new Object[]{1212L}, String.class);

    //返回一个实体类
    Actor actor = this.jdbcTemplate.queryForObject(
    "select first_name, last_name from t_actor where id = ?",
    new Object[]{1212L},
    new RowMapper<Actor>() {
    public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
    Actor actor = new Actor();
    actor.setFirstName(rs.getString("first_name"));
    actor.setLastName(rs.getString("last_name"));
    return actor;
    }
    });

    //返回多个实体类
    List<Actor> actors = this.jdbcTemplate.query(
    "select first_name, last_name from t_actor",
    new RowMapper<Actor>() {
    public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
    Actor actor = new Actor();
    actor.setFirstName(rs.getString("first_name"));
    actor.setLastName(rs.getString("last_name"));
    return actor;
    }
    });


    //提取相同的 RowMapper
    public List<Actor> findAllActors() {
    return this.jdbcTemplate.query( "select first_name, last_name from t_actor", new ActorMapper());
    }
    private static final class ActorMapper implements RowMapper<Actor> {

    public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
    Actor actor = new Actor();
    actor.setFirstName(rs.getString("first_name"));
    actor.setLastName(rs.getString("last_name"));
    return actor;
    }
    }
  2. Updating (INSERT, UPDATE, and DELETE)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //插入数据
    this.jdbcTemplate.update(
    "insert into t_actor (first_name, last_name) values (?, ?)",
    "Leonor", "Watling");
    //更新数据
    this.jdbcTemplate.update(
    "update t_actor set last_name = ? where id = ?",
    "Banjo", 5276L);
    //删除数据
    this.jdbcTemplate.update(
    "delete from actor where id = ?",
    Long.valueOf(actorId));
  3. Execute 执行任何 SQL 语句,通常用于 DDL 语句。

    1
    2
    3
    4
    5
    6
    7
    //创建一个表
    this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");

    //调用存储过程
    this.jdbcTemplate.update(
    "call SUPPORT.REFRESH_ACTORS_SUMMARY(?)",
    Long.valueOf(unionId));

Spring Boot 集成 JdbcTemplate

JdbcTemplate 处理资源创建和释放,Statement 创建和执行,使应用代码获取结果。JdbcTemplate 提供了 CRUD 方法 和调用存储过程的方法,对 ResultSets 执行迭代并返回,捕获 JDBC 异常。

JdbcTemplate 是非常经典和流行的数据库访问技术,但现在已经有成熟ORM框架可以提供更简结的操作和更优的代码结构来支持对数据库的访问。

JdbcTemplate 个人在实际开发中使用不多。 还有一些其它功能更丰富简便的数据访问技术,如 JPA 等。

添加依赖

Spring Boot 中使用 JdbcTemplate,需要添加 JDBC 依赖,Spring Boot 检测到有此库时就会执行与其相应的自动配置。

支持 JdbcTemplate 操作的有两个依赖包,分别是 spring-boot-starter-jdbcspring-boot-starter-data-jdbc

  • spring-boot-starter-jdbc:只提供基于 JdbcTemplate 的操作。
  • spring-boot-starter-data-jdbc:包含了 spring-boot-starter-jdbc 包,还包含了 spring-data-commons 包,此包提供了 Spring Data Repository 功能,在使用时,继承此接口。

pom.xml

1
2
3
4
5
6
7
8
9
10
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

JDBC 配置

JDBC 属性配以 spring.jdbc.template.* 为前缀。如下:

1
2
spring.jdbc.template.max-rows=-1
spring.jdbc.template.fetch-size=-1

JdbcTemplate 操作

在添加了 spring-boot-starter-data-jdbc 包后,Spring Boot 会自动将 JdbcTemplate 注册为 Bean,使用时直接注入即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

@Service
public class UserServiceImpl implements UserService {

@Autowired
private JdbcTemplate jdbcTemplate;


/**
* 增-insert
* @param user
* @return
*/
@Override
public int addUser(User user) {
String sql = "insert into user (id,name,age,address) values (?,?,?,?)";
return jdbcTemplate.update(sql, user.getId(),user.getName(), user.getAge(), user.getAddress());
}

/**
* 改-update
* @param name
* @return
*/
@Override
public int updateUser(String name, Long id) {
String sql = "update user set name = ? where id = ?";
return jdbcTemplate.update(sql, name, id);
}

/**
* 删除-delete
* @param id
* @return
*/
@Override
public int deleteUser(Long id) {
String sql = "delete from user where id = ?";
return jdbcTemplate.update(sql,id);
}

/**
* rowCount
* @return
*/
@Override
public int queryCount() {
String sql = "select count(*) from user";
return jdbcTemplate.queryForObject(sql, Integer.class);
}

/**
* count by
* @return
*/
@Override
public int queryCountByLastName(String lastName) {
String sql = "select count(*) from actor where last_name = ?";
return jdbcTemplate.queryForObject(sql,Integer.class,lastName);
}

/**
* 查询结果是字符串
* @param actorId
* @return
*/
@Override
public String queryLastName(Long actorId) {
String sql = "select last_name from actor where actor_id = ?";
Object[] objArr = new Object[1];
objArr[0] = actorId;
return jdbcTemplate.queryForObject(sql, objArr, String.class);
}

/**
* 返回对象
* @param actorId
* @return
*/
@Override
public Actor queryByActorId(Long actorId) {
String sql = "select * from actor where actor_id = ?";
Object[] objArr = new Object[1];
objArr[0] = actorId;

RowMapper<Actor> actorRowMapper = new RowMapper<Actor>() {
@Override
public Actor mapRow(ResultSet resultSet, int i) throws SQLException {
Actor actor = new Actor()
.setFirstName(resultSet.getString("first_name"))
.setLastName(resultSet.getString("last_name"))
.setActorId(resultSet.getLong("actor_id"))
.setLastUpdate(resultSet.getDate("last_update"));
return actor;
}
};
return jdbcTemplate.queryForObject(sql, objArr, actorRowMapper);
}

/**
* 查询对象集合
* @return
*/
@Override
public List<Actor> queryActorList() {
String sql = "select * from actor";
RowMapper<Actor> actorRowMapper = new RowMapper<Actor>() {
@Override
public Actor mapRow(ResultSet resultSet, int i) throws SQLException {
Actor actor = new Actor()
.setFirstName(resultSet.getString("first_name"))
.setLastName(resultSet.getString("last_name"))
.setActorId(resultSet.getLong("actor_id"))
.setLastUpdate(resultSet.getDate("last_update"));
return actor;
}
};
return jdbcTemplate.query(sql,actorRowMapper);
}

}

Repository 操作

  1. 添加 spring-boot-starter-data-jdbc 依赖包,集成的 spring-data-commons 包提供了 Spring Data Repository 功能。

  2. 继承 CrudRepository 接口,需要分页排序的话,增加继承 PagingAndSortingRepository 接口

    实体类的 Repository 接口

    1
    2
    3
    @Repository
    public interface UserInfoRepository extends CrudRepository<UserInfo, Long>, PagingAndSortingRepository<UserInfo, Long> {
    }

    调用 Repository 接口方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Service
    public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private UserInfoRepository userInfoRepository;

    public UserInfo getByIdFromRepo(Long id) {
    Optional<UserInfo> userInfoOptional = userInfoRepository.findById(id);
    UserInfo userInfo = userInfoOptional.orElse(null);
    return userInfo;
    }
    }

源码 -> Github

Spring Boot 2系列(十九):Spring JDBC JdbcTemplate 集成与使用

http://blog.gxitsky.com/2018/06/25/SpringBoot-19-jdbcTemplate/

作者

光星

发布于

2018-06-25

更新于

2022-06-17

许可协议

评论