Springboot系列-整合JdbcTemplate
Springboot系列-整合JdbcTemplate
前言:在项目开发中,很多时候需要对大量数据进行持久化,数据持久化常见的几种方式如:Spring自带的Template,mybatis或者常说的JPA等,此篇博客将主要对JdbcTemplate进行整合,虽然Template不如mybatis使用方便,但是JdbcTemplate算是最简单的数据持久化方案了
1.配置JdbcTemplate
1.新建JDBC API项目,选上 Jdbc 依赖,以及数据库驱动依赖即可
2.配置pom文件导入依赖,添加 Druid 数据库连接池依赖,此处注意不是一般在 SSM 中添加的 Druid,而是为springboot提供的druid-spring-boot-starter
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
3.修改application.properties,引用alibaba数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/template?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
所有的配置完成之后,就可以直接使用 JdbcTemplate了,因为springboot的自动化配置,所以在操作上相对简洁一些
2.使用JdbcTemplate
1.新建一个user类
public class User {
private Integer id;
private String username;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
2.然后来创建一个 UserService 类,在 UserService 类中注入 JdbcTemplate ,如下:
@Service
public class UserService {
@Autowired
JdbcTemplate jdbcTemplate;
}
3.到此前期准备工作就完成了,接下来我们通过JdbcTemplate来实现对数据的增删改查操作,直接附上代码如下:
@Service
public class UserService {
@Autowired
JdbcTemplate jdbcTemplate;
//这里只需要传入 SQL 即可
public int addUser(User user) {
return jdbcTemplate.update("insert into user (username,address) values (?,?);", user.getUsername(), user.getAddress());
}
//如果你的需求比较复杂,例如在数据插入的过程中希望实现主键回填,那么可以使用 PreparedStatementCreator
public int addUser2(User user) {
KeyHolder keyHolder = new GeneratedKeyHolder();
int update = jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
//首先在构建 PreparedStatement 时传入 Statement.RETURN_GENERATED_KEYS
PreparedStatement ps = connection.prepareStatement("insert into user (username,address) values (?,?);", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, user.getUsername());
ps.setString(2, user.getAddress());
return ps;
}
//然后传入 KeyHolder
}, keyHolder);
//最终从 KeyHolder 中获取刚刚插入数据的 id 保存到 user 对象的 id 属性中去
user.setId(keyHolder.getKey().intValue());
System.out.println(user.getId());
return update;
}
//删除也是使用 update API,传入SQL 即可
public int deleteUserById(Long id) {
return jdbcTemplate.update("delete from user where id=?", id);
}
//此处也可以使用 PreparedStatementCreator
public int updateUserById(User user) {
return jdbcTemplate.update("update user set username=?,address=? where id=?", user.getUsername(), user.getAddress(),user.getId());
}
//查询的话,和之前的增删改不同,此处使用 JdbcTemplate的 query 方法
public List<User> getAllUsers() {
//查询时需要提供一个 RowMapper,就是需要自己手动映射,将数据库中的字段和对象的属性一一对应起来
return jdbcTemplate.query("select * from user", new RowMapper<User>() {
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
String username = resultSet.getString("username");
String address = resultSet.getString("address");
int id = resultSet.getInt("id");
User user = new User();
user.setAddress(address);
user.setUsername(username);
user.setId(id);
return user;
}
});
}
//简单查询方法:前提是数据库中的字段和对象属性的名字一样
public List<User> getAllUsers2() {
return jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<>(User.class));
}
//根据某个参数查询
public User getUserById(Integer id) {
return jdbcTemplate.queryForObject("select * from user where id = ?", new BeanPropertyRowMapper<>(User.class),id);
}
}
由以上代码可以看出在JdbcTemplate 中,除了查询有几个 API 之外,增删改统一都使用 update 来操作,自己来传入 SQL 即可;update 方法的返回值就是 SQL 执行受影响的行数
3.原理分析
在 SpringBoot 中,配置完数据库基本信息之后,就会有一个 JdbcTemplate ,打开它的源码,路径在
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({DataSource.class, JdbcTemplate.class})
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({JdbcProperties.class})
@Import({JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class})
public class JdbcTemplateAutoConfiguration {
public JdbcTemplateAutoConfiguration() {
}
}
从这个类中可以看出,当前类路径下存在 DataSource 和 JdbcTemplate 时,该类就会被自动配置
4.多数据源配置
多数据源配置也是一个常见的开发需求,顾名思义大家也知道和上面配置有何区别,在Spring Boot 中,JdbcTemplate、MyBatis 以及 Jpa 都可以配置多数据源
,接下来我们在上述的基础上进行一些修改
1.在 application.properties 中配置数据源,通过one,two区分
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.username=root
spring.datasource.one.password=201314
spring.datasource.one.url=jdbc:mysql://localhost:3306/template?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
#配置多数据源
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.username=root
spring.datasource.two.password=123456
spring.datasource.two.url=jdbc:mysql://localhost:3306/template1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
2.加 one 和 two 区分之后,配置无法被 SpringBoot 自动加载(因为前面 key 变化了),所以需要自己加载 DataSource ,此时需要配置一个 DataSourceConfig
@Configuration
public class DateSourceConfig {
@Bean
//@ConfigurationProperties 是 Spring Boot 提供的类型安全的属性绑定
//表示使用 spring.datasource.one 前缀的数据库配置去创建一个 DataSource
@ConfigurationProperties(prefix = "spring.datasource.one")
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}
3.创建 JdbcTemplateConfig 类,用来提供两个不同的 JdbcTemplate 实例;每个 JdbcTemplate 的创建都需要一个 DataSource,由于 Spring 容器中现在存在两个 DataSource,因此加上 @Qualifier 注解,表示按照名称查找:
@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dsOne) {
return new JdbcTemplate(dsOne);
}
@Bean
JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dsTwo) {
return new JdbcTemplate(dsTwo);
}
}
4.然后在controller进行测试,如下:
@RestController
public class DsController {
@Autowired
@Qualifier("jdbcTemplateOne")
JdbcTemplate jdbcTemplateOne;
@Resource(name = "jdbcTemplateTwo")
JdbcTemplate jdbcTemplateTwo;
@GetMapping("/user")
public List<User> getAllUser() {
List<User> list = jdbcTemplateOne.query("select * from t_user", new BeanPropertyRowMapper<>(User.class));
return list;
}
@GetMapping("/user2")
public List<User> getAllUser2() {
List<User> list = jdbcTemplateTwo.query("select * from t_user", new BeanPropertyRowMapper<>(User.class));
return list;
}
}
Spring 容器中的 JdbcTemplate 也是有两个,因此不能通过 byType 的方式注入进来,所以可以使用 @Resource 注解,通过 byName 的方式注入进来,也可以使用 @Autowired 注解加上 @Qualifier 注解同样当做是 byName方式注入
将 JdbcTemplate 注入进来之后,jdbcTemplateOne 和 jdbcTemplateTwo 此时代表操作不同的数据源,使用不同的 JdbcTemplate 操作不同的数据源,实现了多数据源配置
结语:对于在springboot中的JdbcTemplate的配置、使用以及多数据源的配置与使用基本上就到这了,虽然在开发中用mybatis的占大多数,不过涉及到业务简单的小打小闹的可以使用相对轻巧的JdbcTemplate
推荐阅读
-
Springboot系列-整合JdbcTemplate
-
SpringBoot+Mybatis+PageHelper+logback+Swagger+Maven的整合配置
-
Dubbo与SpringBoot整合流程(从实例入手,附代码下载)
-
springboot系列文章 博客分类: springbootshiromybatisredis
-
springboot系列文章 博客分类: springbootshiromybatisredis
-
thinkphp整合系列之phpqrcode生成二维码
-
SpringBoot 整合 Shiro 认证返回 json 数据
-
春节酷站系列!帮你整合Dribbble上可以免费下载的优质素材_html/css_WEB-ITnose
-
springboot整合docker部署(两种构建Docker镜像方式)
-
SpringBoot整合Flyway的方法(数据库版本迁移工具)