Spring - 整合jdbc

Posted Lam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring - 整合jdbc相关的知识,希望对你有一定的参考价值。

Spring对数据库的操作在jdbc上面做了更深层次的封装,而JdbcTemplate便是Spring提供的一个操作数据库的便捷工具。我们可以借助JdbcTemplate来执行所有数据库操作,例如插入,更新,删除和从数据库中检索数据,并且有效避免直接使用jdbc带来的繁琐编码。

JdbcTemplate主要提供以下五种类型的方法

execute:可以用于执行任何SQL语句,一般用于执行DDL语句
● update、batchUpdate:用于执行新增、修改、删除等语句
● queryqueryForXXX:用于执行查询相关的语句
● call:用于执行数据库存储过程和函数相关的语句

JdbcTemplate的优点

(1)配置基于模板设置
(2)完成了资源的创建和释放的工作
(3)完成了对JDBC的核心流程的工作,包括SQL语句的创建和执行,简化了对JDBC的操作
(4)仅需要传递DataSource就可以把它实例化
(5)JdbcTemplate只需要创建一次,减少了代码复用的烦恼
(6)JdbcTemplate是线程安全类

JdbcDaoSupport

spring中提供了一个可以操作数据库的对象,对象封装了jdbc技术  ————JDBCTemplate JDBC模板对象。
而JdbcDaoSupport则对JdbcTemplate进行了封装,所以要操作JdbcTemplate,或只需要继承JdbcDaoSupport即可。

当然,在大部分情况下,我们都会直接使用更加强大的持久化框架来访问数据库,比如MyBatis、Hibernate或者Spring Data JPA,我们这里讲解JdbcTemplate的整合,只是告诉大家有这么一种操作数据库的方式。

传统的JDBC回顾

JDBC 我们一定不陌生,刚开始学习的时候,我们写过很多很多重复的模板代码:

该实现有两个明显的缺点就是(1)需要自己管理连接 (2)Jdbc操作重复代码封装与编写

 - C3P0工具类

