JDBC 连接池 & DBUtils

JDBC 连接池 & DBUtils
使用 DBCP C3P0 连接池完成基本数据库的操作
使用DBUtils 完成 CRRD 的操作

目标:
学会 DBCP 配置文件的编写,以及数据源 DataSource 创建。
学会 C3P0 配置文件的编写,以及数据源 DataSource 创建。
能够使用 JDBC 简化工具包 DBUtis 完成单表的增删改查操作。
会描述 DBUtils 底层原理。

使用连接池重写工具类:
实际开发中,“获得连接”和“释放资源”是两个特别消耗资源的过程,为了解决这样的性能问题,通常我们采取池连接技术,来共享 Connection 。
连接池概念:
用池来管理 Connnection 这样可以重复使用 Connection 。有了池,所以我们就不需要自己创建 Connection,而是通过池来获取 Connection对象,当使用完后调用 Connection 的close() 方法也不会真的关闭Connection,而是把 Connection ”归还“给连接池,池就可以再利用 Connectionn 对象了。


规范:
Java 为数据库连接池提供了公共的接口: Javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口,这样应用程序可以方便的切换不同厂商的连接池。
常见的连接池:
DBCP、C3P0

自定义连接池:
1、创建连接池实现(数据源),并实现接口(Javax.sql.DataSource)。因为我们只使用该接口中的 getConnection() 方法。
2、提供一个集合用于存放连接,因为移除/添加的操作太多,所以我们选择 LinkedList
3、初始化三个连接。
4、之后程序需要连接,调用实现类的 getConnection() 方法,本方法可从连接池(容器 List)获得连接。为了保障当前连接只能提供给一个线程使用,所以我们需要将连接先从连接池中移除。
5、当用户使用完连接时候,释放资源,不执行 close(), 而是将连接存放至连接池中。

案例实现:

数据库连接的工具类:

package com.ma.jdbc.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle ;
/**
 * 工具类
 * 提供获取连接及释放资源的方法
 * @author lenovo
 *
 */
public class JDBCUtils {
       /**
       * 获取连接方法
       * @return
       */
       public static Connection getConnection(){
            Connection conn = null ;
             try {
                  Class. forName ( "com.mysql.jdbc.Driver" );
                  
                  conn = DriverManager. getConnection ( "jdbc:mysql://localhost:3306/user" , "root" , "123456" );
                  
            } catch (Exception e) {
                  
                  e.printStackTrace();
            }
            
            
             return conn;
      }
       /**
       * 释放资源方法
       * @param conn
       * @param pstmt
       * @param rs
       */
       public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs){
             if (rs != null ){
                   try {
                        rs.close();
                  } catch (SQLException e) {
                        
                        e.printStackTrace();
                  }
            }
             if (pstmt != null ){
                   try {
                        pstmt.close();
                  } catch (SQLException e) {
                        
                        e.printStackTrace();
                  }
            }
             if (conn != null ){
                   try {
                        conn.close();
                  } catch (SQLException e) {
                        
                        e.printStackTrace();
                  }
            }
      }
}


自己编写的连接池:

package com.ma.jdbc.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import com.ma.jdbc.utils.JDBCUtils;
public class MyDataSource implements DataSource{
       //1、创建一个容器存储 Connection 对象
       private static LinkedList<Connection> pool = new LinkedList<Connection>();
      
