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"
);
}
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();
}
}
打印结果: