01.JDBC连接池_连接池的概念:
1).什么是连接池:对于多用户程序,为每个用户单独创建一个Connection,会使程序降低效率。这时我们可以创建一个"容器",
这个容器中,先缓存一些Connection对象,有用户请求,就从池中取出一个Connection对象,当用户使用完毕,
再将这个Connection放回到容器中,这个容器就叫:连接池。
2).连接池的作用:先期缓存一些Connection对象,并对这些Connection进行反复的使用,回收,而不需要为每个用户单独创建Connection
对象,从而可以提高程序的运行效率。
3).很多的第三方厂商提供了连接池的实现,Sun公司提出,所有厂商的连接池必须实现:javax.sql.DataSource(接口)
1).DBCP连接池:Apache公司的,commons项目组的成员,免费开源的。Tomcat内部使用的就是这个连接池。
2).C3P0连接池【重要掌握】:开源免费的。整体性能要好于DBCP连接池。Spring、Hibernate框架内部使用这个连接池。
02.JDBC连接池_DBCP连接池的使用:
1).将DBCP的所需jar包复制到项目目录下,并且添加构建路径:
commons-dbcp-1.4.jar
commons-pool-1.6.jar
2).复制DBCP的配置文件(dbcpcongif.properties)到项目的src目录下;
(注意:要会修改配置文件中的四个必须的配置项--driverClassName、url、username、password)

/*
dbcpcongif.properties(配置文件)

#连接设置--必须设置的
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/hei66_day21
username=root
password=1233

#可选设置
#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

*/

/*

3).使用连接池:
1).读取配置文件信息:
Properties pro = new Properties();
pro.load(当前类名.class.getClassLoader().getResourceAsStream("配置文件的名"));//运行时会默认从bin目录下查找资源文件
2).创建连接池对象
BasicDataSource dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(pro);
3).从连接池中获取Connection对象:
Connection conn = dataSource.getConnection();
4).发送SQL语句
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from products");
while(rs.next()){
System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname"));
}
rs.close();
stmt.close();
conn.close();//不是关闭,是回收
注意:配置文件中的四项必须配置项中的"键名"不要更改,是固定的名字,由DBCP内部读取。

//DBCP连接池的使用
public class Demo {
public static void main(String[] args) throws Exception {
//1.读取配置文件
Properties pro = new Properties();
pro.load(Demo.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));//在src(bin)下找配置文件
//2.创建连接池对象
BasicDataSource dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(pro);
//3.从连接池中获取连接对象
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from products");
while(rs.next()){
System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname"));
}
rs.close();
stmt.close();
conn.close();
}
}

03.JDBC连接池_C3P0连接池的使用:
1).将第三方所需的jar包复制到项目目录下:
c3p0-0.9.2-pre5.jar
mchange-commons-java-0.2.3.jar
2).将c3p0-cinfig.xml配置文件复制到src目录下:文件名不要改,而且必须在src下,C3P0内部会自动去找
(大家要会修改c3p0-config.xml中的四个必须项的配置:driverClass、jdbcUrl、user、password)

*/

/*
c3p0-cinfig.xml配置文件
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day31</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
<user-overrides user="test-user">
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="maxStatements">0</property>
</user-overrides>
</default-config>

<!-- 命名的配置 -->
<named-config name="baidu">
<!-- 连接数据库的4项基本参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day30_db</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<!-- 初始化连接数 -->
<property name="initialPoolSize">20</property>
<!-- 最小连接数 -->
<property name="minPoolSize">10</property>
<!-- 最大连接数 -->
<property name="maxPoolSize">40</property>
<!-- -JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量 -->
<property name="maxStatements">0</property>
<!-- 连接池内单个连接所拥有的最大缓存statements数 -->
<property name="maxStatementsPerConnection">5</property>
</named-config>
<!-- 命名的配置 -->
<named-config name="heima">
<!-- 连接数据库的4项基本参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day25_db</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<!-- 初始化连接数 -->
<property name="initialPoolSize">20</property>
<!-- 最小连接受 -->
<property name="minPoolSize">10</property>
<!-- 最大连接数 -->
<property name="maxPoolSize">40</property>
<!-- -JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量 -->
<property name="maxStatements">0</property>
<!-- 连接池内单个连接所拥有的最大缓存statements数 -->
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
*/