       //2、创建5个连接放到池子中去
       static {
             for ( int i = 0; i < 5; i++) {
                  Connection conn = JDBCUtils. getConnection ();
                   pool .add(conn);
            }
      }
       /**
       * 获取连接的方法
       */
       @Override
       public Connection getConnection() throws SQLException {
            Connection conn = null ;
             //3、使用前先判断
             if ( pool .size() == 0){
                   //4、池子里面没有我们再创建一些
                   for ( int i = 0; i < 5; i++) {
                        conn = JDBCUtils. getConnection ();
                         pool .add(conn);
                  }
                  
            }
             //5、从池子里面获取连接对象
            conn = pool .remove(0);
             return conn;
      }
       /**
       * 归还连接对象的方法
       */
       public void backConnection(Connection conn){
             pool .add(conn);
      }
       @Override
       public PrintWriter getLogWriter() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void setLogWriter(PrintWriter out) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public void setLoginTimeout( int seconds) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public int getLoginTimeout() throws SQLException {
             // TODO Auto-generated method stub
             return 0;
      }
       @Override
       public Logger getParentLogger() throws SQLFeatureNotSupportedException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public <T> T unwrap(Class<T> iface) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public boolean isWrapperFor(Class<?> iface) throws SQLException {
             // TODO Auto-generated method stub
             return false ;
      }
      
       @Override
       public Connection getConnection(String username, String password)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
}

使用数据库连接池完成数据的添加操作:

package com.ma.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.Test;
import com.ma.jdbc.DataSource.MyDataSource;
public class TestMyDataSource {
      
       @Test
       public void testAddUser (){
            Connection conn = null ;
            PreparedStatement pstmt = null ;
             //1、创建自定义连接池对象
            MyDataSource dataSourse = new MyDataSource();
             try {
                   //2、从池子中获取连接对象
                  conn = dataSourse.getConnection();
                   //3、编写 sql 语句
                  String sql = "insert into t_user values(null, ?, ?, ?)" ;
                   //4、执行 sql
                  pstmt = conn.prepareStatement(sql);
                   //5、设置参数
                  pstmt.setString(1, "Young" );
                  pstmt.setString(2, "555555" );
                  pstmt.setString(3, "Tong" );
                   //6、处理结果
                   int rows = pstmt.executeUpdate();
                   if (rows > 0){
                        System. out .println( "添加成功 !" );
                  } else {
                        System. out .println( "添加失败 !" );
                  }
            } catch (Exception e) {
                  
            } finally {
                  dataSourse.backConnection(conn);
            }
      }
}


此时调用 close() 方法会销毁连接,实现调用 close() 方法将连接对象返回到数据库连接池中的功能。
利用装饰者模式完成功能的增强
装饰者固定格式:接口 A, 已知实现类 C,需要装饰者创建代理类 B。
1、创建类 B 并实现接口 A
2、提供类 B 的构造方法参数类型为 A,用于接收 A 接口的其他实现类(C)
3、给类 B 添加类型为 A  的成员变量,用于存放 A 接口的其他实现类 
4、增强需要的方法
5、实现不需要的方法,方法体重调用成员变量存放的其他实现类对应的方法
package com.ma.jdbc.DataSource;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.LinkedList;
import java.util.List ;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
//1、实现同一个接口 Connection
public class MyConnection implements Connection{
       //3、定义变量
       private Connection conn ;
       private LinkedList<Connection> pool ;
       //2、实现一个构造方法(使用了多态)
       public MyConnection(Connection conn, LinkedList<Connection> pool){
             this . conn = conn;
             this . pool = pool;
      }
      
       @Override
       public void close() throws SQLException {
             pool .add( conn );
      }
      
       @Override
       public <T> T unwrap(Class<T> iface) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public boolean isWrapperFor(Class<?> iface) throws SQLException {
             // TODO Auto-generated method stub
             return false ;
      }
       @Override
       public Statement createStatement() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public PreparedStatement prepareStatement(String sql) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public CallableStatement prepareCall(String sql) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public String nativeSQL(String sql) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void setAutoCommit( boolean autoCommit) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public boolean getAutoCommit() throws SQLException {
             // TODO Auto-generated method stub
             return false ;
      }
       @Override
       public void commit() throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public void rollback() throws SQLException {
             // TODO Auto-generated method stub
            
      }
      
