spring boot中使用JdbcTemplate


本文將介紹如何將spring boot 與 JdbcTemplate一起工作。
Spring對數據庫的操作在jdbc上面做了深層次的封裝,使用spring的注入功能,可以把DataSource注冊到JdbcTemplate之中。 JdbcTemplate 是在JDBC API基礎上提供了更抽象的封裝,並提供了基於方法注解的事務管理能力。 通過使用SpringBoot自動配置功能並代替我們自動配置beans.

數據源配置
在maven中,我們需要增加spring-boot-starter-jdbc模塊
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
通過這個模塊為我們做了以下幾件事
    tomcat-jdbc-{version}.jar為我們自動配置DataSource.
    如果你沒有定義任何DataSource,SpringBoot將會自動配置一個內存的數據庫資源設置
    如果沒有設置任一個beans,SpringBoot會自動注冊它
    初始化數據庫
    如果我們在classpath里定義了schema.sql和data.sql文件,springBoot將會使用這些文件自動初始化數據庫(但你必須選建庫)
    除了載入schema.sql和data.sql外,SpringBoot也會載入schema-${platform}.sql和data-${platform}.sql,如果在你的classpath下存在的話。
    spring.datasource.schema=xxxx-db.sql 可以定義你的建庫文件
    spring.datasource.data=xxxx-data.sql  可以定義你的數據文件
    spring.datasource.initialize=true|false 可以決定是不是要初始化這些數據庫文件
    spring.datasource.continueOnError=true|false 有了錯誤是否繼續運行

嵌入式數據庫支持
嵌入式數據庫通常用於開發和測試環境,不推薦用於生產環境。Spring Boot提供自動配置的嵌入式數據庫有H2、HSQL、Derby,你不需要提供任何連接配置就能使用。
比如,我們可以在pom.xml中引入如下配置使用HSQL
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>runtime</scope>
</dependency>

連接生產數據源配置
以MySQL數據庫為例,先引入MySQL連接的依賴包,在pom.xml中加入:
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.21</version>
</dependency>

在src/main/resources/application.properties中配置數據源信息
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

連接JNDI數據源配置
當你將應用部署於應用服務器上的時候想讓數據源由應用服務器管理,那么可以使用如下配置方式引入JNDI數據源。
spring.datasource.jndi-name=java:jboss/datasources/customers

自定義數據源配置
如果你不想用默認的配置數據源,如你想用阿里巴巴的數據池管理數據源,你也可以自己配置
先排除tomcat-jdbc的默認配置dataSource
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

定義自己的數據資源 這里使用了阿里巴巴的數據池管理,你也可以使用BasicDataSource
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.19</version>
</dependency>

package com.example;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.DispatcherServlet;

import com.alibaba.druid.pool.DruidDataSource;
import com.example.Listener.IndexListener;
import com.example.filter.IndexFilter;
import com.example.servlet.MyServlet;

@SpringBootApplication
public class SpringBootSimpleApplication {
    @Autowired
    private Environment env;
    
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(env.getProperty("spring.datasource.url"));
        dataSource.setUsername(env.getProperty("spring.datasource.username"));//用戶名
        dataSource.setPassword(env.getProperty("spring.datasource.password"));//密碼
        dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setInitialSize(2);
        dataSource.setMaxActive(20);
        dataSource.setMinIdle(0);
        dataSource.setMaxWait(60000);
        dataSource.setValidationQuery("SELECT 1");
        dataSource.setTestOnBorrow(false);
        dataSource.setTestWhileIdle(true);
        dataSource.setPoolPreparedStatements(false);
        return dataSource;
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSimpleApplication.class, args);
    }
}

你也可以用別的:
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
    dataSource.setUrl(env.getProperty("spring.datasource.url"));
    dataSource.setUsername(env.getProperty("spring.datasource.username"));
    dataSource.setPassword(env.getProperty("spring.datasource.password"));
    return dataSource;
}

 

代碼示例
創建實體對象
/src/main/java/com/example/domain/User.java