/*

3).使用连接池:
1).创建连接池对象:
ComboPooledDataSource dataSource = new ComboPooledDataSource();//寻找配置文件中的默认配置
或者
ComboPooledDataSource dataSource = new ComboPooledDataSource("baidu");//寻找配置文件中的命名配置
2).获取连接对象:
Connection conn = dataSource.getConnection();
3).发送SQL语句:
....
conn.close();//不是关闭,是回收
大家要掌握:
1.jar包位置,添加构建路径;
2.c3p0-config.xml文件的位置,内部的必须项的四项的修改:driverClass、jdbcUrl、user、password
3.ComboPooledDataSource的创建的两种方式;
4.以及后面要讲的DBUtils工具类;

//C3P0连接池的使用
public class Demo {
public static void main(String[] args) throws Exception {
//1.创建C3P0的连接池对象
// ComboPooledDataSource dataSource = new ComboPooledDataSource();//寻找配置文件中的默认配置
ComboPooledDataSource dataSource = new ComboPooledDataSource("baidu");//寻找配置文件中的命名配置
//2.获取连接对象
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from products");
while(rs.next()){
System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname"));
}
rs.close();
stmt.close();
conn.close();
}
}

------------------------------------------------------------------------------------------------------------
04.DBUtils工具包_什么是DBUtils:
1.DBUtils工具包:它是数据库相关操作的工具包,内部封装了一些对数据库操作的一些相关方法,以及自动封装结果集的相关方法。
使用它可以简化我们的数据库开发的代码。
它是Apache的项目,免费开源的。

05.DBUtils工具包_自己使用JavaBean封装结果集:

JavaBean就是一个类,在开发中常用于封装数据。具有如下特性
1.需要实现接口:java.io.Serializable ,通常偷懒省略了。
2.提供私有字段:private 类型 字段名;
3.提供getter/setter方法:
4.提供无参构造

......
//遍历结果集
while(rs.next()){//遍历,封装的过程比较繁琐,DBUtils工具包就可以很方便的封装JavaBean
Products pro = new Products();
pro.setPid(rs.getInt("pid"));
pro.setPname(rs.getString("pname"));
pro.setPrice(rs.getInt("price"));
pro.setFlag(rs.getInt("flag"));
pro.setCategory_id(rs.getInt("category_id"));

//将对象添加到集合中
proList.add(pro);
}
.....

//使用JavaBean封装结果集
public class Demo {
public static void main(String[] args) throws Exception {
//1.创建一个C3P0连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2.获取连接对象
Connection conn = dataSource.getConnection();

//3.执行查询
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from products");
//定义集合
List<Products> proList = new ArrayList<>();
//遍历结果集
while(rs.next()){
Products pro = new Products();
pro.setPid(rs.getInt("pid"));
pro.setPname(rs.getString("pname"));
pro.setPrice(rs.getInt("price"));
pro.setFlag(rs.getInt("flag"));
pro.setCategory_id(rs.getInt("category_id"));

//将对象添加到集合中
proList.add(pro);
}
//释放资源
rs.close();
stmt.close();
conn.close();

//遍历集合
for(Products p : proList){
System.out.println(p);
}

}
}

06.DBUtils工具包_DBUtils核心类
1).QueryRunner类:主要用于执行SQL语句;
2).ResultSetHandler接口 :有很多的子类,每种子类都表示一种封装结果集的方式。
3).DBUtils工具类:提供了一些跟事务处理相关的方法。
注意:DBUtils工具包,它内部不提供数据库的连接。它只负责发送SQL语句,执行SQL语句,封装结果集。
我们可以提供"连接池"对象,给QueryRunner使用。
07.DBUtils工具包_基本使用:
1).复制jar包到项目目录下;
commons-dbutils-1.4.jar
2).由于它需要C3P0连接池,所以要将这个连接池配置好。
3).使用QueryRunner执行SQL语句:
//1.添加
public void save() throws Exception{
//1.创建一个QueryRunner对象--使用连接池创建
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--添加
String sql = "insert into products values(?,?,?,?,?)";
int row = qr.update(sql, 12,"索尼电视",8000,1,1);
System.out.println("添加影响的行数:" + row);
}

//2.修改
public void update() throws Exception{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--修改
String sql = "update products set pname = ?,price = ?,flag = ?,category_id = ? where pid = ?";
int row = qr.update(sql,"索尼电视2",8002,0,3,12);
System.out.println("修改影响的行数:" + row);
}
//3.删除
@Test
public void delete() throws Exception{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--删除
String sql = "delete from products where pid = ?";
int row = qr.update(sql,12);
System.out.println("删除影响的行数:" + row);
}
08.DBUtils工具包_ResultSetHandler标记各种结果集【重点掌握】:
1).Object[] ArrayHandler : 用于查询一条记录,如果有多条,将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
如果没有查询结果,返回的是:空数组(0长度数组),不是空指针
String sql = "select * from products where category_id = 20";
Object[] objArray = qr.query(sql, new ArrayHandler());
for(Object o : objArray){
System.out.println(o);
}
2).List<Object[]> ArrayListHandler:用于查询多条记录。将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
String sql = "select * from products";
List<Object[]> objList = qr.query(sql, new ArrayListHandler());
for(Object[] objArray : objList){//遍历行
for(Object o : objArray){//遍历列
System.out.print(o + "\t");
}
System.out.println();
}
3).某个JavaBean BeanHandler:用于查询一条记录,将结果集中第一条记录封装到一个指定的javaBean中。
String sql = "select * from products where pid = 1";
Products pro = qr.query(sql, new BeanHandler<Products>(Products.class));
System.out.println(pro);
4).List<某个JavaBean> BeanListHandler:用于查询多条记录 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
String sql = "select * from products";
List<Products> proList = qr.query(sql, new BeanListHandler<Products>(Products.class));
for(Products p : proList){
System.out.println(p);
}
5).List<Object> ColumnListHandler:查询某个列的数据,将结果集中指定的列的字段值,封装到一个List集合中
String sql = "select pname from products";
List<Object> objList = qr.query(sql, new ColumnListHandler());
for(Object o : objList){
System.out.println(o);
}
6).Map<Object,Map<String,Object>> KeyedHandler:查询多条记录。将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。
String sql = "select * from products";
Map<Object, Map<String, Object>> map = qr.query(sql, new KeyedHandler());
Set<Object> keys = map.keySet();
for(Object k : keys){
System.out.println(k);
Map<String,Object> map2 = map.get(k);
Set<String> keys2 = map2.keySet();
for(String k2 : keys2){
System.out.println("\t" + k2 + " -- " + map2.get(k2));
}
}
7).Map<String,Object> MapHandler:用于查询一条记录。将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值
String sql = "select * from products where pid = 1";
Map<String, Object> map = qr.query(sql, new MapHandler());
Set<String> keys = map.keySet();
for(String k : keys){
System.out.println("键:" + k + " 值:" + map.get(k));
}
8).List<Map<String,Object> MapListHandler:用于查询多条记录。将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。
String sql = "select * from products";
List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
for(Map<String,Object> map : mapList){
Set<String> keys = map.keySet();
for(String k : keys){
System.out.println("键:" + k + " 值:" + map.get(k));
}
System.out.println("--------------------------------");
}
9).Object ScalarHandler:它是用于单个数据。例如select count(*) from 表操作。
String sql = "select sum(price) from products";
Object result = qr.query(sql, new ScalarHandler());
System.out.println("结果:" + result);

//DBUtils的基本使用
public class Demo {
//1.添加
public void save() throws Exception{
//1.创建一个QueryRunner对象--使用连接池创建
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--添加
String sql = "insert into products values(?,?,?,?,?)";
int row = qr.update(sql, 12,"索尼电视",8000,1,1);
System.out.println("添加影响的行数:" + row);
}

//2.修改
public void update() throws Exception{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--修改
String sql = "update products set pname = ?,price = ?,flag = ?,category_id = ? where pid = ?";
int row = qr.update(sql,"索尼电视2",8002,0,3,12);
System.out.println("修改影响的行数:" + row);
}
//3.删除
public void delete() throws Exception{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--删除
String sql = "delete from products where pid = ?";
int row = qr.update(sql,12);
System.out.println("删除影响的行数:" + row);
}

//4.查询
@Test
public void select() throws Exception{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--查询
//1).ArrayHandler:将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
/*String sql = "select * from products where category_id = 20";
Object[] objArray = qr.query(sql, new ArrayHandler());
for(Object o : objArray){
System.out.println(o);
}*/

//2).List<Object[]> ArrayListHandler:用于查询多条记录。将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
/*String sql = "select * from products";
List<Object[]> objList = qr.query(sql, new ArrayListHandler());
for(Object[] objArray : objList){//遍历行
for(Object o : objArray){//遍历列
System.out.print(o + "\t");
}
System.out.println();
}
*/
//3).BeanHandler:将结果集中第一条记录封装到一个指定的javaBean中。
/*String sql = "select * from products where pid = 1";
Products pro = qr.query(sql, new BeanHandler<Products>(Products.class));
System.out.println(pro);*/
//4).BeanListHandler:将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
/*String sql = "select * from products";
List<Products> proList = qr.query(sql, new BeanListHandler<Products>(Products.class));
for(Products p : proList){
System.out.println(p);
}*/

//5).ColumnListHandler:查询某个列的数据,将结果集中指定的列的字段值,封装到一个List集合中
/*String sql = "select pname from products";
List<Object> objList = qr.query(sql, new ColumnListHandler());
for(Object o : objList){
System.out.println(o);
}
*/
//6).KeyedHandler:将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。
/*String sql = "select * from products";
Map<Object, Map<String, Object>> map = qr.query(sql, new KeyedHandler());
Set<Object> keys = map.keySet();
for(Object k : keys){
System.out.println(k);
Map<String,Object> map2 = map.get(k);
Set<String> keys2 = map2.keySet();
for(String k2 : keys2){
System.out.println("\t" + k2 + " -- " + map2.get(k2));
}
}*/

