Spring的数据库编程

一、传统的JDBC编程

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

pom.xml


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.49version>
dependency>
创建 DBUtil 类

第一步我们可以把重复的模板代码提出来创建一个【DBUtil】数据库工具类:

public final class DBUtil {
    private DBUtil(){}
    private static final String DB_IP = "127.0.0.1";
    private static final int DB_PORT = 3305;
    private static final String DATABASE = "spring";
    private static final String ENCODING = "UTF-8";
    private static final String LOGIN_NAME = "root";
    private static final String PASSWORD = "123456";

    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        String url = String.format("jdbc:mysql://%s:%d/%s?useSSL=false&&characterEncoding=%s", DB_IP, DB_PORT, DATABASE, ENCODING);
        return DriverManager.getConnection(url, LOGIN_NAME, PASSWORD);
    }

}
使用 try-catch 语句自动关闭资源
public class StudentServiceImpl {

    public Student getOne(int id) {

        String sql = "SELECT ID,NAME FROM SP_USER WHERE id = ?";
        Student student = null;
        // 将 JDBC 声明变量包含在 try(..) 里将自动关闭资源
        try (Connection con = DBUtil.getConnection(); PreparedStatement ps = con.prepareStatement(sql)) {

            // 设置参数
            ps.setInt(1, id);
            // 执行SQL
            ResultSet rs = ps.executeQuery();
            // 组装结果集返回 POJO
            if (rs.next()) {
                student = new Student();
                student.setId(rs.getInt(1));
                student.setName(rs.getString(2));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return student;
    }
}

其中Student实体类如下:

public class Student {
    private Integer id;
    private String name;
    private Integer age;

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

二、Spring中的JDBC

要想使用 Spring 中的 JDBC 模块,就必须引入相应的 jar 文件:


<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-jdbcartifactId>
    <version>${spring.version}version>
dependency>
<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-txartifactId>
    <version>${spring.version}version>
dependency>

配置数据源有两种:

  • 使用Spring内置的简单数据库配置
  • 使用第三方数据库连接池
Spring内置数据库配置

Spring的内置类是org.springframework.jdbc.datasource.SimpleDriverDataSource

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;

public class StudentSv {

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) throws SQLException {
        this.dataSource = dataSource;
    }

    public Student getOne(int id) {

        String sql = "SELECT ID,NAME FROM SP_USER WHERE id = ?";
        Student student = null;
        // 将 JDBC 声明变量包含在 try(..) 里将自动关闭资源
        try (Connection con = this.dataSource.getConnection(); PreparedStatement ps = con.prepareStatement(sql)) {

            // 设置参数
            ps.setInt(1, id);
            // 执行SQL
            ResultSet rs = ps.executeQuery();
            // 组装结果集返回 POJO
            if (rs.next()) {
                student = new Student();
                student.setId(rs.getInt(1));
                student.setName(rs.getString(2));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return student;
    }
}

xml配置内容如下:

<bean id="dateSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3305/spring?useSSL=false&characterEncoding=UTF-8"/>
bean>

<bean id="studentService" class="com.codedot.db.StudentSv">
    <property name="dataSource" ref="dateSource">property>
bean>

测试

public class DBTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        StudentSv studentSv = context.getBean(StudentSv.class);
        Student student = studentSv.getOne(1);
        System.out.println(student.getName());
    }
}
使用第三方数据源

上面配置的这个简单的数据源一般用于测试,因为它不是一个数据库连接池,只是一个很简单的数据库连接的应用。在更多的时候,我们需要使用第三方的数据库连接。

常用的有dbcp2、C3p0、Druid。

为什么要使用数据库连接池 、好处是什么?

① 资源重用 (连接复用):避免了频繁创建、释放连接引起的大量性能开销。增进系统的平稳性。 

② 更快的系统响应速度:避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。 

③ 统一的连接管理,避免数据库连接泄露

dbcp2数据源

全限定名:org.apache.commons.dbcp2.BasicDataSource
需要添加:commons-dbcp2-xxx.jar、commons-pool2-xxx.jar
注意; dbcp2需要jdk1.7,否则会报错:Unsupported major.minor version 51.0

pom.xml


<dependency>
    <groupId>org.apache.commonsgroupId>
    <artifactId>commons-dbcp2artifactId>
    <version>2.7.0version>
dependency>
<dependency>
    <groupId>org.apache.commonsgroupId>
    <artifactId>commons-pool2artifactId>
    <version>2.7.0version>
dependency>

dbcp2.properties

# BasicDataSource + mysql
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3305/spring?useSSL=false&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.maxTotal=100
jdbc.initialSize=10
jdbc.maxWaitMillis=60000
jdbc.minIdle=10
jdbc.maxIdle=15
jdbc.logAbandoned=true
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=10
jdbc.timeBetweenEvictionRunsMillis=10000
jdbc.numTestsPerEvictionRun=10
jdbc.minEvictableIdleTimeMillis=10000
jdbc.validationQuery=select 1
jdbc.testWhileIdle=true
jdbc.testOnBorrow=true
jdbc.defaultAutoCommit=true
jdbc.defaultReadOnly=false

xml配置


    
   
    
    <context:property-placeholder location="classpath:dbcp2.properties" />
    
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        
        <property name="maxTotal" value="${jdbc.maxTotal}" />
        
        <property name="minIdle" value="${jdbc.minIdle}" />
        
        <property name="maxIdle" value="${jdbc.maxIdle}" />
        
        <property name="initialSize" value="${jdbc.initialSize}" />
        
        <property name="logAbandoned" value="${jdbc.logAbandoned}" />
        
        <property name="removeAbandonedOnBorrow" value="${jdbc.removeAbandoned}" />
        
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
        
        <property name="maxWaitMillis" value="${jdbc.maxWaitMillis}" />
        
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
        
        <property name="numTestsPerEvictionRun" value="${jdbc.numTestsPerEvictionRun}" />
        
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
        <property name="validationQuery" value="${jdbc.validationQuery}" />
        
        
        
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />

        
        
        
        <property name="defaultReadOnly" value="${jdbc.defaultReadOnly}" />
        

    bean>

    <bean id="studentService" class="com.codedot.db.StudentSv">
        <property name="dataSource" ref="dataSource">property>
    bean>
C3p0数据源

全限定名:com.mchange.v2.c3p0.ComboPooledDataSource
需要添加:c3p0-xxx.jar、mchange-commons-java-xxx.jar

pom.xml


<dependency>
    <groupId>com.mchangegroupId>
    <artifactId>c3p0artifactId>
    <version>0.9.5.5version>
dependency>
<dependency>
    <groupId>com.mchangegroupId>
    <artifactId>mchange-commons-javaartifactId>
    <version>0.2.19version>
dependency>

c3p0.properties

# ComboPooledDataSource + mysql
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3305/spring?useSSL=false&characterEncoding=UTF-8
jdbc.user=root
jdbc.password=123456
jdbc.minPoolSize=1
jdbc.maxPoolSize=100
jdbc.initialPoolSize=5
jdbc.maxIdleTime=60
jdbc.acquireIncrement=10
jdbc.maxStatements=10
jdbc.idleConnectionTestPeriod=30
jdbc.acquireRetryAttempts=30
jdbc.breakAfterAcquireFailure=true
jdbc.testConnectionOnCheckout=false
jdbc.automaticTestTable=true
jdbc.checkoutTimeout=15000
jdbc.numHelperThreads=10
jdbc.testConnectionOnCheckin=true

xml配置

 <context:property-placeholder location="classpath:c3p0.properties" />
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          destroy-method="close">
        <property name="driverClass" value="${jdbc.driverClass}" />
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
        <property name="user" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
        
        <property name="minPoolSize" value="${jdbc.minPoolSize}" />
        
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
        
        <property name="initialPoolSize" value="${jdbc.initialPoolSize}" />
        
        <property name="maxIdleTime" value="${jdbc.maxIdleTime}" />
        
        <property name="acquireIncrement" value="${jdbc.acquireIncrement}" />
        
        <property name="maxStatements" value="${jdbc.maxStatements}" />
        

        
        <property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}" />
        
