JavaWeb学习笔记之——JDBC 数据库连接池

JDBC 数据库连接池

1、数据库连接池

1.1、概念

其实就是一个容器(集合),存放数据库连接的容器

当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

好处:

  1. 节约资源
  2. 用户访问高效

1.2、实现

  1. 标准接口:DataSource javax.sql 包下的
    1. 方法:
      • 获取连接:getConnection()
      • 归还连接:Connection.close()。如果连接对象Connection 是从连接池中获取的,那么调用Connection.close() 方法,则不会再关闭连接了。而是归还连接。
  2. 一般我们不去实现它,有数据库厂商来实现
    1. C3P0:数据库连接池技术
    2. Druid:数据库连接池实现技术,由阿里巴巴提供的

1.3、C3P0:数据库连接池技术

步骤:

  1. 导入 jar 包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
    • 不要忘记导入数据库驱动 jar 包
  2. 定义配置文件:
    • 名称: c3p0.properties 或者 c3p0-config.xml
    • 路径:直接将文件放在 src 目录下即可
  3. 创建核心对象:数据库连接池对象 ComboPooledDataSource
  4. 获取连接: getConnection
package cn.itcast.datasource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

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

/**
 * C3p0 演示
 */
public class c3p0Demo {
    public static void main(String[] args) throws SQLException {
        //1.创建数据库连接池对象
        DataSource ds = new ComboPooledDataSource();

        //2.获取连接对象
        Connection conn = ds.getConnection();

        //3.打印
        System.out.println(conn);
    }
}
929, 2021 3:15:02 下午 com.mchange.v2.log.MLog 
信息: MLog clients using java 1.4+ standard logging.
929, 2021 3:15:03 下午 com.mchange.v2.c3p0.C3P0Registry 
信息: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
929, 2021 3:15:03 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 3000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hgf3ltakdfiry4qwe93a|534df152, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hgf3ltakdfiry4qwe93a|534df152, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, jdbcUrl -> jdbc:mysql://192.168.31.140:3306/db3, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
com.mchange.v2.c3p0.impl.NewProxyConnection@1e683a3e [wrapping: com.mysql.jdbc.JDBC4Connection@2053d869]
1.3.1、C3P0 的配置文件
<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://192.168.31.140:3306/db3</property>
    <property name="user">root</property>
    <property name="password">Opfordream@0518</property>
    
    <!-- 连接池参数 -->
    <!-- 初始化连接数量 -->
    <property name="initialPoolSize">5</property>
    <!-- 最大连接数量 -->
    <property name="maxPoolSize">10</property>
    <!-- 超时时间 -->
    <property name="checkoutTimeout">3000</property>
  </default-config>

  <named-config name="otherc3p0"> 
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://192.168.31.140:3306/db3</property>
    <property name="user">root</property>
    <property name="password">Opfordream@0518</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>

验证配置文件的参数:

package cn.itcast.datasource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

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

/**
 * c3p0 配置文件参数验证
 */
public class c3p0Demo2 {
    public static void main(String[] args) throws SQLException {
        //1.获取 DataSource. 使用默认配置
        DataSource ds = new ComboPooledDataSource();

        //2.获取连接
        for (int i = 1; i <= 11; i++) {
            Connection conn = ds.getConnection();
            System.out.println(i + ":" + conn);

            if (i == 5){
                conn.close(); //归还连接到连接池
            }
        }


        System.out.println("-----------------------------------------------");
        testNamedConfig();
    }