//7).MapHandler 将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值
/*String sql = "select * from products where pid = 1";
Map<String, Object> map = qr.query(sql, new MapHandler());
Set<String> keys = map.keySet();
for(String k : keys){
System.out.println("键:" + k + " 值:" + map.get(k));
}*/

//8).MapListHandler 将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。
/*String sql = "select * from products";
List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
for(Map<String,Object> map : mapList){
Set<String> keys = map.keySet();
for(String k : keys){
System.out.println("键:" + k + " 值:" + map.get(k));
}
System.out.println("--------------------------------");
}
*/
//9).ScalarHandler 它是用于单个数据。例如select count(*) from 表操作。
String sql = "select sum(price) from products";
Object result = qr.query(sql, new ScalarHandler());
System.out.println("结果:" + result);
}
}

09.DBUtils工具包_QueryRunner的CRUD方法:
见demo05

//自定义工具类实现CRUD;
public class JDBCUtils {
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

public static DataSource getDataSource(){
return dataSource;
}
}

//自定义工具类实现CRUD (每个都有两种方法)
public class Demo4 {

//1.添加
@Test
public void save() throws Exception {
//1.创建一个 QueryRunner对象--使用连接池创建
//核心类
//QueryRunner qr = new QueryRunner(new ComboPooledDataSource());

QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--添加
//String sql = "insert into car values(?,?,?,?,?)";
String sql = "insert into car (id,cname) values (?,?)";
//3.参数
Object[] params = {14,"捷达"};
//int update = qr.update(sql,11,"朗逸","大众","德国",14);
int update = qr.update(sql,params);
System.out.println("添加影响的行数:" + update);
}

//2.修改
@Test
public void update() throws Exception {
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
//2.执行SQL语句--修改
String sql = "update car set cname = ?,company = ?,grade = ?,price = ? where id = ?";
//3.参数
Object[] params = {"索纳塔","大众","德国",10,14};
int update = qr.update(sql, params);
//int update = qr.update(sql,"宝来","大众","德国",13,11);
System.out.println("修改影响的行数:" + update);
}

//3.删除
@Test
public void delete() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
//2.sql
String sql = "delete from car where id = ?";
//3.参数
Object[] parms = {10};
int update = qr.update(sql,parms);
//int update = qr.update(sql,14);
System.out.println("删除影响的行数:" + update);
}

