SpringBoot—JdbcTemplate(数据持久化)

在Java领域,数据持久化有几个常见的方案,有Spring自带的JdbcTemplate、有MyBatis,还有JPA,在这些方案中,最简单的就是Spring自带的JdbcTemplate了,这个东西虽然没有MyBatis那么方便,但是比起最开始的Jdbc已经强了很多了,它没有MyBatis功能那么强大,当然也意味着它的使用比较简单,事实上,JdbcTemplate算是最简单的数据持久化方案了,本文就和大伙来说说这个东西的使用。

先来创建项目:

项目创建成功之后,记得添加Druid数据库连接池依赖(注意这里可以添加专门为Spring Boot打造的druid-spring-boot-starter而不是我们一般在SSM中添加的Druid),所有添加的依赖如下:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.27</version>
    <scope>runtime</scope>
</dependency>

项目创建完后,接下来只需要在application.properties中提供数据的基本配置即可,如下:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/lianxi

如此之后,所有的配置就算完成了,接下来就可以直接使用JdbcTemplate了?咋这么方便呢?其实这就是SpringBoot的自动化配置带来的好处,我们先说用法,一会来说原理。

首先我们来创建一个User Bean,如下:

@Component
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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

然后来创建一个UserService类,在UserService类中注入JdbcTemplate,如下:

@Service
public class UserService {
@Autowired
JdbcTemplate jdbcTemplate;

public Integer addUser(User user){
return jdbcTemplate.update("insert into user values (?,?,?)",user.getId(),user.getUsername(),user.getAddress());
}

public Integer updateUser(User user){
return jdbcTemplate.update("update user set username=? where id=?",new Object[] {user.getUsername(),user.getId()});
}

public Integer deleteUser(User user){
return jdbcTemplate.update("delete from user where id=?",new Object[] {user.getId()});
}

// public List<User> selectUser(){
// return jdbcTemplate.query("select * from user ", new RowMapper<User>() {
// @Override
// public User mapRow(ResultSet resultSet, int i) throws SQLException {
// User user=new User();
// user.setId(resultSet.getInt("id"));
// user.setUsername(resultSet.getString("username"));
// user.setAddress(resultSet.getString("address"));
// return user;
// }
// });
// }

public List<User> selectUser2(){ //简单方法,前提是bean要和名字一一对应
return jdbcTemplate.query("select * from user ",new BeanPropertyRowMapper<>(User.class));
}
}

增删改查——都在这里了!

最后测试:

@SpringBootTest
class JdbcApplicationTests {
    @Autowired
    UserService userService;
    @Autowired
    User user;

    @Test
    void contextLoads() {
        user.setId(14);
        user.setUsername("1sdfsasd");
        user.setAddress("asd");
        userService.addUser(user);
    }

    @Test
    void uptLoads() {
        user.setId(14);
        user.setUsername("rrrrrrrrr");
        userService.updateUser(user);
    }

    @Test
    void delLoads() {
        user.setId(1);
        userService.deleteUser(user);
    }

    @Test
    void selLoads() {
        List<User> lists= userService.selectUser2();
        System.out.println(lists);
    }
}

原理分析

那么在SpringBoot中,配置完数据库基本信息之后,就有了一个JdbcTemplate了,这个东西是从哪里来的呢?源码在org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration类中,该类源码如下:

@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcTemplateAutoConfiguration {

    @Configuration
    static class JdbcTemplateConfiguration {

        private final DataSource dataSource;

        private final JdbcProperties properties;

        JdbcTemplateConfiguration(DataSource dataSource, JdbcProperties properties) {
            this.dataSource = dataSource;
            this.properties = properties;
        }

        @Bean
        @Primary
        @ConditionalOnMissingBean(JdbcOperations.class)
        public JdbcTemplate jdbcTemplate() {
            JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
            JdbcProperties.Template template = this.properties.getTemplate();
            jdbcTemplate.setFetchSize(template.getFetchSize());
            jdbcTemplate.setMaxRows(template.getMaxRows());
            if (template.getQueryTimeout() != null) {
                jdbcTemplate
                        .setQueryTimeout((int) template.getQueryTimeout().getSeconds());
            }
            return jdbcTemplate;
        }

    }

    @Configuration
    @Import(JdbcTemplateConfiguration.class)
    static class NamedParameterJdbcTemplateConfiguration {

        @Bean
        @Primary
        @ConditionalOnSingleCandidate(JdbcTemplate.class)
        @ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
        public NamedParameterJdbcTemplate namedParameterJdbcTemplate(
                JdbcTemplate jdbcTemplate) {
            return new NamedParameterJdbcTemplate(jdbcTemplate);
        }

    }

}

从这个类中,大致可以看出,当当前类路径下存在DataSource和JdbcTemplate时,该类就会被自动配置,jdbcTemplate方法则表示,如果开发者没有自己提供一个JdbcOperations的实例的话,系统就自动配置一个JdbcTemplate Bean(JdbcTemplate是JdbcOperations接口的一个实现)。