    public static void testNamedConfig() throws SQLException {
        //1.1 获取 DataSource. 使用指定名称配置
        DataSource ds = new ComboPooledDataSource("otherc3p0");

        //2.获取连接
        for (int i = 1; i <= 10; i++) {
            Connection conn = ds.getConnection();
            System.out.println(i + ":" + conn);

        }
    }
}
929, 2021 3:18:03 下午 com.mchange.v2.log.MLog 
信息: MLog clients using java 1.4+ standard logging.
929, 2021 3:18:04 下午 com.mchange.v2.c3p0.C3P0Registry 
信息: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
929, 2021 3:18:04 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 3000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hgf3ltakdfmnmf12hmy87|534df152, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hgf3ltakdfmnmf12hmy87|534df152, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, jdbcUrl -> jdbc:mysql://192.168.31.140:3306/db3, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
1:com.mchange.v2.c3p0.impl.NewProxyConnection@63a12c68 [wrapping: com.mysql.jdbc.JDBC4Connection@28f3b248]
2:com.mchange.v2.c3p0.impl.NewProxyConnection@32b260fa [wrapping: com.mysql.jdbc.JDBC4Connection@581ac8a8]
3:com.mchange.v2.c3p0.impl.NewProxyConnection@57d7f8ca [wrapping: com.mysql.jdbc.JDBC4Connection@76c3e77a]
4:com.mchange.v2.c3p0.impl.NewProxyConnection@67c33749 [wrapping: com.mysql.jdbc.JDBC4Connection@fba92d3]
5:com.mchange.v2.c3p0.impl.NewProxyConnection@fa49800 [wrapping: com.mysql.jdbc.JDBC4Connection@71238fc2]
6:com.mchange.v2.c3p0.impl.NewProxyConnection@5fbdfdcf [wrapping: com.mysql.jdbc.JDBC4Connection@4efc180e]
7:com.mchange.v2.c3p0.impl.NewProxyConnection@25084a1e [wrapping: com.mysql.jdbc.JDBC4Connection@71238fc2]
8:com.mchange.v2.c3p0.impl.NewProxyConnection@3bf9ce3e [wrapping: com.mysql.jdbc.JDBC4Connection@16610890]
9:com.mchange.v2.c3p0.impl.NewProxyConnection@383bfa16 [wrapping: com.mysql.jdbc.JDBC4Connection@4d465b11]
10:com.mchange.v2.c3p0.impl.NewProxyConnection@5562c41e [wrapping: com.mysql.jdbc.JDBC4Connection@32ee6fee]
11:com.mchange.v2.c3p0.impl.NewProxyConnection@7133da86 [wrapping: com.mysql.jdbc.JDBC4Connection@3232a28a]
-----------------------------------------------
929, 2021 3:18:04 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 1000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> otherc3p0, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hgf3ltakdfmnmf12hmy87|73e22a3d, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, jdbcUrl -> jdbc:mysql://192.168.31.140:3306/db3, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 8, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
1:com.mchange.v2.c3p0.impl.NewProxyConnection@35aea049 [wrapping: com.mysql.jdbc.JDBC4Connection@7205765b]
2:com.mchange.v2.c3p0.impl.NewProxyConnection@22ef9844 [wrapping: com.mysql.jdbc.JDBC4Connection@6283d8b8]
3:com.mchange.v2.c3p0.impl.NewProxyConnection@3f6b0be5 [wrapping: com.mysql.jdbc.JDBC4Connection@611889f4]
4:com.mchange.v2.c3p0.impl.NewProxyConnection@48f278eb [wrapping: com.mysql.jdbc.JDBC4Connection@2f217633]
5:com.mchange.v2.c3p0.impl.NewProxyConnection@1a18644 [wrapping: com.mysql.jdbc.JDBC4Connection@5acf93bb]
6:com.mchange.v2.c3p0.impl.NewProxyConnection@6cd28fa7 [wrapping: com.mysql.jdbc.JDBC4Connection@614ca7df]
7:com.mchange.v2.c3p0.impl.NewProxyConnection@66d3eec0 [wrapping: com.mysql.jdbc.JDBC4Connection@1e04fa0a]
8:com.mchange.v2.c3p0.impl.NewProxyConnection@18d87d80 [wrapping: com.mysql.jdbc.JDBC4Connection@618425b5]
Exception in thread "main" java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
	at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
	at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
	at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:690)
	at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
	at cn.itcast.datasource.c3p0.c3p0Demo2.testNamedConfig(c3p0Demo2.java:38)
	at cn.itcast.datasource.c3p0.c3p0Demo2.main(c3p0Demo2.java:29)
Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@20ccf40b -- timeout at awaitAvailable()
	at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1467)
	at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:644)
	at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:554)
	at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:758)
	at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:685)
	... 3 more

1.4、Druid:数据库连接池实现技术

步骤:

  1. 导入 jar 包 druid-1.0.9.jar
  2. 定义配置文件:
    • 是 properties 形式的
    • 可以叫任意名称,可以放在任意目录下
  3. 加载配置文件。Properties
  4. 获取数据库连接池对象:通过工厂类来获取 DruidDataSourceFactory
  5. 获取连接:getConnection
package cn.itcast.datasource.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