package com.sikiedu.jdbc;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0_DataSource {

    // 建立连接的驱动驱动名称
    private static final String DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";
    // 连接数据库的url
    private static final String URL = "jdbc:mysql://localhost:3306/games_db?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8";
    // 连接的数据库账号
    private static final String USERNAME = "root";
    // 数据库连接池-连接的数据库密码
    private static final String PASSWORD = "123456";
    // 数据库连接池-最大活动链接
    private static final int MAX_TOTAL = 20;
    // 数据库连接池-初始化时链接的数量
    private static final int INITIAL_SIZE = 5;

    private static ComboPooledDataSource c3p0 = new ComboPooledDataSource();;

    // 初始化链接参数
    static {
        try {
            c3p0.setDriverClass(DRIVER_CLASS_NAME);
            c3p0.setJdbcUrl(URL);
            c3p0.setUser(USERNAME);
            c3p0.setPassword(PASSWORD);
            c3p0.setInitialPoolSize(INITIAL_SIZE);
            c3p0.setMaxPoolSize(MAX_TOTAL);

        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }

    }

    // 提供获得链接
    public static Connection getConnection() throws SQLException {

        return c3p0.getConnection();

    }

    public static void close(Connection conn, PreparedStatement ps1, PreparedStatement ps2) {
        closeStatement(ps2);
        closeStatement(ps1);
        closeConnection(conn);
    }

    public static void close(Connection conn, Statement statement) {
        closeStatement(statement);
        closeConnection(conn);
    }

    public static void close(Connection conn, Statement statement, ResultSet resultSet) {
        closeResultSet(resultSet);
        closeStatement(statement);
        closeConnection(conn);
    }

    // 关闭Connection
    public static void closeConnection(Connection conn) {
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 关闭Statement
    public static void closeStatement(Statement statement) {
        try {
            if (statement != null)
                statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 关闭ResultSet
    public static void closeResultSet(ResultSet resultSet) {
        try {
            if (resultSet != null)
                resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}
C3P0_DataSource.java

 - 传统jdbc操作数据库 

public User selectUserById(Integer id) {

    String sql = "SELECT id,username,userpassword,balance,grgisterdate FROM games_db.user WHERE id = ?";
    User user = null;
    // 声明 JDBC 变量
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet res = null;
    try {
        // 使用C3P0工具类获取连接
        conn = C3P0_DataSource.getConnection();
        // 预编译SQL
        ps = conn.prepareStatement(sql);
        // 设置参数
        ps.setInt(1, id);
        // 执行SQL
        res = ps.executeQuery();
        // 组装结果集返回 POJO
        if (res.next()) {
            user = new User();
            user.setId(res.getInt(1));
            user.setUsername(res.getString(2));
            user.setUserpassword(res.getString(3));
            user.setBalance(res.getLong(4));
            user.setGrgisterdate(res.getDate(5));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 使用C3P0工具类关闭数据源
        C3P0_DataSource.close(conn, ps, res);
    }
    return user;
}

Spring+Jdbc实现

● 项目准备:

 - 导包 spring-jdbc.jar、spring-tx.jar

 - 数据库配置文件

1 jdbc.driverClass=com.mysql.jdbc.Driver
2 jdbc.jdbcUrl=jdbc:mysql://localhost:3306/games_db?useUnicode=true&characterEncoding=UTF-8&useSSL=true
3 jdbc.user=root
4 jdbc.password=123456
db.properties

 - 创建一个POJO类

 1 package com.sikiedu.bean;
 2 
 3 import java.util.Date;
 4 
 5 public class User {
 6 
 7     private Integer id;
 8     private String username;
 9     private String userpassword;
10     private Long balance;
11     private Date grgisterdate;
12 
13     public Integer getId() {
14         return id;
15     }
16 
17     public void setId(Integer id) {
18         this.id = id;
19     }
20 
21     public String getUsername() {
22         return username;
23     }
24 
25     public void setUsername(String username) {
26         this.username = username;
27     }
28 
29     public String getUserpassword() {
30         return userpassword;
31     }
32 
33     public void setUserpassword(String userpassword) {
34         this.userpassword = userpassword;
35     }
36 
37     public Long getBalance() {
38         return balance;
39     }
40 
41     public void setBalance(Long balance) {
42         this.balance = balance;
43     }
44 
45     public Date getGrgisterdate() {
46         return grgisterdate;
47     }
48 
49     public void setGrgisterdate(Date grgisterdate) {
50         this.grgisterdate = grgisterdate;
51     }
52 
53     @Override
54     public String toString() {
55         return "User [id=" + id + ", username=" + username + ", userpassword=" + userpassword + ", balance=" + balance
56                 + ", grgisterdate=" + grgisterdate + "]";
57     }
58 
59 }
User.java

 - UserDao接口类

 1 package com.sikiedu.dao;
 2 
 3 import java.util.List;
 4 
 5 import com.sikiedu.bean.User;
 6 
 7 public interface UserDao {
 8 
 9     //
10     void save(User u);
11 
12     //
13     void deleteUserById(Integer id);
14 
15     //
16     void updateUser(User u);
17 
18     //19     // 根据id查找用户
20     User selectUserById(Integer id);
21 
22     // 查找所有用户
23     List<User> selecuAllUser();
24 
25     // 查找用户数量
26     Integer selectUserCount();
27 }
UserDao.java

下面我们开始使用spring-jdbc操作数据库

使用JdbcTemplate操作数据库

 - 实现UserDao接口,使用JdbcTemplate对象操作

package com.sikiedu.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import com.sikiedu.bean.User;

public class UserDaoImpl implements UserDao {

    private JdbcTemplate jt;

    public void setJt(JdbcTemplate jt) {
        this.jt = jt;
    }

    // 根据id查询用户
    @Override
    public User selectUserById(Integer id) {

        String sql = "SELECT * FROM user WHERE id = ?";
        User user = jt.queryForObject(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet res, int index) throws SQLException {

                User u = new User();
                u.setId(res.getInt("id"));
                u.setUsername(res.getString("username"));
                u.setUserpassword(res.getString("userpassword"));
                u.setBalance(res.getLong("balance"));
                u.setGrgisterdate(res.getDate("grgisterdate"));

                return u;
            }
        }, id);

        return user;
    }

    // 添加用户
    @Override
    public void save(User u) {

        String sql = "INSERT INTO user(username,userpassword,balance,grgisterdate) VALUES(?,?,?,?)";
        jt.update(sql, u.getUsername(), u.getUserpassword(), u.getBalance(), u.getGrgisterdate());
    }

    // 根据id删除用户
    @Override
    public void deleteUserById(Integer id) {

        String sql = "DELETE FROM user WHERE id = ?";
        jt.update(sql, id);
    }

    // 修改用户
    @Override
    public void updateUser(User u) {

        String sql = "UPDATE user SET username = ?,userpassword = ?,balance = ?,grgisterdate = ? WHERE id = ?";
        jt.update(sql, u.getUsername(), u.getUserpassword(), u.getBalance(), u.getGrgisterdate(), u.getId());
    }

    // 查询所有用户
    @Override
    public List<User> selecuAllUser() {

        String sql = "SELECT * FROM user";
        List<User> list = jt.query(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet res, int index) throws SQLException {
                User user = new User();

                user.setId(res.getInt("id"));
                user.setUsername(res.getString("username"));
                user.setUserpassword(res.getString("userpassword"));
                user.setBalance(res.getLong("balance"));
                user.setGrgisterdate(res.getDate("grgisterdate"));

                return user;
            }
        });

        return list;

    }

    // 查询用户数量
    @Override
    public Integer selectUserCount() {

        String sql = "SELECT COUNT(*) FROM user";
        return jt.queryForObject(sql, Integer.class);
    }

}

 - 配置xml - 依赖关系 dao > jdbcTemplate > dataSource

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <!-- 读取配置文件 -->
    <context:property-placeholder location="db.properties" />
    
    <!-- dataSource -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- jdbcTemplate -->
    <bean name="jt" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- dao -->
    <bean name="userDao" class="com.sikiedu.dao.UserDaoImpl">
        <property name="jt" ref="jt"></property>
    </bean>

</beans>

使用JdbcDaoSupport

 - 实现UserDao,继承JdbcDaoSupport,使用getJdbcTemplate操作

package com.sikiedu.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.sikiedu.bean.User;

public class UserDaoImpl extends JdbcDaoSupport implements UserDao {

    // 根据id查询用户
    @Override
    public User selectUserById(Integer id) {

        String sql = "SELECT * FROM user WHERE id = ?";
        User user = getJdbcTemplate().queryForObject(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet res, int index) throws SQLException {

                User u = new User();
                u.setId(res.getInt("id"));
                u.setUsername(res.getString("username"));
                u.setUserpassword(res.getString("userpassword"));
                u.setBalance(res.getLong("balance"));
                u.setGrgisterdate(res.getDate("grgisterdate"));

                return u;
            }
        }, id);

        return user;
    }

    // 添加用户
    @Override
    public void save(User u) {

        String sql = "INSERT INTO user(username,userpassword,balance,grgisterdate) VALUES(?,?,?,?)";
        getJdbcTemplate().update(sql, u.getUsername(), u.getUserpassword(), u.getBalance(), u.getGrgisterdate());
    }

    // 根据id删除用户
    @Override
    public void deleteUserById(Integer id) {

        String sql = "DELETE FROM user WHERE id = ?";
        getJdbcTemplate().update(sql, id);
    }

    // 修改用户
    @Override
    public void updateUser(User u) {

        String sql = "UPDATE user SET username = ?,userpassword = ?,balance = ?,grgisterdate = ? WHERE id = ?";
        getJdbcTemplate().update(sql, u.getUsername(), u.getUserpassword(), u.getBalance(), u.getGrgisterdate(),
                u.getId());
    }

    // 查询所有用户
    @Override
    public List<User> selecuAllUser() {

        String sql = "SELECT * FROM user";
        List<User> list = getJdbcTemplate().query(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet res, int index) throws SQLException {
                User user = new User();

                user.setId(res.getInt("id"));
                user.setUsername(res.getString("username"));
                user.setUserpassword(res.getString("userpassword"));
                user.setBalance(res.getLong("balance"));
                user.setGrgisterdate(res.getDate("grgisterdate"));

                return user;
            }
        });

        return list;

    }

    // 查询用户数量
    @Override
    public Integer selectUserCount() {

        String sql = "SELECT COUNT(*) FROM user";
        return getJdbcTemplate().queryForObject(sql, Integer.class);
    }
}

 - 配置xml - 依赖关系 userDao > dataSource

 继承JdbcDaoSupport不需要配置JdbcTemplate,只需要将数据源注入到继承JdbcDaoSupport的类即可

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <!-- 读取配置文件 -->
    <context:property-placeholder location="db.properties" />

    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <bean name="userDao" class="com.sikiedu.dao.UserDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

