十钉嘹、JDBC(重點)
1.數(shù)據(jù)庫驅(qū)動
驅(qū)動:聲卡问畅、顯卡以及數(shù)據(jù)庫等都需要驅(qū)動罕邀。
程序會通過數(shù)據(jù)庫驅(qū)動乏苦,和數(shù)據(jù)庫打交道株扛。
2.JDBC
SUN公司為了簡化開發(fā)人員的(對數(shù)據(jù)庫的統(tǒng)一)操作尤筐,提供了一個(java操作數(shù)據(jù)庫的)規(guī)范,俗稱JDBC洞就。
這些規(guī)范的實現(xiàn)由具體的廠商去做盆繁。
對于開發(fā)人員來說只需要掌握J(rèn)DBC接口的即可。
編寫時需要用到兩個包:java.sql和javax.sql旬蟋,在java中默認(rèn)就有油昂。
還需要導(dǎo)入一個數(shù)據(jù)庫驅(qū)動包:mysql-connector-java-5.1.47.jar。
mysql-connector-java下載地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java
3.第一個JDBC程序
1)創(chuàng)建一個普通項目
創(chuàng)建測試數(shù)據(jù)庫jdbcstudy和表user并插入數(shù)據(jù)倾贰,可下載使用:https://share.weiyun.com/L8nRqipC秕狰,也可以直接復(fù)制下方。
CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
USE jdbcStudy;
CREATE TABLE `users`(
id INT PRIMARY KEY,
NAME VARCHAR(40),
PASSWORD VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','lisi@sina.com','1981-12-04'),
(3,'wangwu','123456','wangwu@sina.com','1979-12-04')
打開IDEA——>選擇Create New Project——>選擇Java——>Next——>Next——>填寫項目地址和名稱躁染,點擊Finish
2)導(dǎo)入數(shù)據(jù)庫驅(qū)動
①右擊項目架忌,在其下新建一個lib目錄吞彤。
②將jar包拷入到lib目錄下。
③右擊lib——>選擇Add as Library…——>OK
3)編寫測試代碼
package demo;
import java.sql.*;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException,SQLException {
//1.加載驅(qū)動
Class.forName("com.mysql.jdbc.Driver");//固定寫法叹放,加載驅(qū)動
//2.用戶信息和url
String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&&useSSL=true";
String username = "root";
String password = "123456";
//3.連接成功饰恕,連接數(shù)據(jù)庫對象 Connection
Connection connection = DriverManager.getConnection(url,username,password);
//4.執(zhí)行SQL對象 Statement
Statement statement = connection.createStatement();
//5.執(zhí)行SQL可能存在的結(jié)果,查看返回的結(jié)果
String sql = "SELECT * FROM user";
ResultSet resultSet = statement.executeQuery(sql);//返回的結(jié)果集井仰,封裝了查詢出來的全部結(jié)果
while(resultSet.next()) {
System.out.println("id="+resultSet.getObject("id"));
System.out.println("name="+resultSet.getObject("NAME"));
System.out.println("pwd="+resultSet.getObject("PASSWORD"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("birth="+resultSet.getObject("birthday"));
}
//6.釋放連接
resultSet.close();
statement.close();
connection.close();
}
}
步驟總結(jié):Ⅰ加載驅(qū)動埋嵌。
Ⅱ連接數(shù)據(jù)庫 DriverManager
Ⅲ獲得執(zhí)行sql的對象 Statement
Ⅳ獲得返回的結(jié)果集。
Ⅴ釋放連接俱恶。
①DriverManager
注冊驅(qū)動的原來寫法:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
但不建議使用雹嗦,因為注冊了兩次。
推薦使用:
Class.forName("com.mysql.jdbc.Driver");//固定寫法合是,加載驅(qū)動
connection 代表數(shù)據(jù)庫
connection.rollback();//事務(wù)回滾
connection.commit();//事務(wù)提交
connection.setAutoCommit();//事務(wù)自動提交
②URL
//協(xié)作://主機(jī)地址:端口號/數(shù)據(jù)庫名?參數(shù)1&參數(shù)2&參數(shù)3
String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&&useSSL=true";
mysql的默認(rèn)端口號是3306了罪,oracle的默認(rèn)端口號是1521。
③Statement執(zhí)行SQL的對象聪全、PreparedStatement執(zhí)行SQL的對象
String sql = "SELECT * FROM user";//正常情況下泊藕,前面就編寫sql
statement.executeQuery();//查詢操作,返回結(jié)果集ResultSet
statement.execute();//執(zhí)行任何SQL
statement.executeUpdate();//更新难礼、插入娃圆、刪除都用這個,返回一個受影響的行數(shù)
④ResultSet查詢的結(jié)果集:封裝了所有的查詢結(jié)果蛾茉。
Ⅰ獲得指定的數(shù)據(jù)類型
resultSet.getObject();//在不知道列類型的情況下使用
//如果知道列類型就使用指定的類型
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();
…
Ⅱ遍歷讼呢,指針
resultSet.beforeFirst();//移動到最前面
resultSet.afterLast();//移動到最后面
resultSet.next();//移動到下一個數(shù)據(jù)
resultSet.previous();//移動到前一行
resultSet.absolute(row);//移動到指定行
⑤釋放資源
resultSet.close();
statement.close();
connection.close();//耗資源,用完關(guān)掉
4.statement對象
Jdbc中的statement對象用于向數(shù)據(jù)庫發(fā)送SQL語句谦炬,想完成對數(shù)據(jù)庫的增刪改查吝岭,只需要通過這個對象向數(shù)據(jù)庫發(fā)送增刪改查的語句即可。
Statement對象的executeUpdate方法,用于向發(fā)送增窜管、刪散劫、改的sql語句,executeUpdate執(zhí)行完后幕帆,將會返回一個整數(shù)(即增刪改語句導(dǎo)致了數(shù)據(jù)庫幾行數(shù)據(jù)發(fā)生了變化)
Statement.executeQuery方法用于向數(shù)據(jù)庫發(fā)送查詢語句获搏,executeQuery方法返回代表查詢結(jié)果的ResultSet的對象。
1)CRUD操作-create
使用executeUpdate(String sql)方法完成數(shù)據(jù)添加操作失乾。
Statement st = conn.createStatement();
String sql = "SELECT INTO user(…) VALUES(…)";
int num = executeUpdate(sql);
if(num>0) {
System.out.println("插入成功");
}
2)CRUD操作-delete
使用executeUpdate(String sql)方法完成數(shù)據(jù)刪除操作常熙。
Statement st = conn.createStatement();
String sql = "DELETE FROM user WHERE id=1";
int num = executeUpdate(sql);
if(num>0) {
System.out.println("刪除成功");
}
3)CRUD操作-update
使用executeUpdate(String sql)方法完成數(shù)據(jù)修改操作。
Statement st = conn.createStatement();
String sql = "UPDATE user SET name = ' ' WHERE name = ' '";
int num = executeUpdate(sql);
if(num>0) {
System.out.println("修改成功");
}
4)CRUD操作-read
使用executeQuery(String sql)方法完成數(shù)據(jù)查詢操作碱茁。
Statement st = conn.createStatement();
String sql = "SELECT * FROM user WHERE id=1";
int num = executeQuery(sql);
while(rs.next()) {
//根據(jù)獲取列的數(shù)據(jù)類型裸卫,分別調(diào)用rs的相應(yīng)方法映射到j(luò)ava對象中
}
5)代碼實現(xiàn)
①提取工具類
Ⅰ創(chuàng)建utils包,專注于寫sql纽竣。
Ⅱ創(chuàng)建db.properties墓贿,把配置類單獨放出來(如連接JDBC)。
db.properties代碼:
driver = com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&&useSSL=true
username = root
password = 123456
Ⅲ在utils包中創(chuàng)建工具類JbdcUtils.java蜓氨,讀取配置文件聋袋。
JbdcUtils.java代碼:
package demo;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.utils.Properties;
public class JbdcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.loads(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//驅(qū)動只用加載一次
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取連接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//釋放連接資源
public static void release(Connection conn,Statement st,ResultSet rs) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
②編寫增刪改的方法 executeUpdate
Ⅰ增加
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import jav.sql.Statement;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();//獲取數(shù)據(jù)庫連接
st = conn.createStatement();//獲得SQL的執(zhí)行對象
String sql = "INSERT INTO user(id,`NAME`,`PASSWORD`,`email`,`birthday`)"+"VALUES(4,'xiaoming','123456','2585801995@qq.com','2020-01-01')";
int i = st.executeUpdate(sql);
if(i>0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
Ⅱ刪除
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import jav.sql.Statement;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();//獲取數(shù)據(jù)庫連接
st = conn.createStatement();//獲得SQL的執(zhí)行對象
String sql = "DELETE FROM users WHERE id=4";
int i = st.executeUpdate(sql);
if(i>0) {
System.out.println("刪除成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
Ⅲ修改
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import jav.sql.Statement;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();//獲取數(shù)據(jù)庫連接
st = conn.createStatement();//獲得SQL的執(zhí)行對象
String sql = "UPDATE users SET `NAME`='xiaoming',`email`='2585801995@qq.com' WHERE id=1";
int i = st.executeUpdate(sql);
if(i>0) {
System.out.println("修改成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
③查詢
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import jav.sql.Statement;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
String sql = "SELECT * FROM users WHERE id=1";
rs = st.executeQuery(sql);//查詢完畢返回一個結(jié)果集
while(rs.next()) {
System.out.println(rs.getString("NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
6)SQL注入的問題
sql存在漏洞,會被攻擊導(dǎo)致數(shù)據(jù)泄露穴吹,SQL會被拼接幽勒。
例:登錄業(yè)務(wù)。
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import jav.sql.Statement;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Login("'or '1=1","'or '1=1");
}
public static void Login(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
String sql = "SELECT * FROM users WHERE `NAME`='"username"' AND `PASSWORD`='"password"'";
rs = st.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("PASSWORE"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
5.PreparedStatement對象
PreparedStatement可以防止SQL注入港令,效率更好啥容。
1)新增
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.Date;
import jav.sql.Statement;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
try {
conn = JdbcUtils.getConnection();
//Statement與PreparedStatement的區(qū)別
//使用?占位符代替參數(shù)
String sql = "SELECT INTO users(id,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES(?,?,?,?,?)";
st = conn.prepareStatement(sql);//預(yù)編譯SQL,先寫sql然后不執(zhí)行
//手動給參數(shù)賦值
st.setInt(1,4);
st.setString(2,"xiaoming");
st.setString(3,"123456");
st.setString(4,"1790283208@qq.com");
st.setDate(5,new.java.sql.Date(new Date().get Time()));
//執(zhí)行
int i = st.executeUpdate();
if(i>0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,null);
}
}
}
注意點:sql.Date 數(shù)據(jù)庫 java.sql.Date()
util.Date Java new java.sql.Date(new Date().getTime())
2)刪除
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.Date;
import jav.sql.PerparedStatement;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
try {
conn = JdbcUtils.getConnection();
//Statement與PreparedStatement的區(qū)別
//使用?占位符代替參數(shù)
String sql = "DELETE FROM users WHERE id=?";
st = conn.prepareStatement(sql);//預(yù)編譯SQL顷霹,先寫sql然后不執(zhí)行
//手動給參數(shù)賦值
st.setInt(1,4);
//執(zhí)行
int i = st.executeUpdate();
if(i>0) {
System.out.println("刪除成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,null);
}
}
}
3)更新
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.Date;
import jav.sql.Statement;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
try {
conn = JdbcUtils.getConnection();
//Statement與PreparedStatement的區(qū)別
//使用?占位符代替參數(shù)
String sql = "UPDATE users SET `NAME`=? WHERE id=?";
st = conn.prepareStatement(sql);//預(yù)編譯SQL干毅,先寫sql然后不執(zhí)行
//手動給參數(shù)賦值
st.setString(1,"xiaohong");
st.setInt(2,1);
//執(zhí)行
int i = st.executeUpdate();
if(i>0) {
System.out.println("更新成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,null);
}
}
}
4)查詢
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import jav.sql.PerparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "SELECT * FROM users WHERE id=?";
st = conn.prepareStatement(sql);//預(yù)編譯
st.setInt(2,1);//傳參賦值
rs = st.executeQuery();//執(zhí)行
if(rs.next()) {
System.out.pringln(rs.getString("NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,null);
}
}
}
5)防止SQL注入
PreparedStatement防止SQL注入的本質(zhì):把傳遞進(jìn)來的參數(shù)當(dāng)作字符。
假設(shè)其中存在轉(zhuǎn)義字符泼返,比如說'會被直接轉(zhuǎn)義硝逢。
例:修改上述登錄業(yè)務(wù)。
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import jav.sql.Statement;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Login("xiaohong","123456");
}
public static void Login(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "SELECT * FROM users WHERE `NAME`=? AND `PASSWORD`=?";
st = conn.prepareStatement(sql);
st.setString(1,username);
st.setString(2,password);
rs = st.executeQuery();
while(rs.next()) {
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("PASSWORE"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
6.使用IDEA連接數(shù)據(jù)庫
1)IDEA連接數(shù)據(jù)庫:右側(cè)Database——>點擊+——>選擇Data Source——>選擇MySQL——>填寫數(shù)據(jù)庫的用戶名和密碼——>點擊Test Connection測試功能——>點擊Apply——>OK
2)連接成功后绅喉,可以選擇數(shù)據(jù)庫:
選擇設(shè)置——>選擇Schemas渠鸽,選擇需要選擇的數(shù)據(jù)庫——>Apply
雙擊數(shù)據(jù)庫或其中的表即可查看。
更新數(shù)據(jù):修改完表后點擊帶有DB的綠色箭頭柴罐。
3)編寫SQL:
右側(cè)控制臺——>選擇console(Default)
右上角可以切換數(shù)據(jù)庫徽缚。
創(chuàng)建賬戶測試表account并導(dǎo)入測試數(shù)據(jù),可下載使用:https://share.weiyun.com/LYbdjkee革屠,也可以直接復(fù)制下方凿试。
CREATE TABLE account(
id Int PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(40),
money FLOAT
);
/*插入測試數(shù)據(jù)*/
insert into account(name,money) values('A',1000);
insert into account(name,money) values('B',1000);
insert into account(name,money) values('B',1000);
4)可能遇到的問題:
測試連接失敗:①lib下沒有導(dǎo)入jar包排宰。
②導(dǎo)入后仍然失敗:左側(cè)數(shù)據(jù)庫中選擇MySQL那婉,查看當(dāng)前Class和數(shù)據(jù)庫對應(yīng)的版本SQL板甘。
7.事務(wù)
要么都成功,要么都失敗!
ACID原則:
原子性:要么全部完成试伙,要么都不完成。
一致性:總數(shù)不變冰木。
隔離性:多個進(jìn)程互不干擾。
持久性:一旦提交不可逆,持久化到數(shù)據(jù)庫了。
隔離性的問題:
臟讀:一個事務(wù)讀取了另一個沒有提交的事務(wù)猫妙。
不可重復(fù)讀:在同一個事務(wù)內(nèi),重復(fù)讀取表中的數(shù)據(jù)聚凹,表數(shù)據(jù)發(fā)生了改變割坠。
虛讀(幻讀):在一個事務(wù)內(nèi),讀取到了別人插入的數(shù)據(jù)元践,導(dǎo)致前后讀出來的結(jié)果不一致。
用Java來實現(xiàn)模擬轉(zhuǎn)賬童谒。
package demo;
import demo.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import jav.sql.ResultSet;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
//關(guān)閉數(shù)據(jù)庫的自動提交单旁,自動會開啟事務(wù)
conn.SetAutoCommit(false);//開啟事務(wù)
String sql1 = "UPDATE account SET money = money-100 WHERE name='A'";
st = conn.prepareStatement(sql1);
st.executeUpdate();
String sql2 = "UPDATE account SET money = money+100 WHERE name='B'";
st = conn.prepareStatement(sql2);
st.executeUpdate();
//業(yè)務(wù)完畢,提交事務(wù)
conn.commit();
System.out.println("成功");
} catch (SQLException e) {
//若失敗饥伊,則默認(rèn)回滾
//try {
//conn.rollback();//如果失敗象浑,則回滾事務(wù)
//} catch (SQLException e1) {
//e1.printStackTrace();
//}
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,null);
}
}
}
代碼實現(xiàn)步驟:
①開啟事務(wù)。
conn.setAutoCommit(false);
②一組事務(wù)執(zhí)行完畢琅豆,提交事務(wù)
③可在catch語句中顯示的定義回滾語句愉豺,但默認(rèn)失敗就會回滾。
8.數(shù)據(jù)庫連接池
數(shù)據(jù)庫——>執(zhí)行完畢——>釋放
連接——>釋放:十分浪費(fèi)系統(tǒng)資源
池化技術(shù):準(zhǔn)備一些預(yù)先的資源茫因,過來就連接預(yù)先準(zhǔn)備好的蚪拦。
最小連接數(shù)根據(jù)常用連接數(shù)來設(shè)置。
最大連接數(shù)為業(yè)務(wù)最高的承載上限冻押,超過就排隊等待驰贷。
等待超時,等待超過一定時間洛巢。
編寫連接池括袒,實現(xiàn)一個接口DataSource。
開源數(shù)據(jù)源實現(xiàn)(拿來就用):
使用數(shù)據(jù)庫連接池后稿茉,在項目開發(fā)中就不需要編寫連接數(shù)據(jù)庫的代碼了锹锰。
①DBCP
需要用到的jar包:commons-dbcp-1.4芥炭、commons-pool-1.6 導(dǎo)入lib目錄下
創(chuàng)建配置dbcpconfig.properties,可下載使用:https://share.weiyun.com/RNemC1zT恃慧,也可以直接復(fù)制下方园蝠。
#連接設(shè)置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
#<!-- 初始化連接 -->
initialSize=10
#最大連接數(shù)量
maxActive=50
#<!-- 最大空閑連接 -->
maxIdle=20
#<!-- 最小空閑連接 -->
minIdle=5
#<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驅(qū)動建立連接時附帶的連接屬性屬性的格式必須為這樣:【屬性名=property;】
#注意:"user" 與 "password" 兩個屬性會被明確地傳遞,因此這里不需要包含他們糕伐。
connectionProperties=useUnicode=true;characterEncoding=UTF8
#指定由連接池所創(chuàng)建的連接的自動提交(auto-commit)狀態(tài)砰琢。
defaultAutoCommit=true
#driver default 指定由連接池所創(chuàng)建的連接的只讀(read-only)狀態(tài)。
#如果沒有設(shè)置該值良瞧,則“setReadOnly”方法將不被調(diào)用陪汽。(某些驅(qū)動并不支持只讀模式,如:Informix)
defaultReadOnly=
#driver default 指定由連接池所創(chuàng)建的連接的事務(wù)級別(TransactionIsolation)褥蚯。
#可用值為下列之一:(詳情可見javadoc挚冤。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
創(chuàng)建工具類JdbcUtils_DBCP.java,讀取配置文件赞庶。
JdbcUtils_DBCP.java代碼:
package demo;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.utils.Properties;
public class JbdcUtils_DBCP {
private static DataSource dataSource = null;
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.loads(in);
//創(chuàng)建數(shù)據(jù)庫 工廠模式——>創(chuàng)建
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取連接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//釋放連接資源
public static void release(Connection conn,Statement st,ResultSet rs) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
②C3P0
需要用到的jar包:c3p0-0.95.5训挡、mchange-commons-java-0.2.19 導(dǎo)入lib目錄下
創(chuàng)建配置c3p0-config.xml,可下載使用:https://share.weiyun.com/ZzjAbPtR歧强,也可以直接復(fù)制下方澜薄。
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!--c3p0的缺省(默認(rèn))配置
如果在代碼中"ComboPooledDataSource ds=new ComboPooledDataSource();"這樣寫就表示使用的是c3p0的缺侍帷(默認(rèn))-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&uesSSL=true&serverTimezone=UTC</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquiredIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!--c3p0的命名配置
如果在代碼中"ComboPooledDataSource ds=new ComboPooledDataSource();"這樣寫就表示使用name="MySQL"的配置-->
<name-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&uesSSL=true&serverTimezone=UTC</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquiredIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</name-config>
</c3p0-config>
注:可單獨命名多套配置
創(chuàng)建工具類JdbcUtils_C3P0.java肤京,讀取配置文件。
JdbcUtils_C3P0.java代碼:
package demo;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.utils.Properties;
public class JbdcUtils_DBCP {
private static ComboPooledDataSource dataSource = null;
static {
try {
//代碼版配置茅特,不建議使用
dataSource.setDriverClass();
dataSource.setUser();
dataSource.setPassword();
dataSource.setJdbcUrl();
dataSource.setMaxPoolSize();
dataSource.setMinPoolSize();
//配置文件寫法
dataSource = new ComboPooledDataSource("MySQL");
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取連接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//釋放連接資源
public static void release(Connection conn,Statement st,ResultSet rs) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
③阿里巴巴:Druid
結(jié)論:無論使用什么數(shù)據(jù)源忘分,本質(zhì)還是一樣的。DataSource接口不會變白修,方法就不會變妒峦。