欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Springboot系列-整合JdbcTemplate

程序员文章站 2024-02-07 23:02:34
...

Springboot系列-整合JdbcTemplate

前言:在项目开发中,很多时候需要对大量数据进行持久化,数据持久化常见的几种方式如:Spring自带的Template,mybatis或者常说的JPA等,此篇博客将主要对JdbcTemplate进行整合,虽然Template不如mybatis使用方便,但是JdbcTemplate算是最简单的数据持久化方案了


1.配置JdbcTemplate

1.新建JDBC API项目,选上 Jdbc 依赖,以及数据库驱动依赖即可

Springboot系列-整合JdbcTemplate

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系列