       @Override
       public boolean isClosed() throws SQLException {
             // TODO Auto-generated method stub
             return false ;
      }
       @Override
       public DatabaseMetaData getMetaData() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void setReadOnly( boolean readOnly) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public boolean isReadOnly() throws SQLException {
             // TODO Auto-generated method stub
             return false ;
      }
       @Override
       public void setCatalog(String catalog) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public String getCatalog() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void setTransactionIsolation( int level) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public int getTransactionIsolation() throws SQLException {
             // TODO Auto-generated method stub
             return 0;
      }
       @Override
       public SQLWarning getWarnings() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void clearWarnings() throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public Statement createStatement( int resultSetType, int resultSetConcurrency)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public PreparedStatement prepareStatement(String sql, int resultSetType,
                   int resultSetConcurrency) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public CallableStatement prepareCall(String sql, int resultSetType,
                   int resultSetConcurrency) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Map<String, Class<?>> getTypeMap() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public void setHoldability( int holdability) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public int getHoldability() throws SQLException {
             // TODO Auto-generated method stub
             return 0;
      }
       @Override
       public Savepoint setSavepoint() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Savepoint setSavepoint(String name) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void rollback(Savepoint savepoint) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public void releaseSavepoint(Savepoint savepoint) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public Statement createStatement( int resultSetType,
                   int resultSetConcurrency, int resultSetHoldability)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public PreparedStatement prepareStatement(String sql, int resultSetType,
                   int resultSetConcurrency, int resultSetHoldability)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public CallableStatement prepareCall(String sql, int resultSetType,
                   int resultSetConcurrency, int resultSetHoldability)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public PreparedStatement prepareStatement(String sql, int [] columnIndexes)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public PreparedStatement prepareStatement(String sql, String[] columnNames)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Clob createClob() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Blob createBlob() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public NClob createNClob() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public SQLXML createSQLXML() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public boolean isValid( int timeout) throws SQLException {
             // TODO Auto-generated method stub
             return false ;
      }
       @Override
       public void setClientInfo(String name, String value)
                   throws SQLClientInfoException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public void setClientInfo(Properties properties)
                   throws SQLClientInfoException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public String getClientInfo(String name) throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Properties getClientInfo() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Array createArrayOf(String typeName, Object[] elements)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public Struct createStruct(String typeName, Object[] attributes)
                   throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void setSchema(String schema) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public String getSchema() throws SQLException {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void abort(Executor executor) throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public void setNetworkTimeout(Executor executor, int milliseconds)
                   throws SQLException {
             // TODO Auto-generated method stub
            
      }
       @Override
       public int getNetworkTimeout() throws SQLException {
             // TODO Auto-generated method stub
             return 0;
      }
      
}

C3P0连接池:
C3P0 开源免费的连接池,目前使用它的开源项目有 Spring、Hibernate 等。使用第三方工具需要导入 jar 包 ,C3P0 使用时还需要添加配置文件 c3p0-config.xml



<? xml version = "1.0" encoding = "UTF-8" ?>
< c3p0-config >
  < default-config >
    < property name = "driverClass" > com.mysql.jdbc.Driver </ property >
       < property name = "jdbcUrl" > jdbc:mysql:///user </ property >
       < property name = "user" > root </ property >
       < property name = "password" > 123456 </ property >
       < property name = "initialPoolSize" > 5 </ property >
       < property name = "maxPoolSize" > 20 </ property >
  </ default-config >
 
