(database connection pool)
每一次链接数据库后都会关闭一次链接是相当麻烦和浪费时间和资源的。现在我们可以通过连接池获取数据库链接,用完了再放回去,可以省去不停创建和关闭连接的时间和操作,更加高效,现在普遍连接池都可以自己设置连接池的配置。
可以作为创建连接池的基本依据,如果有想法可以以此为基本概念写一个自己的连接池
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.ujiuye.util.JdbcUtil;
public class MyConPool {
public static int initConut=5;//连接池的容量
public static List<Connection> list;//连接池
static {
list=new ArrayList<Connection>();
for (int i = 0; i <initConut; i++) {
Connection con=JdbcUtil.getConnection();
list.add(con);
}
}
public static Connection getConnection() {
if (list.isEmpty()) {
System.out.println("连接池中的连接用完了,必须等待别人归还");
return null;
}
Connection con=list.get(0);
list.remove(0);//取出一条,池子里面少一条
return con;
}
public static void close(Connection con ,Statement sm,ResultSet rs) {
list.add(con);//归还到连接池中
try {
if (sm!=null) {
sm.close();
}
if (null!=rs) {
rs.close();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
@Test
public void test1() {
Connection con1=MyConPool.getConnection();
Connection con2=MyConPool.getConnection();
Connection con3=MyConPool.getConnection();
Connection con4=MyConPool.getConnection();
Connection con5=MyConPool.getConnection();
MyConPool.close(con5, null, null);
Connection con6=MyConPool.getConnection();
System.out.println(con6);
System.out.println(con5);
System.out.println(con6==con5);
}
DataSource:为核心类
配置文件:注意键名是固定的(最前面的单词),配置文件的名字随便写
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/databaseName?useUnicode=true&characterEncoding=utf-8
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
maxIdle=8
minIdle=3
创建数据源datasource
BasicDataSourceFactory.createDataSource(properties)
public class DBCPUtil {
public static DataSource ds=null;
static {
Properties p=new Properties();
try {
p.load(new FileInputStream("src/dbcp.properties"));
// InputStream is=DBCPUtil.class.getClassLoader().
// getResourceAsStream("dbcp.properties");
// p.load(is);
//利用dbcp工具类获取数据源
ds= BasicDataSourceFactory.createDataSource(p);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
也是一个开源的数据库连接池
资源文件的名称
c3p0.properties
资源文件的配置:
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/java0708?useUnicode=true&characterEncoding=utf-8
c3p0.user=root
c3p0.password=123456
c3p0.maxPoolSize=20
c3p0.minPoolSize=3
c3p0.maxStatements=30
c3p0.maxIdleTime=150
ComboPooledDataSource dataSource = new ComboPooledDataSource();
需要注意的是,资源文件的名称和内容的key都是固定的,如果改变了将不能直接访问,需要我们在此手动读取资源文件;
public class C3P0Util {
public static ComboPooledDataSource ds;
static {
ds=new ComboPooledDataSource();
}
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
//p 为配置的properties文件的 properties对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(p);
public class DRUIDUtil {
public static DataSource ds;
static {
Properties p=new Properties();
try {
p.load(new FileInputStream("src/dbcp.properties"));
//获取数据源对象
ds=DruidDataSourceFactory.createDataSource(p);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
需要的jar包
Apache 发布的jar包
QueryRunner qr=new QueryRunner(datasource)
qr.update(sql,?的参数列表(…))返回值int类型,影响了几行
查询
qr.query(sql语句,?参数列表,返回值类型)
返回值类型:
ArrayHandler 返回的是数组
ArrayListHandler 返回的是集合
BeanHandler 返回的是对象
BeanListHandler 返回对象的集合
ScalarHandler 返回一个字段,一般情况查询聚合函数
Bean ,model ,vo 均为数据库表对应所创建的实体对象所使用的包名
案例
public class DbutilTest {
public QueryRunner qr=new QueryRunner(C3P0Util.ds);
/**增删改
* @throws SQLException
*/
public void testUpdate() throws SQLException {
int res=qr.update("insert counts(name,money) values(?,?)", "admin",10000);
System.out.println("影响了"+res+"行");
}
/**插入的同时获取自动增长的主键
* @throws SQLException
*/
public void testUpdategetKey() throws SQLException {
long key= qr.insert("insert counts(name,money) values(?,?)", new ScalarHandler<Long>(),"jack",10000);
System.out.println("主键值:"+key);
}
/**ArrayHandler,返回一条数据的所有列,以数组的方式返回
* @throws SQLException
*/
public void test3() throws SQLException {
Object[] o = qr.query("select*from counts where id=?", new ArrayHandler(),1);
System.out.println(Arrays.toString(o));
}
public void test4() throws SQLException {
List<Object[]> list = qr.query("select*from counts", new ArrayListHandler());
for(Object[] o:list) {
System.out.println(Arrays.toString(o));
}
}
/**new BeanHandler<>(Counts.class) 将查询结果自动装载到对象中
* @throws SQLException
*/
public void test5() throws SQLException {
Counts c = qr.query("select*from counts where id=?",new BeanHandler<>(Counts.class), 1);
System.out.println(c.getName());
System.out.println(c);
}
/**new BeanListHandler<>(Counts.class) 封装成对象的集合
* @throws SQLException
*/
public void test6() throws SQLException {
List<Counts> list = qr.query("select*from counts", new BeanListHandler<>(Counts.class));
for(Counts c:list) {
System.out.println(c.getId()+"--"+c.getName()+"--"+c.getMoney());
}
}
/**ScalarHandler 一般用于聚合函数的查询
* @throws SQLException
*/
@Test
public void test7() throws SQLException {
int max = qr.query("select max(money) from counts", new ScalarHandler<>());
System.out.println(max);
}
}