1. 程式人生 > >Spring的JDBC模板

Spring的JDBC模板

driver println 傳統 -i jdb cte char handle bject

Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架。它針對JavaEE三層中的每一層都提供了不同的解決技術,在dao層,Spring提供了JDBC模板的技術,可對數據庫進行CRUD操作。Spring提供了很多持久層技術的模板類簡化了編程,如下圖:

技術分享圖片

Spring框架對不同的持久層技術做了封裝,如對傳統的JDBC使用JdbcTemplate進行了封裝,對Hibernate框架使用HibernateTemplate進行了封裝。JdbcTemplate對JDBC進行了簡單封裝,使用類似於dbutils,但是使用並沒有dbutils方便,只是提供了一種實現的方式而已。下面來演示使用JdbcTemplate模板類實現CRUD操作。

使用JdbcTemplate模板類實現CRUD操作

首先創建數據庫和表,如下:

create database spring_lee;
use spring_lee;

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `username` varchar(100) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

使用JdbcTemplate模板類還須導入jar包,先引入JdbcTemplate的jar包:

技術分享圖片

但我們要知道spring-jdbc-4.2.4.RELEASE.jar包才是最主要的。除此之外還須導入MySQL數據庫驅動的jar包。

添加操作

在src目錄下創建一個cn.itcast.jdbcTemplate包,並在該包下編寫一個JdbcTemplateDemo1單元測試類。現在要編寫一個add方法來測試添加操作。

public class JdbcTemplateDemo1 {

    // 1.添加操作
    @Test
    public void add() {
        // 1.設置數據庫相關信息(JDBC模板依賴連接池獲得數據庫連接,所以必須先構造連接池)
        DriverManagerDataSource dataSource = new
DriverManagerDataSource(); // 數據源 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///spring_lee"); dataSource.setUsername("root"); dataSource.setPassword("yezi"); // 2.做添加的操作 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); String sql = "insert into user values(?,?)"; int rows = jdbcTemplate.update(sql, "liayun", "lee"); System.out.println(rows); } }

註意:JDBC模板依賴連接池獲得數據庫連接,所以必須先構造連接池,然後再創建JdbcTemplate模板類對象。而且還須用到JdbcTemplate模板類的update方法:

技術分享圖片

這個方法中有兩個參數:

  • 第一個參數是sql語句。
  • 第二個參數是傳遞的參數值,Object類型的可變參數。

修改操作

現在要在單元測試類中編寫一個update方法來測試修改操作。

public class JdbcTemplateDemo1 {

    // 2.修改操作
    @Test
    public void update() {
        // 1.設置數據庫相關信息
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_lee");
        dataSource.setUsername("root");
        dataSource.setPassword("yezi");

        // 實現修改操作
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "update user set password=? where username=?";
        int rows = jdbcTemplate.update(sql, "9999", "liayun");
        System.out.println(rows);
    }

}

刪除操作

現在要在單元測試類中編寫一個delete方法來測試刪除操作。

public class JdbcTemplateDemo1 {

    // 3.刪除操作
    @Test
    public void delete() {
        // 1.設置數據庫相關信息
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_lee");
        dataSource.setUsername("root");
        dataSource.setPassword("yezi");

        // 實現刪除操作
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "delete from user where username=?";
        int rows = jdbcTemplate.update(sql, "liayun");
        System.out.println(rows);
    }

}

查詢操作

查詢表中的記錄數

現在要在單元測試類中編寫一個testCount方法來測試查詢表中記錄數的操作。

public class JdbcTemplateDemo1 {

    // 查詢表記錄數
    @Test
    public void testCount() {
        // 1.設置數據庫相關信息
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_lee");
        dataSource.setUsername("root");
        dataSource.setPassword("yezi");

        // 2.創建JdbcTemplate模板類的對象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        // 3.sql語句
        String sql = "select count(*) from user";
        // 4.調用JdbcTemplate模板類裏面的方法
        // 返回int類型
        int count = jdbcTemplate.queryForObject(sql, Integer.class);
        System.out.println(count);
    }

在查詢表中記錄數的操作時,用到了JdbcTemplate模板類裏面的queryForObject方法,如下:

技術分享圖片

這個方法中有兩個參數:

  • 第一個參數:sql語句
  • 第二個參數:返回類型的class

查詢返回對象

使用JdbcTemplate模板類進行查詢操作的時候,還是比較麻煩的。前面我也說過JdbcTemplate對JDBC進行了簡單封裝,使用類似於dbutils,但是使用並沒有dbutils方便,只是提供了一種實現的方式而已。為何這麽說呢?因為在dbutils裏面幫我們編寫好了一些實現類,使用這些實現類可以封裝結果,這些實現類都實現了接口ResultSetHandler;使用JdbcTemplate模板類進行查詢操作返回數據結果的時候,雖然在JdbcTemplate模板類中有個接口,但是並沒有提供實現類,故還需要自己編寫實現類來封裝結果。

首先在cn.itcast.jdbcTemplate包下編寫一個User類。

public class User {

    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }

}

接下來,就來講如何使用JdbcTemplate模板類進行查詢操作並返回一個User類的對象。其中就要用到JdbcTemplate模板類裏面的queryForObject方法:

技術分享圖片

這個方法有3個參數:

  • 第一個參數:sql語句
  • 第二個參數:RowMapper接口
    1. 之前使用dbutils進行查詢時,返回結果有ResultSetHandler接口,但是在dbutils裏面有其對應的實現類。
    2. 使用JdbcTemplate模板類的時候,雖然提供了RowMapper接口,但是這個接口沒有實現類,需要自己進行實現,然後進行數據封裝。
  • 第三個參數:可變參數

現在要在JdbcTemplateDemo2單元測試類中編寫一個testObject方法來測試查詢時返回一個User類對象的操作。

public class JdbcTemplateDemo2 {

    // 1.查詢返回對象
    @Test
    public void testObject() {

        // 1.設置數據庫相關信息
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_lee");
        dataSource.setUsername("root");
        dataSource.setPassword("yezi");

        // 2.創建JdbcTemplate對象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        // 3.sql語句
        String sql = "select * from user where username=?";

        // 4.調用方法執行
        // 第二個參數是接口,RowMapper,要自己創建一個類實現這個接口,在裏面進行封裝
        User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), "mary");
        System.out.println(user);

    }

}