//4.通过ID查询
@Test
public void findById() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from car where id = ?";
//3.参数
Object[] parms = {8};
Products update = qr.query(sql, new BeanHandler<Products>(Products.class),parms);
//Products query = qr.query(sql, new BeanHandler<Products>(Products.class),9);
System.out.println(update);
}
//5.查询所有
@Test
public void findAll() throws Exception {
/*QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from car";
List<Products> query = qr.query(sql, new BeanListHandler<Products>(Products.class));
for (Products products : query) {
System.out.println(products);
}*/
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from car";
Object[] parms = {};
List<Products> query = qr.query(sql, new BeanListHandler<Products>(Products.class),parms);
for (Products products : query) {
System.out.println(products);
}
}

//6.查询总记录
@Test
public void count() throws Exception {
/*QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select avg(price) from car";
Object query = qr.query(sql, new ScalarHandler());
System.out.println(query);*/
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
String sql = "select count(*) from car";
Object[] parms = {};
Object query = qr.query(sql, new ScalarHandler(),parms);
System.out.println(query);
}

}

10.通过ResultSet获取列头信息:
ResultSet rs = stmt.executeQuery("select * from products");
ResultSetMetaData metaData = rs.getMetaData();//获取列的信息对象
int count = metaData.getColumnCount();//获取列的数量
System.out.println("列数:" + count);
for(int i = 1 ; i <= count ; i++){
System.out.println("列名:" + metaData.getColumnName(i));//获取指定索引的列名。索引值从1开始
}

//通过ResultSet获取列头信息
public class Demo {
public static void main(String[] args) throws Exception {
Connection conn = JDBCUtils.getDataSource().getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from products");
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
System.out.println("列数:" + count);
for(int i = 1 ; i <= count ; i++){
System.out.println("列名:" + metaData.getColumnName(i));
}
}
}

=============================================================================================================
学习目标总结:
目标:能够理解连接池的原理
1.连接池就是一个存储了一些Connection对象的容器。可以先期缓存一些Connection对象,当用户使用时取出,当用户使用完毕时回收。
可以对这些Connection对象进行反复的重用,达到提高程序运行效率的目的。

目标:能够使用DBCP连接池
1.复制2个jar包;
2.复制配置文件到src目录下。

3.创建连接池:
1).读取配置文件:
Properties pro = new Properties();
pro.load(当前类名.class.getClassLoader().getResourceAsStream("配置文件名"));
2).通过工厂类获取连接池对象
BasicDataSource dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(pro);
3).获取Connection对象
Connection conn = dataSource.getConncetion();
...
conn.close();//不是关闭,是回收
目标:能够使用C3P0连接池
1.复制2个jar包;
2.复制配置文件c3p0-config.xml到src目录下;
3.创建连接池对象:
1).创建连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();//读取默认配置
//或者
ComboPooledDataSource dataSource = new ComboPooledDataSource("baidu");//读取命名配置
2).获取连接:
Connection conn = dataSource.getConnection();
...
conn.close();//不是关闭,是回收
目标:能够理解DBUtils工具类
1.对JDBC进行了封装,用于执行增删改查等SQL语句(主要用于查询--可以自动封装结果集)
目标:能够应用QueryRunner类
1.创建对象:
QueryRunner qr = new QueryRunner(连接池对象);