● 测试

package com.sikiedu.test;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.sikiedu.bean.User;
import com.sikiedu.dao.UserDao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class JdbcTest2 {

    @Resource(name = "userDao")
    private UserDao userDao;

    //
    @Test
    public void save() {

        User user = new User();
        user.setUsername("大大毛");
        user.setUserpassword("dm123");
        user.setBalance(2000L);
        user.setGrgisterdate(new Date(System.currentTimeMillis()));

        userDao.save(user);
    }

    //
    @Test
    public void deleteUserById() {

        userDao.deleteUserById(105);

    }

    //
    @Test
    public void updateUser() {

        User user = new User();
        user.setId(104);
        user.setUsername("diao毛");
        user.setUserpassword("dm312");
        user.setBalance(1000L);
        user.setGrgisterdate(new Date(System.currentTimeMillis()));
        userDao.updateUser(user);
    }

    //
    @Test
    public void selectUserById() {

        User user = userDao.selectUserById(2);
        System.out.println(user);

    }

    @Test
    public void selecuAllUser() {

        List<User> list = userDao.selecuAllUser();
        for (User u : list) {
            System.out.println(u);
        }
    }

    @Test
    public void selectUserCount() {

        Integer count = userDao.selectUserCount();
        System.out.println(count);
    }

}
Test

RowMapper的使用:在Jdbc的操作中,有很多情况下是要将ResultSet里的数据封装到一个持久化Bean里,再把持久化Bean封装到集合中。这样会造成大量的代码的重复,不利于代码重用。而RowMapper正好解决了这个问题。

以上是关于Spring - 整合jdbc的主要内容,如果未能解决你的问题,请参考以下文章

JAVAEE框架整合技术之spring03-SpringJdbcTemplate模板技术和事务处理

spring整合JDBC

Spring整合JDBC以及AOP管理事务

Spring整合JDBC以及AOP管理事务

Spring整合JDBC以及AOP管理事务

JAVAEE——spring03:spring整合JDBC和aop事务