JDBC
一、概述
1.什么是JDBC
JDBC(Java Data Base Connectivity,java数据库连接):是一种用于SQL语句的JavaAPI,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的类和接口组成。jdbc提供了一个基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也时商标名。
2.什么是数据库驱动
- 驱动:两个设备(应用)之间通信的桥梁。
3.为什么学习JDBC
没有JDBC的时候,如果现在要开发一套系统,使用Java连接MySQL数据库,那么这时候Java程序员需要了解MySQL驱动API,如果使用Java连接Oracle数据库,那么这个时候Java程序员需要了解Oracle数据库驱动API。
SUN公司提供一套统一的规范(接口)。然后各个数据库生产商提供这套接口的实现。这套接口规范就是JDBC的规范。
二、入门
1.环境准备
-
创建数据库和表
create database web_test3; use web_test3; create table user( id int primary key auto_increment, username varchar(20), password varchar(20), nickname varchar(20), age int ); insert into user values (null,'aaa','123','小丽',34); insert into user values (null,'bbb','123','大王',32); insert into user values (null,'ccc','123','小明',28); insert into user values (null,'ddd','123','大黄',21);
创建项目,引入jar包(mysql-connector-java-5.0.8-bin.jar)
2.代码实现
-
开发步骤
- 加载驱动
- 获得连接
- 基本操作
- 释放资源
-
代码实现
import org.junit.Test; public class JDBCDemo1 { @Test /** \* JDBC的入门 */ public void demo1() throws Exception{ // 1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); // 2.获得连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "abc"); // 3.基本操作:执行SQL // 3.1获得执行SQL语句的对象 Statement statement = conn.createStatement(); // 3.2编写SQL语句: String sql = "select * from user"; // 3.3执行SQL: ResultSet rs = statement.executeQuery(sql); // 3.4遍历结果集: while(rs.next()){ System.out.print(rs.getInt("id")+" "); System.out.print(rs.getString("username")+" "); System.out.print(rs.getString("password")+" "); System.out.print(rs.getString("nickname")+" "); System.out.print(rs.getInt("age")); System.out.println(); } // 4.释放资源 rs.close(); statement.close(); conn.close(); } }
三、DriverManager:驱动管理类
作用一:注册驱动
registerDriver(Driver driver)
这个方法可以完成驱动的注册,但是实际开发中一般不会使用这个方法完成驱动的注册!!!
-
原因:如果需要注册驱动,就会使用DriverManager.registerDriver(new Driver());,但是查看源代码发现,在代码中有一段静态代码块,静态代码块已经调用了注册驱动的方法。
static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver"); } }
如果再手动调用该方法注册驱动,就会导致驱动被注册两次。实际开发中一般会采用:
Class.forname("");来加载驱动
作用二:获得连接
getConnection(String url, String user, String password)建立给定数据库URL的连接
这个方法就是用来获得与数据库连接的方法:这个方法中有三个参数:
- url:与数据库连接的路径
- user:与数据库连接的用户名
- password:与数据库连接的密码
主要关注的是url的写法:jdbc:mysql://localhost:3306/web_test3 注:如果连接本地书据库,可简写为 jdbc:mysql:///web_test3
- jdbc:连接数据库的协议
- mysql:是jdbc的子协议
- localhost:连接的MySQL数据库服务器的主机地址。(连接是本机就可以写成localhost),如果连接不是本机的,就需要写上连接主机的IP地址。
- 3306:MySQL数据库服务器的端口号
- web_test3:数据库名称
四、Connection:与数据库连接对象
作用一:创建执行SQL语句的对象
createStatement()创建一个Statement对象来将SQL语句发送到数据库。
prepareCall(String sql)创建一个CallableStatement对象来调用数据库存储过程
prepareStatement(String sql)创建一个prepareStatement对象来将参数化的SQL语句发送到数据库
执行SQL语句对象:
- Statement:执行SQL
- CallableStatement:执行数据库中存储过程
- PreparedStatement:执行SQL.对SQL进行预处理。解决SQL注入漏洞。
作用二:管理事务
setAutoCommit(boolean autoCommit)将此连接的自动提交模式设置为给定状态。
commit()使所有上一次提交/回滚后进行的更改成为持久更改,并释放Connection对象当前持有的所有数据库锁。
rollback()取消在当前事务中进行所有更改,并释放此Connection对象当前持有的所欲哦数据库锁。
五、Statement:执行SQL
作用一:执行SQL
execute(String sql)执行给定的SQL语句,该语句可能返回多个结果
excutQuery(String sql)执行给定的SQL语句,该语句返回单个ResultSet对象
excuteUpdate(String sql)执行给定SQL语句,该语句可能为INSERT语句,或者不返回任何内容的SQL语句(如SQL DDL语句)
执行SQL的方法
- boolean execute(String sql); 执行查询,修改,添加,删除的SQL语句。
- ResultSet executeQuery(String sql);执行查询(执行select语句)。
- int executeUpate(String sql);执行修改,添加,删除的SQL语句。
作用二:执行批处理
addBatch(String sql)将给定的SQL命令添加到此Statement对象的当前命令列表中。
clearBatch()清空此Statement对象的当前SQL命令列表。
executeBatch()将一批命令交给数据库执行,如果全部命令执行成功,则返回更新技术组成的数组。
六、ResultSet:结果集
通过select语句的查询结果。
1.结果集的遍历
next()将光标从当前位置向前移一行
结果集遍历原理
代码实现
while(rs.next()){
System.out.print(rs.getInt("id")+" ");
System.out.print(rs.getString("username")+" ");
System.out.print(rs.getString("password")+" ");
System.out.print(rs.getString("password")+" ");
System.out.print(rs.getString("nickname")+" ");
System.out.print(rs.getString("age"));
System.out.print(rs.getInt("age"));
}
2.结果集的获取
int getInt(int columnIndex)以java编程语言中int的形式获取此ResultSet对象的当前行中指定列的值。
int getInt(String cloumnLabel)以Java编程语言中int的形式获取此ResultSet对象的当前行中指定列的值。
long getLong(String cloumnIndex)以Java编程语言中long的形式获取此ResultSet对象的当前行中指定列的值。
long getLong(String columnLabel)以Java编程语言中long的形式获取此ResultSet对象的当前行中指定列的值。
getString(int columnIndex)以Java编程语言中String的形式获取此ResultSet对象的当前行中指定列的值。
getString(String columnLabel)以Java编程语言中String的形式获取此ResultSet对象的当前行中指定列的值。
-
结果集获取可以使用结果集中的:
getXXX()方法通常都会有一个重载的方法。
- getXXX(int columnIndex);
- getXXX(String columnName);
七、JDBC资源释放
JDBC程序执行结束后,将与数据库进行交互的对象释放掉,通常是ResultSet,Statement,Connection。
这几个对象中尤其是Connection对象是非常稀有的。这个对象一定要做到尽量晚创建,尽早释放掉。
- 将资源释放的代码写入到finally的代码块中。
- 资源释放的代码应该写的标准:
if(rs !=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(statement !=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if(conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
八、CRUD操作
1.保存操作
@Test
/**
\* 保存操作的代码实现
*/
**public** **void** demo1(){
Connection conn = **null**;
Statement stmt = **null**;
**try**{
// 注册驱动:
Class.*forName*("com.mysql.jdbc.Driver");
// 获得连接:
conn = DriverManager.*getConnection*("jdbc:mysql:///web_test3", "root", "abc");
// 执行操作:
// 创建执行SQL语句对象:
stmt = conn.createStatement();
// 编写SQL语句:
String sql = "insert into user values (null,'eee','123','阿黄',21)";
// 执行SQL语句:
int num = stmt.executeUpdate(sql);
if(num > 0){
System.out.println("保存用户成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
2.修改操作
@Test
/**
* 修改操作的代码实现
*/
public void demo2(){
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动:
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行操作:
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL语句:
String sql = "update user set password='abc',nickname='旺财' where id = 5";
// 执行SQL语句:
int num = stmt.executeUpdate(sql);
if(num > 0){
System.out.println("修改用户成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
3.删除操作
@Test
/**
* 删除操作的代码实现
*/
public void demo3(){
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动:
Class.forName("com.mysql.jdbc.Driver");
// 获得连接:
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 创建执行SQL语句对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "delete from user where id = 5";
// 执行SQL:
int num = stmt.executeUpdate(sql);
if(num > 0){
System.out.println("删除用户成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
4.查询多条记录
@Test
/**
* 查询多条记录
*/
public void demo4(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行操作
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user";
// 执行SQL:
rs = stmt.executeQuery(sql);
// 遍历结果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
5.查询一条语句
@Test
/**
* 查询一条记录
*/
public void demo5(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行SQL
// 创建执行SQL语句对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user where id = 4";
rs = stmt.executeQuery(sql);
// 判断就可以:
if(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
6.抽取一个JDBC的工具类
/**
* JDBC的工具类
* @author jt
*
*/
public class JDBCUtils {
private static final String driverClassName;
private static final String url;
private static final String username;
private static final String password;
static{
driverClassName="com.mysql.jdbc.Driver";
url="jdbc:mysql:///web_test3";
username="root";
password="abc";
}
/**
* 注册驱动的方法
*/
public static void loadDriver(){
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获得连接的方法
*/
public static Connection getConnection(){
Connection conn = null;
try{
// 将驱动一并注册:
loadDriver();
// 获得连接
conn = DriverManager.getConnection(url,username, password);
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
/**
* 释放资源的方法
*/
public static void release(Statement stmt,Connection conn){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn){
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
7.配置文件
- 属性文件
- 格式:扩展名是.properties
- 内容:key=value
- XML文件
8.提取信息到配置文件
- 定义一个配置文件
9.在工具类中解析属性文件
static{
Properties properties = new Properties();
try{
properties.load(new FileInputStream("src/db.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
driveClassName = properties.getProperty("driverClassName");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
}
九、SQL注入漏洞
- 输入用户名
- aaa’ or ‘1=1 密码随意
- aaa’ -- 密码随意
public class JDBCDemo4 {
@Test
/**
*SQL注入漏洞的演示
*/
public void demo1(){
UserDao userDao = new UserDao();
//boolean flag = userDao.login("aaa' or '1=1","d");
boolean flag = userDao.login("aaa' --","d");
if(flag) {
System.out.println("登录成功!");
} else {
System.out.println("登陆失败!");
}
}
}
1.注入漏洞解决
需要采用PreparedStatement对象解决SQL注入漏洞。这个对象将SQL预先进行编译,使用?作为占位符。?所代表内容是SQL所固定。再次传入变量(包含SQL的关键字)。这个时候也不会识别这些关键字。
public class UserDao {
public boolean login(String username,String password){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
// 定义一个变量:
boolean flag = false;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "select * from user where username = ? and password = ?";
// 预编译SQL
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, username);
pstmt.setString(2, password);
// 执行SQL语句:
rs = pstmt.executeQuery();
if(rs.next()){
// 说明根据用户名和密码可以查询到这条记录
flag = true;
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
return flag;
}
2.CRUD操作
保存
@Test
/**
* 保存操作
*/
public void demo1(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "insert into user values (null,?,?,?,?)";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, "eee");
pstmt.setString(2, "abc");
pstmt.setString(3, "旺财");
pstmt.setInt(4, 32);
// 执行SQL
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("保存成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
修改
@Test
/**
* 修改操作
*/
public void demo2(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, "abc");
pstmt.setString(2, "1234");
pstmt.setString(3, "旺旺");
pstmt.setInt(4, 23);
pstmt.setInt(5, 6);
// 执行SQL:
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("修改成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
删除
@Test
/**
* 删除操作
*/
public void demo3(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "delete from user where id = ?";
// 预编译SQL
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setInt(1, 4);
// 执行SQL:
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("删除成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
查询
@Test
/**
* 查询操作
*/
public void demo4(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL:
String sql = "select * from user";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
// 执行SQL:
rs = pstmt.executeQuery();
// 遍历结果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("nickname"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}
十、批处理
1.什么是批处理
之前进行JDBC的操作的时候,都是一条SQL语句执行。现在如果使用批处理,可以将一批SQL一起执行。
2.批处理基本使用
@Test
/**
* 批处理基本操作
*/
public void demo1(){
Connection conn = null;
Statement stmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 创建执行批处理对象:
stmt = conn.createStatement();
// 编写一批SQL语句:
String sql1 = "create database test1";
String sql2 = "use test1";
String sql3 = "create table user(id int primary key auto_increment,name varchar(20))";
String sql4 = "insert into user values (null,'aaa')";
String sql5 = "insert into user values (null,'bbb')";
String sql6 = "insert into user values (null,'ccc')";
String sql7 = "update user set name = 'mmm' where id = 2";
String sql8 = "delete from user where id = 1";
// 添加到批处理
stmt.addBatch(sql1);
stmt.addBatch(sql2);
stmt.addBatch(sql3);
stmt.addBatch(sql4);
stmt.addBatch(sql5);
stmt.addBatch(sql6);
stmt.addBatch(sql7);
stmt.addBatch(sql8);
// 执行批处理:
stmt.executeBatch();
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(stmt, conn);
}
}
3.批量插入(使用PreparedStatement)
@Test
/**
* 批量插入记录:
* * 默认情况下MySQL批处理没有开启的,需要在url后面拼接一个参数即可。
*/
public void demo2(){
// 记录开始时间:
long begin = System.currentTimeMillis();
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "insert into user values (null,?)";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
for(int i=1;i<=10000;i++){
pstmt.setString(1, "name"+i);
// 添加到批处理
pstmt.addBatch();
// 注意问题:
// 执行批处理
if(i % 1000 == 0){
// 执行批处理:
pstmt.executeBatch();
// 清空批处理:
pstmt.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
long end = System.currentTimeMillis();
System.out.println((end-begin));
}
十一、连接池
- 连接池是创建和管理一个连接的缓冲池的技术,这些连接准备被任何需要他们的线程使用。
- 连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。
1.连接池原理
2.自定义连接池
- 编写一个类实现DataSource接口
- 重写getConnection方法
- 初始化多个连接在内存中
- 编写归还连接的方法
- 自定义连接池的代码实现
代码实现
public class MyDataSource implements DataSource {
//将一些连接存入到内存中,可以定义一个集合,用于存储连接对象
private List<Connection> connList = new ArrayList<Connection>();
//在初始化的时候提供一些连接
public MyDataSource() {
//初始化连接
for(int i = 1; i < 4; i++) {
//向集合中存入连接
connList.add(JDBCUtils.getConnection());
}
}
// 从连接池中获得连接的方法
@Override
public Connection getConnection() throws SQLException {
Connection conn = connList.remove(0);
return conn;
}
//编写一个归还连接的方法
public void addBack(Connection conn){
connList.add(conn);
}
}
使用装饰者模式增强Connection中的close方法
为了简化编程,提供一个模板类(模板类原封不动的将接口中的所有方法都实现,但是都没有增强)。编写一个装饰类继承模板类。在装饰类中只需要增强某一个方法即可。
代码实现
/**
* 使用装饰者增强Connection中的close方法
*/
public class MyConnectionWrapper extends ConnectionWrpper {
private Connection conn;
private List<Connection> connList;
public MyConnectionWrapper(Connection conn, List<Connection> connList) {
super(conn);
this.conn = conn;
this.connList = connList;
}
// 增强某个方法:
@Override
public void close() throws SQLException {
// super.close();
//归还连接:
connList.add(conn);
}
}
//改写连接池
public class MyDataSource implements DataSource {
// 将一些连接存入到内存中,可以定义一个集合,用于存储连接对象。
private List<Connection> connList = new ArrayList<Connection>();
// 在初始化的时候提供一些连接
public MyDataSource() {
// 初始化连接:
for(int i = 1;i<=3;i++){
// 向集合中存入连接:
connList.add(JDBCUtils.getConnection());
}
}
// 从连接池中获得连接的方法
@Override
public Connection getConnection() throws SQLException {
Connection conn = connList.remove(0);
// 增强连接:
MyConnectionWrapper connWrapper = new MyConnectionWrapper(conn, connList);
return connWrapper;
}
// 编写一个归还连接的方法:
/*public void addBack(Connection conn){
connList.add(conn);
}*/
}
3.Druid开源连接池的使用
Druid的概述
Druid阿里旗下开源连接池产品,使用非常简单,可以与Spring框架进行快速整合。
Druid的使用
@Test
/**
* Druid的使用:
* * 手动设置参数的方式
*/
public void demo1(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 使用连接池:
DruidDataSource dataSource = new DruidDataSource();
// 手动设置数据库连接的参数:
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///web_test4");
dataSource.setUsername("root");
dataSource.setPassword("abc");
// 获得连接:
// conn = JDBCUtils.getConnection();
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
// 执行SQL:
rs = pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}
@Test
/**
* Druid的使用:
* * 配置方式设置参数
* Druid配置方式可以使用属性文件配置的。
* * 文件名称没有规定但是属性文件中的key要一定的。
*/
public void demo2(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 使用连接池:
// 从属性文件中获取:
Properties properties = new Properties();
properties.load(new FileInputStream("src/druid.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
// 获得连接:
// conn = JDBCUtils.getConnection();
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
// 执行SQL:
rs = pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}
4.C3P0开源连接池的使用
C3P0的连接池的概述
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
C3P0的连接池的使用
@Test
/**
* 手动设置参数的方式:
*/
public void demo1(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 获得连接:从连接池中获取:
// 创建连接池:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置连接参数:
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///web_test4");
dataSource.setUser("root");
dataSource.setPassword("abc");
// 从连接池中获得连接:
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 执行SQL:
rs = pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}
采用配置文件的方式:
- 配置连接池
- 使用连接池
@Test
/**
* 采用配置文件的方式:
*/
public void demo2(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 获得连接:从连接池中获取:
// 创建连接池://创建连接池默认去类路径下查找c3p0-config.xml
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 从连接池中获得连接:
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 执行SQL:
rs = pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}