2.发送SQL语句:
1).public int update(String sql,Object ... params):用于执行添加、修改、删除语句的。
2).public T query(String sql,ResultSetHandler<T> rsh,Object ... params):用于执行查询语句的。
目标:能够应用ResultSetHandler接口
1.Object[] ArrayHandler:用于查询一条记录;封装第一条记录
2.List<Object[]> ArrayListHandler:用于查询多条记录的。
3.某个Bean类型 BeanHandler : 查询一条,并自动封装JavaBean。
4.List<Bean类型> BeanListHandler:查询多条。
5.List<Object> ColumnListHandler : 查询某列的数据。
6.Map<Object , Map<String,Object>> KeyedHandler : 查询多条记录。
7.Map<String,Object> MapHandler : 查询一条记录;
8.List<Map<String,Object>> MapListHandler :查询多条记录
9.Object ScalarHandler : 查询聚合结果。单个数据

//DBCPUtiles工具类:

public class Utils_DBCP {
private static DataSource ds;
static{
Properties p = new Properties();
try{
p.load(Utils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));
ds = BasicDataSourceFactory.createDataSource(p);
}catch(Exception e){
e.printStackTrace();
}
}
public static Connection getConnection(){
try{
return ds.getConnection();
}catch(SQLException e){
throw new RuntimeException("创建连接连接失败!");
}
}
}

dbcpconfig.properties文件内容:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
password=root
username=root
上面的配置文件中的内容编写的依据是什么?源代码!!!!

测试代码:
package DBCPUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
public class Test001 {
@Test
public void demo01(){
//添加:向分类表中添加数据
Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
try {
//1 获得连接
conn = Utils_DBCP.getConnection();
//2 处理sql语句
String sql = "insert into category(cid,cname) values(?,?)";
//3获得预处理对象
psmt = conn.prepareStatement(sql);
//4设置实际参数
psmt.setString(1,"c009");
psmt.setString(2,"预处理12");
//5执行
int r = psmt.executeUpdate();
System.out.println(r);
} catch (Exception e) {
throw new RuntimeException(e);
} finally{
//6释放资源
//JdbcUtils.closeResource(conn, psmt, rs);
}
}
}