註意,還要編寫RowMapper接口的一個實現類。在以上JdbcTemplateDemo2.java源代碼文件中編寫RowMapper接口的一個MyRowMapper實現類。

/ T:表示要將數據封裝到哪個類的對象中
class MyRowMapper implements RowMapper<User> {

    // 實現接口裏面的方法,在方法中實現數據封裝
    // 第一個參數:返回的結果集,第二個參數是當前的行數(即第幾行)
    @Override
    public User mapRow(ResultSet rs, int rows) throws SQLException {
        // 從結果集得到數據
        String username = rs.getString("username");
        String password = rs.getString("password");

        // 封裝到對象裏面
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        return user;
    }

}

查詢返回List集合

現在要在JdbcTemplateDemo2單元測試類中編寫一個testList方法來測試查詢時返回List集合的操作。

public class JdbcTemplateDemo2 {

    // 2.返回List集合
    @Test
    public void testList() {

        // 1.設置數據庫相關信息
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_lee");
        dataSource.setUsername("root");
        dataSource.setPassword("yezi");

        // 2.查詢操作
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "select * from user";

        List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
        System.out.println(list);

    }

}

在進行查詢並返回List集合的操作時,須用到JdbcTemplate模板類裏面的query方法:

技術分享圖片

技術分享圖片

Spring配置連接池

在實際開發中,一般都會用Spring配置C3P0連接池,所以下面我就來重點介紹在Spring中如何配置C3P0連接池。
首先引入Spring的配置文件,主要是引入約束:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">

</beans>

接著導入Spring的基本jar包,除此之外,還要導入C3P0的jar包:

技術分享圖片

試想要是以前在Web項目中配置C3P0連接池,勢必會寫這樣的代碼:

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUser(user);
dataSource.setPassword(password);

而現在我們就可以在Spring配置文件(bean2.xml)中配置C3P0連接池了,即在Spring配置文件中添加如下配置:

<!-- 配置C3P0連接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql:///spring_lee"></property>
    <property name="user" value="root"></property>
    <property name="password" value="yezi"></property>
</bean>

現在舉例來演示如何在Spring中配置C3P0連接池了。創建一個UserService類和一個UserDao類,然後在UserService類裏面調用UserDao類的方法,在UserDao類中使用JdbcTemplate模板類進行數據庫CRUD操作,並且用上C3P0連接池。
先在src目錄下創建一個cn.itcast.c3p0包,並在該包下編寫一個UserDao類。

public class UserDao {

    // 在Dao裏面要得到JdbcTemplate對象
    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    // 添加操作,使用JdbcTemplate模板來實現添加
    public void add() {
        String sql = "insert into user values(?,?)";
        jdbcTemplate.update(sql, "李阿昀", "lee");
    }
}

再在該包下編寫一個UserService類,並在UserService類裏面調用UserDao類的add方法。

public class UserService {

    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add() {
        userDao.add();
    }
}

那麽Spring核心配置文件就應該像下面這樣配置:

<!-- 配置service和dao以及它們的註入 -->
<bean id="userService" class="cn.itcast.c3p0.UserService">
    <property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="cn.itcast.c3p0.UserDao">
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>

<!-- 配置JdbcTemplate模板類的對象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!-- 註入dataSource,因為在其源代碼中dataSource屬性有其對應的set方法,故可直接註入 -->
    <property name="dataSource" ref="dataSource"></property>
</bean>

從上面的配置可看出:UserDao中註入了JdbcTemplate對象,JdbcTemplate對象裏面又註入了dataSource。
最後再在該包下編寫一個TestDemo單元測試類。

public class TestDemo {

    @Test
    public void testBook() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
}

Spring的JDBC模板