        <property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}" />
        
        <property name="breakAfterAcquireFailure" value="${jdbc.breakAfterAcquireFailure}" />
        
        <property name="testConnectionOnCheckout" value="${jdbc.testConnectionOnCheckout}" />

        
        <property name="automaticTestTable" value="${jdbc.automaticTestTable}" />
        
        <property name="checkoutTimeout" value="${jdbc.checkoutTimeout}" />
        
        <property name="numHelperThreads" value="${jdbc.numHelperThreads}" />
        
        <property name="testConnectionOnCheckin" value="${jdbc.testConnectionOnCheckin}" />
    bean>

    <bean id="studentService" class="com.codedot.db.StudentSv">
        <property name="dataSource" ref="dataSource">property>
    bean>
Druid数据源

Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,号称是目前最好的连接池。

全限定名:com.alibaba.druid.pool.DruidDataSource
需要添加:druid-xxx.jar、commons-logging-1.2.jar

pom.xml


<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>druidartifactId>
    <version>1.1.23version>
dependency>
<dependency>
    <groupId>commons-logginggroupId>
    <artifactId>commons-loggingartifactId>
    <version>1.2version>
dependency>

druid.properties

# DruidDataSource + mysql
jdbc.name=druid-1
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3305/spring?useSSL=false&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.initialSize=1
jdbc.maxActive=10
jdbc.minIdle=1
jdbc.maxWait=10000
jdbc.poolPreparedStatements=true
jdbc.maxOpenPreparedStatements=20
jdbc.validationQuery=select 1
jdbc.testOnBorrow=true
jdbc.testOnReturn=false
jdbc.testWhileIdle=true
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.filters=stat
jdbc.defaultAutoCommit=true

xml配置

 <context:property-placeholder location="classpath:druid.properties" />
    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="name" value="${jdbc.name}" />
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        
        <property name="initialSize" value="${jdbc.initialSize}" />
        
        <property name="maxActive" value="${jdbc.maxActive}" />
        
        <property name="minIdle" value="${jdbc.minIdle}" />
        
        <property name="maxWait" value="${jdbc.maxWait}" />
        
        <property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}" />
        
        <property name="maxOpenPreparedStatements" value="${jdbc.maxOpenPreparedStatements}" />
        
        <property name="validationQuery" value="${jdbc.validationQuery}" />
        
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
        
        <property name="testOnReturn" value="${jdbc.testOnReturn}" />
        
        <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
        
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
        
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
        
        <property name="filters" value="${jdbc.filters}" />
        
        <property name="defaultAutoCommit" value="${jdbc.defaultAutoCommit}" />
    bean>


    <bean id="studentService" class="com.codedot.db.StudentSv">
        <property name="dataSource" ref="dataSource">property>
    bean>

 

你可能感兴趣的:(Spring的数据库编程)