/**
 * Druid 演示
 */
public class DruidDemo {
    public static void main(String[] args) throws Exception {
        //1.导入 jar 包
        //2.定义配置文件

        //3.加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        //4.获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);

        //5.获取连接
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }
}
929, 2021 3:21:06 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
com.mysql.jdbc.JDBC4Connection@5c90e579
1.4.1、定义工具类
  1. 定义一个类 JDBCUtils
  2. 提供静态代码块加载配置文件,初始化连接池对象
  3. 提供方法
    1. 获取连接方法:通过数据库连接池获取连接
    2. 释放资源
    3. 获取连接池的方法
package cn.itcast.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * Druid 连接池的工具类
 */
public class JDBCUtils {

    //1. 定义成员变量 DataSource
    private static DataSource ds;

    static {
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));

            //2.获取 DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 释放资源
     */
    public static void  close(Statement stmt, Connection conn){
        if (stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    public static void  close(ResultSet rs,Statement stmt, Connection conn){
        if (rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取连接池的方法
     */
    public static DataSource getDataSource(){
        return ds;
    }

}
package cn.itcast.datasource.druid;

import cn.itcast.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * 使用新的工具类
 */
public class DruidDemo2 {
    public static void main(String[] args) {
        /**
         * 完成一个添加的操作,给 account 添加一条记录
         */

        Connection conn = null;
        PreparedStatement pstmt = null;

        try {
            //1.获取连接
            conn = JDBCUtils.getConnection();

            //2.定义 sql
            String sql = "insert into account values(null, ?, ?)";

            //3.获取 pstmt 对象
            pstmt = conn.prepareStatement(sql);
            //给 ? 赋值
            pstmt.setString(1, "wangwu");
            pstmt.setDouble(2, 3000);

            //4.执行 sql
            int count = pstmt.executeUpdate();

            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(pstmt, conn);
        }
    }
}
929, 2021 3:25:48 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
1

2、Spring JDBC

Spring 框架对 JDBC 的简单封装。提供了一个 JDBCTemplate 对象简化 JDBC 的开发。

步骤:

  1. 导入 jar 包

  2. 创建 JdbcTemplate 对象。依赖于数据源 DataSource

    • JdbcTemplate template = new JdbcTemplate(ds);
  3. 调用 JdbcTemplate 的方法来完成 CRUD 的操作

    • update():执行 DML 语句。增、删、改语句

    • queryForMap():查询结果将结果集封装为 map 集合,将列名作为 key,将值作为 value 将这条记录封装为一个map 集合

      注意:这个方法查询的结果集长度只能是 1

    • queryForList():查询结果将结果集封装为 list 集合

      注意:将每一条记录封装为一个 Map 集合,再将 Map 集合装载到 List 集合中

    • query():查询结果,将结果封装为 JavaBean 对象

      • query 的参数:RowMapper
        • 一般我们使用 BeanPropertyRowMapper 实现类。可以完成数据到 JavaBean 的自动封装
        • new BeanPropertyRowMapper<类型>(类型.class)
    • queryForObject():查询结果,将结果封装为对象

      一般用于聚合函数的查询

练习

需求:

  1. 修改 1 号数据的 salary 为 10000
  2. 添加一条记录
  3. 删除刚才添加的记录
  4. 查询 id 为 1 的记录,将其封装为 Map 集合
  5. 查询所有记录,将其封装为 List
  6. 查询所有记录,将其封装为 Emp 对象的 List 集合
  7. 查询总记录数
package JdbcTemplate;

import JdbcTemplate.domain.Emp;
import cn.itcast.utils.JDBCUtils;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

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

public class JdbcTemplateDemo2 {

    //1.获取 JDBCTemplate 对象
     private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

    //Junit 单元测试,可以让方法独立执行

    /**
     * 1. 修改1号数据的 salary 为 10000
     */
    @Test
    public void test1() {

        //2.定义 sql
        String sql = "update emp set salary = 10000 where id = 1001";
        //3.执行 sql
        int count = template.update(sql);
        System.out.println(count);
    }


    /**
     *2. 添加一条记录
     */
    @Test
    public void test2(){
        //2.定义 sql
        String sql = "insert into emp(id, ename, dept_id) values(?, ?, ?) ";
        //3.执行 sql
        int count = template.update(sql, 1015, "郭靖", 10);
        System.out.println(count);
    }

    /**
     *3. 删除刚才添加的记录
     */
    @Test
    public void test3(){
        //2.定义 sql
        String sql = "delete from emp where id = ?";
        //3.执行 sql
        int count = template.update(sql, 1015);
        System.out.println(count);
    }

    /**
     *4. 查询id为1的记录,将其封装为Map集合
     * 注意,这个方法查询的结果集长度只能是 1
     */
    @Test
    public void test4(){
        //2.定义 sql
        String sql = "select * from emp where id = ? /*or id = ?*/";
        //3.执行 sql
        Map<String, Object> map = template.queryForMap(sql, 1001/*, 1002*/);
        System.out.println(map);
        //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
    }

    /**
     * 5. 查询所有记录,将其封装为List
     */
    @Test
    public void test5(){
        //2.定义 sql
        String sql = "select * from emp";
        //3.执行 sql
        List<Map<String, Object>> list = template.queryForList(sql);

        for (Map<String, Object> stringObjectMap : list) {
            System.out.println(stringObjectMap);
        }
    }

    /**
     * 6. 查询所有记录,将其封装为Emp对象的List集合
     */
    @Test
    public void test6(){
        //2.定义 sql
        String sql = "select * from emp";
        //3.执行 sql
        List<Emp> list = template.query(sql, new RowMapper<Emp>() {
            @Override
            public Emp mapRow(ResultSet rs, int i) throws SQLException {
                Emp emp = new Emp();
                int id = rs.getInt("id");
                String ename = rs.getString("ename");
                int job_id = rs.getInt("job_id");
                int mgr = rs.getInt("mgr");
                Date join_date = rs.getDate("joindate");
                double salary = rs.getDouble("salary");
                double bonus = rs.getDouble("bonus");
                int dept_id = rs.getInt("dept_id");

                emp.setId(id);
                emp.setEname(ename);
                emp.setJob_id(job_id);
                emp.setMgr(mgr);
                emp.setJoindate(join_date);
                emp.setSalary(salary);
                emp.setBonus(bonus);
                emp.setDept_id(dept_id);

                return emp;
            }
        });

        for (Emp emp: list) {
            System.out.println(emp);
        }
    }

    /**
     * 6. 查询所有记录,将其封装为Emp对象的List集合
     */
    @Test
    public void test6_1(){
        //2.定义 sql
        String sql = "select * from emp";
        //3.执行 sql
        List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));

        for (Emp emp: list) {
            System.out.println(emp);
        }
    }


    /**
     * 7. 查询总记录数
     */
    @Test
    public void test7(){
        //2.定义 sql
        String sql = "select count(id) from emp";
        //3.执行 sql
        Long total = template.queryForObject(sql, Long.class);

        System.out.println(total);
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JDBC(Java Database Connectivity)是Java语言操作数据库的基础API,它提供了一种标准的方法来连接和操作各种关系型数据库JDBC的基本使用分为以下几个步骤: 1. 加载驱动程序:在使用JDBC操作数据库之前,需要先加载相应的驱动程序。不同的数据库需要加载不同的驱动程序,一般情况下驱动程序的jar包都会提供。 ```java Class.forName("com.mysql.jdbc.Driver"); ``` 2. 建立连接:使用DriverManager类的getConnection()方法连接数据库。 ```java String url = "jdbc:mysql://localhost:3306/test?useSSL=false"; String username = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, username, password); ``` 其中url为连接数据库的URL,username和password为连接数据库的用户名和密码。 3. 创建Statement对象:通过Connection对象的createStatement()方法创建一个Statement对象,用于执行SQL语句。 ```java Statement stmt = conn.createStatement(); ``` 4. 执行SQL语句:可以通过Statement对象的execute()或executeQuery()方法执行SQL语句,如果是更新操作则使用executeUpdate()方法。 ```java ResultSet rs = stmt.executeQuery("SELECT * FROM users"); ``` 5. 处理结果集:如果执行的SQL语句返回了结果集,则可以通过ResultSet对象进行处理。 ```java while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println("id: " + id + ", name: " + name); } ``` 6. 关闭连接:使用完数据库后需要关闭连接,释放资源。 ```java rs.close(); stmt.close(); conn.close(); ``` 以上就是JDBC的基本使用过程,通过JDBC可以实现Java程序与数据库的交互,完成各种数据库操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值