java核心技术第四篇之JDBC第二篇
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第二篇的更多相关文章
- javaWeb核心技术第四篇之Javascript第二篇事件和正则表达式
- 事件 - 表单提交(掌握) "onsubmit" - 单击事件(掌握) "onclick" - 页面加载成功事件(掌握) "onload" ...
- java核心技术第三篇之JDBC第一篇
01.JDBC_两个重要的概念: 1).什么是数据库驱动程序:由数据库厂商提供,面向某种特定的编程语言所开发的一套访问本数据库的类库. 驱动包一般由两种语言组成,前端是:面向某种特定编程语言的语言:后 ...
- JDBC第二篇--【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】
这是我JDBC的第一篇 http://blog.csdn.net/hon_3y/article/details/53535798 1.PreparedStatement对象 PreparedState ...
- 【Java面试题系列】:Java基础知识常见面试题汇总 第二篇
文中面试题从茫茫网海中精心筛选,如有错误,欢迎指正! 第一篇链接:[Java面试题系列]:Java基础知识常见面试题汇总 第一篇 1.JDK,JRE,JVM三者之间的联系和区别 你是否考虑过我们写的x ...
- Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释
上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: JNIEXPO ...
- JAVA基础第四章-集合框架Collection篇
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...
- Java核心技术第四章——3.对象构造
重载: 如果多个方法(包含构造方法)有相同的名字.不同的参数,便产生重载.编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配挑选出相对应的方法. 如果 ...
- #Java学习之路——基础阶段(第二篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- [Java核心技术]第四章-对象与类(4.1-4.6总结)
4.1面向对象程序设计概述 OOP(面向对象编程Object Oriented Programming) OOP中数据第一位,算法第二位. 类 封装:关键在于不能让其他方法直接访问类的实例域,程序仅通 ...
随机推荐
- Springboot异常处理和自定义错误页面
1.异常来源 要处理程序发生的异常,首先需要知道异常来自哪里? 1.前端错误的的请求路径,会使得程序发生4xx错误,最常见的就是404,Springboot默认当发生这种错误的请求路径,pc端响应的页 ...
- 用Python制作的一本道生成器,最后笑喷了!
今天皮一下,众所周知,一本道是一本正经的胡说八道的简称,想必写过议论文的小伙伴,都知道引经据典是议论文高分必备,套上名人的话更加具有说服力是语文老师必教的知识点. 所以呢,今天介绍的这个生成器就走的是 ...
- C#中获取指定路径下指定后缀名的所有文件的路径的list
场景 指定一个路径和后缀名,查找这个路径下所有以此后缀名结尾的文件. 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序猿 获取 ...
- mago3DJS 应用
用于3D多块可视化的开源JavaScript库 生成3D GIS平台,集成和可视化AEC(建筑,工程,建筑)区域和传统的3D空间信息(3D GIS).将AEC和3D GIS集成到Web浏览器中,室内, ...
- 国内Maven仓库--阿里云Aliyun仓库地址及设置
aliyun Maven:http://maven.aliyun.com/nexus/#view-repositories 需要使用的话,要在maven的settings.xml 文 ...
- Linux系统学习 三、网络基础—虚拟机网络配置
Linux网络基础 Linux的ip地址配置 Linux网络配置文件 常用网络命令 虚拟机网络参数配置 1.配置Linux的IP地址 首先配置一个IP地址,让IP生效. ifconfig查看当前网络配 ...
- Linux下新增和使用系统调用
关键词:__SYSCALL().SYSCALL_DEFINEx().syscall()等等. 1. 为什么使用syscall 内核和用户空间数据交换有很多种方式:sysfs.proc.信号等等. 但是 ...
- 【机器学习之数学】03 有约束的非线性优化问题——拉格朗日乘子法、KKT条件、投影法
目录 1 将有约束问题转化为无约束问题 1.1 拉格朗日法 1.1.1 KKT条件 1.1.2 拉格朗日法更新方程 1.1.3 凸优化问题下的拉格朗日法 1.2 罚函数法 2 对梯度算法进行修改,使其 ...
- 测试使用索引库crud和高级查询分页
1.搭建ES的服务 导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifa ...
- python的imread、newaxis
一:imread 用来读取图片,返回一个numpy.ndarray类型的多维数组,具有两个参数: 参数1 filename, 读取的图片文件名,可以使用相对路径或者绝对路径,但必须带完整的文件扩展名( ...