//示例代码
@Test
public void method(){
try {
//获取QueryRunner对象
QueryRunner qr = new QueryRunner();
//执行SQL语句
String sql = "SELECT * FROM zhangwu";
Object[] params = {};
Connection conn = JDBCUtils.getConnection();
Object[] objArray = qr.query(conn, sql, new ArrayHandler(), params);
//结果集的处理
System.out.println( Arrays.toString(objArray) );

conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

示例代码:
@Test
public void method(){
try {
//获取QueryRunner对象
QueryRunner qr = new QueryRunner();
//执行SQL语句
String sql = "SELECT * FROM zhangwu WHERE money>?";
Object[] params = {2000};
Connection conn = JDBCUtils.getConnection();
List<Object[]> list = qr.query(conn, sql, new ArrayListHandler(), params);
//结果集的处理
for (Object[] objArray : list) {
System.out.println( Arrays.toString(objArray) );
}

conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

ColumnListHandler什么意思?怎么使用?必须保留一份操作代码!
示例代码:

@Test
public void method(){
try {
//获取QueryRunner对象
QueryRunner qr = new QueryRunner();
//执行SQL语句
String sql = "SELECT name FROM zhangwu WHERE money>?";
Object[] params = {2000};
Connection conn = JDBCUtils.getConnection();
List<String> list = qr.query(conn, sql, new ColumnListHandler<String>(), params);
//结果集的处理
for (String str : list) {
System.out.println(str);
}

conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

java核心技术第四篇之JDBC第二篇的更多相关文章

  1. javaWeb核心技术第四篇之Javascript第二篇事件和正则表达式

    - 事件 - 表单提交(掌握) "onsubmit" - 单击事件(掌握) "onclick" - 页面加载成功事件(掌握) "onload" ...

  2. java核心技术第三篇之JDBC第一篇

    01.JDBC_两个重要的概念: 1).什么是数据库驱动程序:由数据库厂商提供,面向某种特定的编程语言所开发的一套访问本数据库的类库. 驱动包一般由两种语言组成,前端是:面向某种特定编程语言的语言:后 ...

  3. JDBC第二篇--【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】

    这是我JDBC的第一篇 http://blog.csdn.net/hon_3y/article/details/53535798 1.PreparedStatement对象 PreparedState ...

  4. 【Java面试题系列】:Java基础知识常见面试题汇总 第二篇

    文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 1.JDK,JRE,JVM三者之间的联系和区别 你是否考虑过我们写的x ...

  5. Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释

    上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: JNIEXPO ...

  6. JAVA基础第四章-集合框架Collection篇

    业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...

  7. Java核心技术第四章——3.对象构造

    重载: 如果多个方法(包含构造方法)有相同的名字.不同的参数,便产生重载.编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配挑选出相对应的方法. 如果 ...

  8. #Java学习之路——基础阶段(第二篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  9. [Java核心技术]第四章-对象与类(4.1-4.6总结)

    4.1面向对象程序设计概述 OOP(面向对象编程Object Oriented Programming) OOP中数据第一位,算法第二位. 类 封装:关键在于不能让其他方法直接访问类的实例域,程序仅通 ...

随机推荐

  1. cisco ssh实验--附带配置脚本-2019.11.19

    cisco ssh实验

  2. 使用cJSON库解析和构建JSON字符串

    使用cJSON库解析和构建JSON字符串 前言 其实之前的两篇博文已经介绍了json格式和如何使用cJSON库来解析JSON: 使用cJSON库解析JSON JSON简介 当时在MCU平台上使用时,会 ...

  3. 【朝花夕拾】Android自定义View篇之(三)Canvas绘制文字

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10968358.html],谢谢! 前面的文章中在介绍Canvas的时候,提到过后续单独讲Can ...

  4. 多线程七 AQS

    一 . 简介AQS AQS简介 在同步组件的实现中,AQS是核心部分,同步组件的实现者,通过使用AQS提供的模板方法 实现同步组件语义 AQS实现了对同步状态的管理以及阻塞线程进行排队,等待通知等等一 ...

  5. 关于scrapy中如何区分是接着发起请求还是开始保存文件

    一.区分 根据yield迭代器生成的对象是request对象还是item对象 二.item 1.配置tem对象 在items.py文件中设置类 class MyscrapyItem(scrapy.It ...

  6. Implement Custom Business Classes and Reference Properties实现自定义业务类和引用属性(EF)

    In this lesson, you will learn how to implement business classes from scratch. For this purpose, the ...

  7. 清新简约风格毕业论文答辩PPT模板推荐

    不管是学生还是老师,应该经常会需要学生答辩的PPT模板,今天给大家推荐织梦58的学生答辩ppt模板. 模版来源:http://ppt.dede58.com/gongzuohuibao/26494.ht ...

  8. oracle表空间相关统计查询

    部分转自 https://www.cnblogs.com/xwdreamer/p/3511047.html--查询表空间使用情况SELECT UPPER(F.TABLESPACE_NAME) &quo ...

  9. C#&.Net干货分享- iTextSharp导出数据源到PDF

    namespace Frame.ITextSharp{    /// <summary>    /// iTextSharp导出数据源到PDF    /// </summary> ...

  10. Linux 定位进程对应的文件路径

    ls -al /proc/[pid]/exe # 例如: [root@localhost ~]# ls -al /proc/9109/exe lrwxrwxrwx. 1 ibaboss ibaboss ...