  < named-config name = "oracle" >
    < property name = "driverClass" > com.mysql.jdbc.Driver </ property >
       < property name = "jdbcUrl" > jdbc:mysql:///web_07 </ property >
       < property name = "user" > root </ property >
       < property name = "password" > 123 </ property >
  </ named-config >
 
</ c3p0-config >


测试代码:
package com.ma.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import javax.sql.DataSource ;
import org.junit.Test;
import com.ma.jdbc.DataSource.MyDataSource ;
import com.ma.jdbc.utils.JDBCUtils;
public class TestC3p0 {
       @Test
       public void testAddUser (){
            Connection conn = null ;
            PreparedStatement pstmt = null ;
             //1、创建自定义连接池对象
            ComboPooledDataSource  dataSource = new ComboPooledDataSource();
             //ComboPooledDataSource  dataSource = new ComboPooledDataSource("name");//加载有名称的 datasource
            
             try {
                   //2、从池子中获取连接对象
                  conn = dataSource.getConnection();
                   //3、编写 sql 语句
                  String sql = "insert into t_user values(null, ?, ?, ?)" ;
                   //4、执行 sql
                  pstmt = conn.prepareStatement(sql);
                   //5、设置参数
                  pstmt.setString(1, "Toung" );
                  pstmt.setString(2, "444444" );
                  pstmt.setString(3, "LIN" );
                   //6、处理结果
                   int rows = pstmt.executeUpdate();
                   if (rows > 0){
                        System. out .println( "添加成功 !" );
                  } else {
                        System. out .println( "添加失败 !" );
                  }
            } catch (Exception e) {
                  
            } finally {
                  JDBCUtils. release (conn, pstmt, null );
            }
      }
}

运行结果:

DBCP 数据库连接池:

配置文件名称:*.propreties
配置文件位置:任意,建议 src 目录下面

在增删改查代码中有很多相同的代码,只有少量的地方不同,对于不同的地方我们采用传参的方式解决。
DBUtils 就是 JDBC 的简化开发工具包。
相关知识:
JavaBean 组件,JavaBean 就是一个类,在开发中常用于封装数据,具有以下特征:
1、需要实现接口:java.io.Serializable,通常偷懒省略了。
2、提供私有字段:private 类型 字段名。
3、提供 getter/setter 方法。
4、提供无参构造。

DBUtils 完成增删改查:
DbUtils 是 Java 编程中的数据库操作实用工具,小巧简单实用。
DBUtils 简化了 JDBC 的操作,可以少写代码。
DBUtils 的三个核心功能简介:
1、QueryRunner 中提供对sql 语句操作的 api。
2、ResultSetHandler 接口,用于定义 select 操作后,怎么封装结果集。
3、DbUtils 类,它就是一个工具类,定义了关闭资源与处理事务的方法。

QueryRunner 核心类:
1、QueryRunner(DataSource ds),提供数据源(连接池),DBUtils 底层自动维护连接 Connection 。
2、update(String sql, Object... params),执行更新数据。
3、query(String sql, ResultSetHandler<T> rst, Object... params),执行查询。

ResultSethandler 结果集处理类:

ArrayListHandler 将结果集中的每一条记录都封装到一个 object[]数组中,将这些数组封装到 List 集合中。
BeanHandler 将结果集中的每一条数据封装到指定的 JavaBean 中。
BeanListHandler 将结果集中的每一条记录封装到指定 JavaBean 中,将这些 JavaBean 再封装到 List 集合中。
ColumnListHandler 将结果集中指定列的字段值,封装到一个 List 集合中。
KeyedHandler 将结果集中每一条记录封装到 Map<String, Object>,再将这个 Map 集合作为令一个Map 的  value ,另一个 Map 的 key 是指定的字段的值。
MapHandler 将结果集中每一条记录封装到 Map<String, Object>集合中, key 就是字段名称, value 就是字段值。
MapListHandler 将结果集中每一条记录封装到 Map<String, Object>集合中, key 就是字段名称, value 就是字段值,再将这些 Map 封装到 List 集合中。
ScalarHandler 它适用于单数据,例如 select count(*) from 表 。
测试:

1、添加用户信息

工具类:
package com.ma.jdbc.utils;
import java.sql.Connection;
import java.sql.SQLException;
import javax.management.RuntimeErrorException ;
import javax.sql.DataSource;
public class C3P0Utils {
       private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
       public static DataSource getDataSouce(){
             return dataSource ;
      }
      
       public static Connection getConnection(){
             try {
                   return dataSource . getConnection ();
            } catch ( SQLException e) {
                  
                   throw new RuntimeException(e);
            }
      }
}

测试类:
package com.ma.jdbc.test;
import java.sql.SQLException;
import org.junit.Test;
import com.ma.jdbc.utils.C3P0Utils;
import com.mchange.v2.c3p0.cfg.C3P0ConfigUtils ;
public class TestDBUtils {
      
