1.JDBC 概念
java database conactivity
java 數據庫連接技術 程序員
使用java語言操作數據的技術
使用框架操作數據庫:
mybatis、hibernate
2.JDBC 簡介
SUN 公司爲了簡化和統一對數據庫的操作制定了JDBC 的接口規範。 然後由各大數據庫廠商 提供 java連接數據庫的驅動程序。
JDBC規範中,涉及到兩個包 一個是 java.sql javax.sql
3.連接數據的URL
用來定位數據庫的位置的
主協議:子協議:[]://主機:端口號/數據庫名
jdbc:oracle:thin:@localhost:1521/xe
jdbc:mysql://localhost:3306/emp
4.JDBC 連接數據庫的步驟
4.1 加載驅動
有兩種手段 但是推薦使用第二種反射的方式
4.2 獲取數據庫連接
DriverManager.getConnection(….);
4.3 獲取sql的執行環境 Statement
4.4 執行sql
insert delete update 只要不報異常 基本上執行成功了
select 就會獲得結果集 要進行遍歷
DDL (create table drop table alter table) 基本不用
4.5 關閉資源
連接 執行環境 結果集
5.如何導入jar包
項目上右鍵 —— buildpath —- configbuild path —— add
library —– user library — - new library —– add External jars —- 一路完成 確定
6.使用JDBC 做了一個更新操作
6.1 加載驅動
Class.forName(“oracle.jdbc.OracleDriver”);
6.2 獲取數據庫連接
Connection conn = DriverManager.getConnection(url,username,password);
6.3 獲取sql 的執行環境 Statement
Statement st = conn.createStatement();
6.4 執行sql 語句 dml操作推薦使用 executeUpdate select操作推薦 executeQuery
int rows = st.executeUpdate(sql語句);
6.5 釋放資源 從小到大釋放 st 和 conn
if(st != null){
try{
st.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
st = null;
}
}
1. 元數據
主要是描述數據屬性的信息,記錄表中數據的類型 字段名字 字段的個數
create table myUser(
id number primary key,
name varchar2(30),
password varchar2(30)
);
insert into myUser values(1,’kobe’,’123’);
insert into myUser values(2,’tmac’,’456’);
commit;
2.滾動結果集
st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY); 可以隨機訪問數據 而不是按照順序訪問
3.PreparedStatement
相對於Statement優勢:
可以避免sql注入問題 ’ or ‘a’=’a
避免sql緩衝溢出
提前預編譯 提高了執行的效率
簡化了sql的拼接 避免sql語法錯誤
5. 批處理
5.1 使用 Statement 一次執行多個sql 可以是不同的操作 st.addBatch(sql3); int[] results = st.executeBatch();
5.2 使用 PreparedStatement
一次執行多個sql 每次執行的sql語句相同 只是值不同
“insert into myUser values(myuser_id_seq.nextval,?,?)”
addBatch();
executeBatch();
6.JDBC中的事務
JDBC 中事務默認是 自動提交的 把事務改爲手動提交之後 如果不主動斷開連接 事務是不會提交的 但是主動關閉會
提交事務 但是不能寄希望於這裏。我們需要明確的提交 或者 回滾 conn.commit()
或者 conn.rollback()。
1.事務的四個隔離級別
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 可以通過 Connection 點的方式 獲取對應的常量
Connection.TRANSACTION_READ_UNCOMMITED 讀未提交
Connection.TRANSACTION_READ_COMMITED 讀提交
Connection.TRANSACTION_REPEATABLE_READ 可重複讀
Connection.TRANSACTION_SERIALIZABLE 序列化
這四個隔離級別 是爲了解決三個問題
髒讀
一個事務 讀取到了 另外一個事務沒有提交的數據不可重複讀
一個事務在開始時 讀取了一份數據 然後操作的過程中 這個事務影響的數據
被另外一個事務修改了並做了修改的提交,這個時候再次讀取這份時 數據就
發生了改變。幻讀
一個事務在開始時 對錶中的所有數據進行了統計 然後操作的過程中 表中的數據發生了
增 刪 這樣統計的數據就發生了改變。
2.連接池
2.1 爲什麼要有連接池
頻繁的獲取 和 關閉連接 是非常消耗資源的 連接池的連接的關閉 只是把連接放回了連接池2.2 使用連接池來獲取連接
BasicDataSource datasource = new BasicDataSource(); // 設置數據源的參數
datasource.setDriverClassName(“oracle.jdbc.OracleDriver”);
datasource.setUrl(“jdbc:oracle:thin:@127.0.0.1:1521:xe”);
datasource.setUsername(“system”);
datasource.setPassword(“abc123”);
// 最大空閒數
datasource.setMaxIdle(5);
// 最小空閒數
datasource.setMinIdle(1);
// 最大活動連接 最大連接數據
datasource.setMaxActive(15);
// 初始化數量
datasource.setInitialSize(2);
兩種連接池比較
c3p0與dbcp區別:
dbcp沒有自動的去回收空閒連接的功能
c3p0有自動回收空閒連接功能
兩者主要是對數據連接的處理方式不同!
C3P0提供最大空閒時間,DBCP提供最大連接數。
加載驅動代碼:
db.properties
driverClassName=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=system
password=abc123
JDBCUtilProperties
package com.x.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtilProperties {
public static String driverClassName;
public static String url;
public static String username;
public static String password;
static {
try {
// 讀取 db.properties 文件
InputStream inputStream = JDBCUtilProperties.class.getClassLoader().
getResourceAsStream("com/xdl/util/db.properties");
/* Properties 就是一個key value 結構 */
Properties pro = new Properties();
try {
pro.load(inputStream);
driverClassName = pro.getProperty("driverClassName");
url = pro.getProperty("url");
username = pro.getProperty("username");
password = pro.getProperty("password");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/* 獲取數據庫 連接的方法 */
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/* 釋放資源的方法 */
public static void releaseResource(Connection conn,Statement st,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs = null;
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
st = null;
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
測試
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.x.util.JDBCUtilProperties;
public class Demo4 {
public static void main(String[] args) {
// 1.使用工具類獲取連接
Connection conn = JDBCUtilProperties.getConnection();
// 2.獲取執行環境
try {
Statement st = conn.createStatement();
// 3.執行sql
ResultSet rs = st.executeQuery
("select id,first_name name,salary from s_emp");
// 遍歷結果集
while(rs.next()) {
System.out.println(rs.getInt(1)+":"+rs.getString(2)+":"+rs.getDouble(3));
System.out.println(rs.getInt("id")+":"+rs.getString("name")+":"
+rs.getDouble("salary"));
System.out.println(rs.getInt("ID")+":"+rs.getString("NAME")+":"
+rs.getDouble("salary"));
}
//4.程序結束 釋放資源
JDBCUtilProperties.releaseResource(conn, st, rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
批處理
使用Statement 做批處理
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import com.xdl.util.JDBCUtilProperties;
public class Demo5 {
/* 使用Statement 做批處理 */
public static void test1(){
String sql1="insert into myUser values(myuser_id_seq.nextval,'testgg','xyy')";
String sql2="delete from myUser where id < 22";
String sql3="update myUser set password = '123' where id > 2";
//1.獲取連接
Connection conn = null;
Statement st = null;
conn = JDBCUtilProperties.getConnection();
//2. 獲取執行環境
try {
st = conn.createStatement();
st.addBatch(sql1);
st.addBatch(sql2);
st.addBatch(sql3);
int[] results = st.executeBatch();
for(int i : results){
System.out.println("執行的結果是 成功了:"+ i +"條");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
JDBCUtilProperties.releaseResource(conn, st, null);
}
}
public static void test2(){
String sql = "insert into myUser values(myUser_id_seq.nextval,?,?)";
String names[] = {"test1","test2","test3","test4","test5"};
String password[] = {"1","2","3","4","5"};
Connection conn = null;
PreparedStatement ps = null;
conn = JDBCUtilProperties.getConnection();
try {
ps = conn.prepareStatement(sql);
for(int i=0;i<names.length;i++){
ps.setString(1, names[i]);
ps.setString(2, password[i]);
ps.addBatch();
}
ps.executeBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
JDBCUtilProperties.releaseResource(conn, ps, null);
}
}
public static void main(String[] args) {
//test1();
test2();
}
}
}
public class Demo7 {
/* 轉賬的案例
create table bankAccount(
id number primary key,
name varchar2(30),
money number);
insert into bankAccount values(1,'mengge',10000000);
insert into bankAccount values(2,'canglaoshi',10000000);
commit;
*/
public static void test3(){
// 1.獲取連接
Connection conn = null;
PreparedStatement ps = null;
PreparedStatement ps2 = null;
conn = JDBCUtilProperties.getConnection();
try {
conn.setAutoCommit(false);
double m = 1000000;
ps = conn.prepareStatement
("update bankaccount set money=money-? where id=1 and name='mengge'");
ps.setDouble(1, m);
int rows = ps.executeUpdate();
ps2 = conn.prepareStatement
("update bankaccount set money=money+? where id=2 and name='lianglaoshi'");
ps2.setDouble(1, m);
int rows2 = ps2.executeUpdate();
if(rows == 1 && rows2 == 1 ){
System.out.println("轉賬成功");
conn.commit();
}else{
System.out.println("轉賬失敗");
conn.rollback();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtilProperties.releaseResource(conn, ps, null);
JDBCUtilProperties.releaseResource(conn, ps2, null);
}
}
public static void main(String[] args) {
//test1();
//test2();
test3();
}
}
}
public class Demo6 {
/* 測試jdbc 默認的自動提交的事務 */
public static void test1(){
Connection conn = null;
PreparedStatement ps = null;
conn = JDBCUtilProperties.getConnection();
try {
ps = conn.prepareStatement
("insert into myUser values(myuser_id_seq.nextval,?,?)");
ps.setString(1, "test99");
ps.setString(2, "888888");
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
JDBCUtilProperties.releaseResource(conn, ps, null);
}
}
/* 改變jdbc 默認的自動提交的事務 改爲手動提交 */
public static void test2(){
Connection conn = null;
PreparedStatement ps = null;
conn = JDBCUtilProperties.getConnection();
try {
// 改爲手工提交
conn.setAutoCommit(false);
ps = conn.prepareStatement
("insert into myUser values(myuser_id_seq.nextval,?,?)");
ps.setString(1, "test101");
ps.setString(2, "11111111");
ps.executeUpdate();
System.out.println("好好看着 有沒有提交");
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
JDBCUtilProperties.releaseResource(conn, ps, null);
}
}
“`