JDBC02

JDBC重构设计:
重构:就是通过调整程序代码,改善软件的质量,性能,使其程序的设计模式和框架更加合理
1.在书写Dao.Impl包下类时候每个方法中是不是都写了驱动名称/数据库连接路径/用户名和密码
更换任意一个值,非常麻烦
解决:将当前数据提取出来,做一个封装,分装成一个成员变量 方便修改
2.在书写Dao.Impl包下类时候每个方法中是不是都写了加载驱动/获取连接对象
每个方法都写了会出现重复
解决:提供一个方法专门用来提供加载驱动和获取连接对象的操作
static --> 做工具类 封装出一个工具类 ,提供加载驱动和连接对象方法
JDBCUtil工具类 --.提供一些连接数据库的基本属性,提供一个连接方法
3.JDBCUtil中getConn这个方法中有一句话Class.forname-->只要调用方法就会加载这句话
既然Class.forname每次都要加载,可以在创建JDBCUtil类的时候就提供加载完成
Class.forname提供到static代码块中
4. 在书写Dao.Impl包下类时候每个方法中是不是都写了释放资源
连接对象,执行语句对象 结果集对象
提取出来做一个封装就是是释放前资源对象
第一版本重构

5.JDBCUtil中虽然提供了一些属性这些属性是连接数据库的基本属性
只要是修改这些属性,那么就需要找到这个类JDBCUtil
可以将当前连接数据的属性值写成一个资源文件db.properties 提供连接数据库的属性
第二版重构

6.在书写Dao.Impl包下类时候每个方法中都使用SQL语句,但是是静态SQL直接将SQL语句完全写完,即不方便也不便捷,
提供预编译语言对象
执行SQL语句的时候Statement接口 -->对象 --> 用于执行静态SQL
对数据库操作也提供一种预编译语句
PreparedStatement表示预编译的 SQL 语句的对象。
在写SQL语句式,所有传递参数的位置都使用 ? 作为占位符存在
通过当前接口下setXXX(位置符号,实际传入的值)
如何看?是哪个位置 --> ? 是从1开始依次类推
例如:"UPDATE EMPLOYEESSET SALARY = ? WHERE ID = ?"
从左向后开始 第一个 ? 就即使第1位,依次类推
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)
ps:XXX-->对应的是数据类型 -->如何知道数据类型 数据库表中类的数据类型对应

执行操作方法不变参考父类接口中Statement
executeQuery() --> 查询 executeUpdate()---> 插入,删除 更新


*******db.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1
username=root
password=123456

/**
*
*/
package com.qfedu.Day28_JDBC2.domain;

/**
* Description: domain包存储的都是描述类 <br/>
* Copyright (c) , 2018, JK <br/>
* This program is protected by copyright laws. <br/>
* Program Name:Student.java <br/>
*
* @author 千锋智哥
* @version : 1.0
*/
//这个类的设计原则是根据表来完成的 ,表中提供哪些列,那么就需要在这个类中描述出来
public class Student {
private String name;
private Integer age;
private Long id;
public Student(String name, Integer age, Long id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", id=" + id + "]"+"\n";
}

}


/**
*
*/
package com.qfedu.Day28_JDBC2.dao;


import java.util.List;


import com.qfedu.Day28_JDBC2.domain.Student;


/**
* Description: 定义对数据库中的数据访问方法<br/>
* Copyright (c) , 2018, JK <br/>
* This program is protected by copyright laws. <br/>
* Program Name:IStudentDAO.java <br/>
*
* @author 千锋智哥
* @version : 1.0
*/
public interface IStudentDAO {
/**
* 将学生对象保存到数据库中
* @param student 需要保存的学生对象
*/
void save(Student student);
/**
* 删除指定学生对象
* @param id 被删除学生对象在数据库中的主键
*/
void delete(int id);
/**
* 修改指定id学生对象的信息
* @param id 学生对象在数据库中主键
* @param student 新的学生对象
*/

void update(int id,Student student);

/**
*查询所有学生对象
*@return 获取所有学生对象信息并存储到集合中
*/
List<Student> list();

/**
* 通过指定id查出对应的学生
* @param id 指定id
* @return 如果存在返回该id对应的学生对象,不存在就返回null
*/

Student get(int id);

}

/**
*
*/
package com.qfedu.Day28_JDBC2.PerparedStatement;

import static org.junit.Assert.*;

import java.sql.*;

import org.junit.Test;

/**
* Description: 测试预编译语句<br/>
* Copyright (c) , 2018, JK <br/>
* This program is protected by copyright laws. <br/>
* Program Name:PSTest.java <br/>
*
* @author 千锋智哥
* @version : 1.0
*/
public class PSTest {

@Test
public void testSaveByPerparedStatement()throws Exception {
String sql = "insert into t_student(name,age)values(?,?)";
//加载驱动获取连接对象
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "123456");
//获取执行预编译语句对象,参数需要传入sql语句

PreparedStatement ps = conn.prepareStatement(sql);
//给当前SQL语句中? 占位的位置赋予实际的值
//第一个?的位置是1 依次类推 从左向右 赋值的数据类型需要和数据库中表的数据类型一致
//当前的步骤只是给SQL语句赋值,并没有执行
ps.setString(1, "B哥");
ps.setInt(2, 35);
//执行SQL 预编译对象的执行语句 一定没有参数 千万不要传递
int rows = ps.executeUpdate();
if(rows > 0) {
System.out.println("插入成功");
}

ps.close();
conn.close();

}

}

/**
*
*/
package com.qfedu.Day28_JDBC2.dao.Impl;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;


import com.qfedu.Day28_JDBC2.dao.IStudentDAO;
import com.qfedu.Day28_JDBC2.domain.Student;


/**
* Description: 就是对整个业务的实现逻辑CRUD<br/>
* Copyright (c) , 2018, JK <br/>
* This program is protected by copyright laws. <br/>
* Program Name:StudentDAOImpl.java <br/>
*
* @author 千锋智哥
* @version : 1.0
*/
public class StudentDAOImpl implements IStudentDAO {


/*
* 插入 插入数据
*/
@Override
public void save(Student student) {
String sql = "insert into t_student(name,age)values(?,?)";
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil.getConn();
//获取预编译对象
ps = conn.prepareStatement(sql);
//赋值
ps.setString(1, student.getName());
ps.setInt(2, student.getAge());
//执行SQL 不要有参数
int rows = ps.executeUpdate();

if (rows == 1) {
System.out.println("插入成功");
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.close(conn, ps, null);
}


}


/*
* 删除
*/
@Override
public void delete(int id) {
String sql = "delete from t_student where id = ?";
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
ps.setInt(1, id);
int rows = ps.executeUpdate();
if (rows == 1) {
System.out.println("删除成功");
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.close(conn, ps, null);
}


}


/*
* 更新
*/
@Override
public void update(int id, Student student) {
String sql = "update t_Student set name = ?,age = ? where id = ?";
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
ps.setString(1, student.getName());
ps.setInt(2, student.getAge());
ps.setLong(3, id);
int rows = ps.executeUpdate();
if (rows == 1) {
System.out.println("更新成功");
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.close(conn, ps, null);
}


}


/*
* 查询
*/


@Override
public List<Student> list() {
// SQL语句
String sql = "select * from t_student";
// 创建一个集合对象 用来存储 查询结果
List<Student> list = new ArrayList<>();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {


conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();


while (rs.next()) {
Student stu = new Student();
// 因为数据库表中的列所对应的值是是可以出现null
// 这里在做描述类的时候,建议将数据类型使用包装类这样既可以兼容null也可以兼容基本类型
stu.setId(rs.getLong("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
list.add(stu);
}


if (list.size() != 0) {
return list;


}


} catch (Exception e) {


e.printStackTrace();
} finally {
JDBCUtil.close(conn, ps, rs);


}


return null;
}


/*
* 单独查询
*/
@Override
public Student get(int id) {
String sql = "select * from t_student where id= ?";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {


conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
ps.setLong(1, id);
rs = ps.executeQuery();


// 将结果集中的对象取出来
while (rs.next()) {
Student stu = new Student();
stu.setId(rs.getLong("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
return stu;
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.close(conn, ps, rs);
}


// 没有渠道值就是空对象
return null;


}


public static void main(String[] args) {
List<Student> list = new StudentDAOImpl().list();
System.out.println(list);
}


}

/**
*
*/
package com.qfedu.Day28_JDBC2.DBCP;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;


import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil;

/**
* Description: <br/>
* Copyright (c) , 2018, JK <br/>
* This program is protected by copyright laws. <br/>
* Program Name:BDCPDemo.java <br/>
*
* @author 千锋智哥
* @version : 1.0
*/
class DBCPUtil{
//1.先创建连接池对象
private static DataSource ds;
//DBCP不能像C3P0一样自动获取资源
static {
try {
Properties p = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream in = loader.getResourceAsStream("dbcp.properties");
//加载文件
p.load(in);
//DBCP对象 --> 工厂模式 -->Spring推荐 --> 底层就是工厂模式和注解
ds = BasicDataSourceFactory.createDataSource(p);
}catch(Exception e) {
e.printStackTrace();
}

}

public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
throw new RuntimeException("连接异常");
}





}

public class DBCPDemo {

public static void main(String[] args)throws Exception {
/*
* 正常使用DBCP创建对象
* BasicDataSource ds = new BasicDataSource();
* ds.setDriver/url/username/password
*
*
*/


String sql = "select * from product";
Connection conn = DBCPUtil.getConnection();
//剩余操作和JDBC是一样的
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
String name = rs.getString("productName");
double price = rs.getDouble("salePrice");
System.out.println(name + " "+ price);

}
//可以不用释放 池会管理
//建议直接释放
JDBCUtil.close(conn, ps, rs);

}

}

 



 


预编译语句和静态语句的区别
PerparedStatement的优点:
1.预编译语句的代码的可读性和可维护性好(SQL模板中使用?占位符表示参数)
2.预编译语句能最大好处的提高性能(预编译)
需要注意的是MySQL中是不支持预编译语句的性能优化的而Oracle是支持的而写数据非常快
ps:预编译的意思其实就是提前先编译好,然后在执行
3.预编译语句可以保证安全(SQL注入-->PHP写到网站)
而Statemet语句繁琐需要先创建完还需要进行拼接 所以建议使用预编译的形式来完成SQL语句

最后简要给大家分析一下预编译语句在数据库端的过程
通过Java app 将数据库查询语句发送给数据库,数据库做如下操作:
1.安全性能分析
2.语法分析
3.语法编译
4.选择并执行一条对于当前计划
5.针对于某一些数据库服务器,会存在一个预编译池 (字符串池)
在池中会先判断当前发送到DB的SQL是否已经存在在预编译池中了
若存在,则直接执行第4步
若不存在,就执行1-2-3-4-5再把该SQL存到预编译池中
重构第三版

为什么要使用连接池:
为什么必须要使用数据库连接池
普通的JDBC数据连接(Connection对象)使用DriverManager来获取,每次想数据库建立连接的时候都需要将
Connection对象加载内存中,然后在验证用户和密码(需要花费0.05~1s的时间)
建立很多Connection连接 开销成本就会非常大
需要数据连接的时候就会想数据要求一个连接请求,然后执行玩完成后在断开连接,这样的方式也会造成跟大的开销
需要一种可以即可以面对多人次的访问,又可以自动断开连接的技术 --> 数据库连接池


在java中连接池使用 javax.sql.DataSource接口来表示连接池和数据源


ps: javax --> 增强包
ps:DataSource和JDBC一样仅仅是一个接口.由各大服务厂商来实现
Connection接收数据库连接池对象
常量的DataSource:
C3p0: Hibernate推荐,该连接池在07年之后就不在更新
ps:相对来来说老一点项目都在使用C3p0 不太推荐了:性能不太好
DBCP: Apache组织的项目 Spring推荐的, 真的不错
Druid: 阿里巴巴的项目(德鲁伊) 比较好的

使用连接池和不使用连接池区别?
没有连接池通过DriverManager来获对象直接连接DB
连接池之后:直接通过连接池对象来获连接对象
Connection conn = DataSource对象.getConnection();
没有连接池的时候当前连接对象.close来释放资源
有了建连接池可以通过吃来进行对对象资源释放的管理

下面这些连接池都需要JDBC驱动

C3p0使用方式:
1.将当前C3p0所支持的jar包复制到工程下
2.通过build path --> add build path 加载到工程
3.简单的演示了C3P0连接
4.提供两种配置C3P0资源文件
需要注意C3P0的配置文件名字是固定不能变
c3p0-config.xml c3p0.properties
4.1使用xml作为资源文件加载
c3p0会自动检测是否存在c3p0-config.xml,若存在自动加载,创建对象即可
4.2使用c3p0.properties作为资源文件

*****c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db1</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123456</property>

<!--checkoutTimeout
配置当连接池所有连接用完时应用程序getConnection的等待时间。为0则无限等待直至有其他连接释放
或者创建新的连接,不为0则当时间到的时候如果仍没有获得连接,则会抛出SQLException。
initialPoolSize
连接池初始化时创建的连接数
maxIdleTime
连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接
如果为0,则永远不会断开连接
maxPoolSize
连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待
其他连接释放,所以这个值有可能会设计地很大
minPoolSize
连接池保持的最小连接数
maxStatements
连接池为数据源缓存的PreparedStatement的总数。由于PreparedStatement属于单个Connection,所以
这个数量应该根据应用中平均连接数乘以每个连接的平均PreparedStatement来计算。为0的时候不缓存
-->
<property name="checkoutTimeout">30000</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>

</default-config>
</c3p0-config>

*****c3p0.properties

c3p0.jdbcUrl=jdbc:mysql://localhost:3306/db1
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.user=root
c3p0.password=123456


c3p0.checkoutTimeout=30000
c3p0.initialPoolSize=10
c3p0.maxIdleTime=30
c3p0.maxPoolSize=100
c3p0.maxStatements=200
c3p0.minPoolSize=10
>


/**
* */ package com.qfedu.Day28_JDBC2.C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: C3P0连接<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:C3P0Demo.java <br/> * * @author 千锋智哥 * @version : 1.0 */ public class C3P0Demo { //资料中会有c3p0的官方文档 //提供一个静态方法 public static DataSource getDataSource()throws Exception{ //创建连接池对象 ComboPooledDataSource ds = new ComboPooledDataSource(); //告诉连接池如何可以进行数据库的连接 ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql://localhost:3306/db1"); ds.setUser("root"); ds.setPassword("123456"); return ds; } public static void main(String[] args) throws Exception { String sql = "select * from product"; //此时拿到的对象就是连接池中出现的Connection对象 Connection conn = getDataSource().getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } } /** * */ package com.qfedu.Day28_JDBC2.C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: XML来进行C3P0使用<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:C3P0DemoXML.java <br/> * * @author 千锋智哥 * @version : 1.0 */ class C3P0Util{ //XML配置文件 //1.创建连接池对象 private static ComboPooledDataSource ds = new ComboPooledDataSource(); public static Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } throw new RuntimeException("数据库连接异常"); } } public class C3P0DemoXML { /** * @param args */ public static void main(String[] args) throws Exception{ String sql = "select * from product"; Connection conn = C3P0Util.getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } } /** * */ package com.qfedu.Day28_JDBC2.C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.EmptyStackException; import javax.sql.DataSource; import com.mchange.v2.c3p0.DataSources; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: Properties文件连接C3P0<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:C3P0DemoProperties.java <br/> * * @author 千锋智哥 * @version : 1.0 */ class C3P0Utils{ //连接池对象 private static DataSource ds; static { try { //加载池对象并且获取Properties文件 DataSource dss = DataSources.unpooledDataSource(); //通过对象构建具体DataSource ds = DataSources.pooledDataSource(dss); } catch (SQLException e) { throw new RuntimeException("连接异常"); } } public static Connection getConnection()throws Exception{ return ds.getConnection(); } } public class C3P0DemoProperties { public static void main(String[] args)throws Exception { String sql = "select * from product"; //此时拿到的对象就是连接池中出现的Connection对象 Connection conn = C3P0Utils.getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } }


 


DBCP连接池:
1.将DBCP所支持的jar复制到当前工程下
2.通过build path --> add build path 加载到工程
3.演示连接
4.直接使用配置文件的形式来进行连接,但是不支持XML

**********dbcp.properties
url=jdbc:mysql://localhost:3306/db1 driverClass=com.mysql.jdbc.Driver username=root password=123456 maxActive=20 /** * */ package com.qfedu.Day28_JDBC2.DBCP; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: <br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:BDCPDemo.java <br/> * * @author 千锋智哥 * @version : 1.0 */ class DBCPUtil{ //1.先创建连接池对象 private static DataSource ds; //DBCP不能像C3P0一样自动获取资源 static { try { Properties p = new Properties(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream in = loader.getResourceAsStream("dbcp.properties"); //加载文件 p.load(in); //DBCP对象 --> 工厂模式 -->Spring推荐 --> 底层就是工厂模式和注解 ds = BasicDataSourceFactory.createDataSource(p); }catch(Exception e) { e.printStackTrace(); } } public static Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } throw new RuntimeException("连接异常"); } } public class DBCPDemo { public static void main(String[] args)throws Exception { /* * 正常使用DBCP创建对象 * BasicDataSource ds = new BasicDataSource(); * ds.setDriver/url/username/password * * */ String sql = "select * from product"; Connection conn = DBCPUtil.getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } }

 

 


Druid连接池:
Druid连接池和DBCP是一样的,jar包到工程
通过build path --> add build path 加载到工程
配置文件也和DBCP一样
创建对象方式 不一样

*****druid.properties
url=jdbc:mysql://localhost:3306/db1
driverClass=com.mysql.jdbc.Driver
username=root
password=123456
maxActive=20
/**
 * 
 */
package com.qfedu.Day28_JDBC2.Druid;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;



import com.alibaba.druid.pool.DruidDataSourceFactory;

import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil;

/**
 * Description: druid连接池<br/>
 * Copyright (c) , 2018, JK <br/>
 * This program is protected by copyright laws. <br/>
 * Program Name:DruidDemo.java <br/>
 * 
 * @author 千锋智哥
 * @version : 1.0
 */
class DruidUtil{
    //1.先创建连接池对象
    private static  DataSource ds;
    //DBCP不能像C3P0一样自动获取资源
    static {
        try {
          Properties p = new Properties();
          ClassLoader loader = Thread.currentThread().getContextClassLoader();
          InputStream in = loader.getResourceAsStream("druid.properties");
         //加载文件
          p.load(in);
          //创建对象
         ds = DruidDataSourceFactory.createDataSource(p);
         
        }catch(Exception e) {
            e.printStackTrace();
        }
        
    }
    
      public static Connection getConnection() {
          try {
            return ds.getConnection();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          throw new  RuntimeException("连接异常");
      }
    
    
}

public class DruidDemo {

    public static void main(String[] args)throws Exception {
         String sql = "select * from product";
         Connection conn = DruidUtil.getConnection();
         //剩余操作和JDBC是一样的
           PreparedStatement ps = conn.prepareStatement(sql);
           ResultSet rs =   ps.executeQuery();
           while(rs.next()) {
               String  name = rs.getString("productName");
               double  price = rs.getDouble("salePrice");
               System.out.println(name + " "+ price);
           
           }
           //可以不用释放 池会管理
           //建议直接释放
           JDBCUtil.close(conn, ps, rs);
    }

}

 


 

posted @ 2018-09-17 19:35  lijun199309  阅读(138)  评论(0编辑  收藏  举报