       @Test
       public void testAddUser (){
            
             try {
                   //1、创建核心类
                  QueryRunner qr = new QueryRunner(C3P0Utils. getDataSouce ());
                   //2、编写 sql 语句
                  String sql = "insert into t_user values(null, ?, ?, ?)" ;
                   //3、为占位符设置值
                  Object[] params = { "Long" , "333333" , "Tong" };
                   //4、执行添加操作
                   int rows = qr.update(sql, params);
                   if (rows > 0){
                        System. out .println( "插入成功 !" );
                  } else {
                        System. out .println( "插入失败 !" );
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
      }
}


2、更新用户信息
@Test
       public void testUpdateUser (){
            
             try {
                   //1、创建核心类
                  QueryRunner qr = new QueryRunner(C3P0Utils. getDataSouce ());
                   //2、编写 sql 语句
                  String sql = "update t_user set password = ? where uid = ?" ;
                   //3、为占位符设置值
                  Object[] params = { "666666" , 14};
                   //4、执行添加操作
                   int rows = qr.update(sql, params);
                   if (rows > 0){
                        System. out .println( "更新成功 !" );
                  } else {
                        System. out .println( "更新失败 !" );
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
      }


3、删除用户信息
@Test
       public void testDeleteUser (){
            
             try {
                   //1、创建核心类
                  QueryRunner qr = new QueryRunner(C3P0Utils. getDataSouce ());
                   //2、编写 sql 语句
                  String sql = "delete from t_user where uid = ?" ;
                   //3、为占位符设置值
                  Object[] params = {14};
                   //4、执行添加操作
                   int rows = qr.update(sql, params);
                   if (rows > 0){
                        System. out .println( "删除成功 !" );
                  } else {
                        System. out .println( "删除失败 !" );
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
      }

结果:
查询所有用户信息
package com.ma.jdbc.test;
import java.sql.SQLException;
import java.util.List;
import org.junit.Test;
import com.ma.domain.User;
import com.ma.jdbc.utils.C3P0Utils;
public class TestDBUtils1 {
      
       @Test
       public void queryAll(){
            
             try { //1、获取核心类
                  QueryRunner qr = new QueryRunner(C3P0Utils. getDataSouce ());
                   //2、创建 sql 语句
                  String sql = "select * from t_user" ;
                   //3、执行查询操作
                  List<User> users = qr.query(sql, new BeanListHandler<User>(User. class ));
                   //4、遍历结果
                   for (User user : users){
                        System. out .println( "uid =" + user.getUid() + "username =" + user.getUsername() + "password =" + user.getPassword() + "address =" + user.getAddress());
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
            
      }
}

结果:

打印结果:

根据 uid 查询用户信息
/**
       * 根据 uid 查询信息
       */
       @Test
       public void queryUserById(){
            
             try { //1、获取核心类
                  QueryRunner qr = new QueryRunner(C3P0Utils. getDataSouce ());
                   //2、创建 sql 语句
                  String sql = "select * from t_user where uid = ?" ;
                   //3、设置参数
                  Object[] param = {13};
                   //4、执行查询
                  User user = qr.query(sql, new BeanHandler<User>(User. class ), param);
                  System. out .println( "uid =" + user.getUid()+ " " + "username =" + user.getUsername()+ " " + "password =" + user.getPassword()+ " " + "address =" + user.getAddress());
                  
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
            
      }

结果:


查询用户总数
/**
       * 查询用户总数
       */
       @Test
       public void queryCount (){
            
             try { //1、获取核心类
                  QueryRunner qr = new QueryRunner(C3P0Utils. getDataSouce ());
                   //2、创建 sql 语句
                  String sql = "select count(*) from t_user" ;
                   //3、设置参数
                  Object[] param = {13};
                   //4、执行查询
                  Long count = (Long) qr.query(sql, new ScalarHandler());
                  System. out .println(count);
                  
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
            
      }

打印结果:


猜你喜欢

转载自blog.csdn.net/young_1004/article/details/80709751