package com.example.domain;

public class User
{
    private Integer id;
    private String name;
    private String email;

    public User()
    {
    }

    public User(Integer id, String name, String email)
    {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public Integer getId()
    {
        return id;
    }

    public void setId(Integer id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getEmail()
    {
        return email;
    }

    public void setEmail(String email)
    {
        this.email = email;
    }

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

創建持久層
有了上面的數據源配置,我們可以注入JdbcTemplate到數據訪問組件並與數據庫交互。
/src/main/java/com/example/repositories/UserRepository.java

package com.example.repositories;

import com.example.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.sql.*;
import java.util.List;

@Repository
public class UserRepository {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Transactional(readOnly = true)
    public List<User> findAll() {
        return jdbcTemplate.query("select * from users", new UserRowMapper());
    }

    @Transactional(readOnly = true)
    public User findUserById(int id) {
        return jdbcTemplate.queryForObject("select * from users where id=?", new Object[]{id}, new UserRowMapper());
    }

    public User create(final User user) {
        final String sql = "insert into users(name,email) values(?,?)";

        KeyHolder holder = new GeneratedKeyHolder();

        jdbcTemplate.update(new PreparedStatementCreator() {

            @Override
            public PreparedStatement createPreparedStatement(Connection connection)
                    throws SQLException {
                PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, user.getName());
                ps.setString(2, user.getEmail());
                return ps;
            }
        }, holder);

        int newUserId = holder.getKey().intValue();
        user.setId(newUserId);
        return user;
    }

    public void delete(final Integer id) {
        final String sql = "delete from users where id=?";
        jdbcTemplate.update(sql,
                new Object[]{id},
                new int[]{java.sql.Types.INTEGER});
    }

    public void update(final User user) {
        jdbcTemplate.update(
                "update users set name=?,email=? where id=?",
                new Object[]{user.getName(), user.getEmail(), user.getId()});
    }
}

class UserRowMapper implements RowMapper<User> {

    @Override
    public User mapRow(ResultSet rs, int rowNum) throws SQLException {
        User user = new User();
        user.setId(rs.getInt("id"));
        user.setName(rs.getString("name"));
        user.setEmail(rs.getString("email"));

        return user;
    }

}


單元測試
你或許己注意到,大多數時候,我們都在應用中做這些配置的事。
創建單元測試測試我們的持久層方法
/src/test/java/SpringBootJdbcDemoApplicationTests.java

import com.example.SpringBootJdbcDemoApplication;
import com.example.domain.User;
import com.example.repositories.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(SpringBootJdbcDemoApplication.class)
public class SpringBootJdbcDemoApplicationTests
{
     Logger logger= LoggerFactory.getLogger(SpringBootJdbcDemoApplicationTests.class);
    @Autowired
    private UserRepository userRepository;

    @Test public void testAll(){
        findAllUsers();
        findUserById();
        createUser();
    }

    @Test
    public void findAllUsers()  {
        List<User> users = userRepository.findAll();
        assertNotNull(users);
        assertTrue(!users.isEmpty());

    }

    @Test
    public void findUserById()  {
        User user = userRepository.findUserById(1);
        assertNotNull(user);
    }
    private void updateById(Integer id)  {
        User newUser = new User(id, "JackChen", "JackChen@qq.com");
        userRepository.update(newUser);
        User newUser2 = userRepository.findUserById(newUser.getId());
        assertEquals(newUser.getName(), newUser2.getName());
        assertEquals(newUser.getEmail(), newUser2.getEmail());
    }
    @Test
    public void createUser() {
        User user = new User(0, "tom", "tom@gmail.com");
        User savedUser = userRepository.create(user);
        logger.debug("{}",savedUser);
        User newUser = userRepository.findUserById(savedUser.getId());
        assertEquals("tom", newUser.getName());
        assertEquals("tom@gmail.com", newUser.getEmail());
        updateById(newUser.getId());
        userRepository.delete(newUser.getId());
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM