Java筆記 MySql資料庫JDBC(黑馬)
##JDBC
JAVA Database Connectivity java 資料庫連線
- 為什麼會出現JDBC
SUN公司提供的一種資料庫訪問規則、規範, 由於資料庫種類較多,並且java語言使用比較廣泛,sun公司就提供了一種規範,讓其他的資料庫提供商去實現底層的訪問規則。 我們的java程式只要使用sun公司提供的jdbc驅動即可。
###使用JDBC的基本步驟
-
註冊驅動
在工程中新建lib資料夾,將驅動copy到此資料夾,並右鍵點選構建路徑
DriverManager.registerDriver(new com.mysql.jdbc.Driver()); -
建立連線
//DriverManager.getConnection(“jdbc:mysql://localhost/test?user=monty&password=greatsqldb”);
//2. 建立連線 引數一: 協議 + 訪問的資料庫 , 引數二: 使用者名稱 , 引數三: 密碼。
conn = DriverManager.getConnection(“jdbc:mysql://localhost/student”, “root”, “root”); -
建立statement
//3. 建立statement , 跟資料庫打交道,一定需要這個物件
st = conn.createStatement(); -
執行sql ,得到ResultSet
//4. 執行查詢 , 得到結果集
String sql = “select * from t_stu”;
rs = st.executeQuery(sql); -
遍歷結果集
//5. 遍歷查詢每一條記錄
while(rs.next()){
int id = rs.getInt(“id”);
String name = rs.getString(“name”);
int age = rs.getInt(“age”);
System.out.println(“id=”+id + “===name=”+name+"==age="+age);
} -
釋放資源
private static void closeRs(ResultSet rs) {
try {
if(rs!=null) {
rs.close();
}
}catch(SQLException e) {
e.printStackTrace();
}finally {
rs=null;
}
}
private static void closeSt(Statement st) {
try {
if(st!=null) {
st.close();
}
}catch(SQLException e) {
e.printStackTrace();
}finally {
st=null;
}
}
private static void closeConn(Connection conn) {
try {
if(conn!=null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}finally {
conn=null;
}
}
###JDBC 工具類構建
-
資源釋放工作的整合
-
驅動防二次註冊
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Driver 這個類裡面有靜態程式碼塊,一上來就執行上面這句程式了,所以等同於我們註冊了兩次驅動。 其實沒這個必要的。
//靜態程式碼塊 —> 類載入了,就執行。 java.sql.DriverManager.registerDriver(new Driver());最後形成以下程式碼即可 Class.forName("com.mysql.jdbc.Driver"); /可以不用寫
-
使用properties配置檔案
-
在src底下宣告一個檔案 xxx.properties ,裡面的內容如下:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/student
name=root
password=root -
在工具類裡面,使用靜態程式碼塊,讀取屬性
-
static{
try {
//1. 建立一個屬性配置物件
Properties properties = new Properties();
InputStream is = new FileInputStream("jdbc.properties"); //對應檔案位於工程根目錄
//使用類載入器,去讀取src底下的資原始檔。 後面在servlet //對應檔案位於src目錄底下
//InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
//匯入輸入流。
properties.load(is)
//讀取屬性
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
name = properties.getProperty("name");
password = properties.getProperty("password")
} catch (Exception e) {
e.printStackTrace();
}
}
###資料庫的CRUD sql
-
insert
INSERT INTO t_stu (NAME , age) VALUES (‘wangqiang’,28)
INSERT INTO t_stu VALUES (NULL,'wangqiang2',28) // 1. 獲取連線物件 conn = JDBCUtil.getConn(); // 2. 根據連線物件,得到statement st = conn.createStatement(); //3. 執行新增 String sql = "insert into t_stu values(null , 'aobama' , 59)"; //影響的行數, ,如果大於0 表明操作成功。 否則失敗 int result = st.executeUpdate(sql); if(result >0 ){ System.out.println("新增成功"); }else{ System.out.println("新增失敗"); }
-
delete
DELETE FROM t_stu WHERE id = 6
// 1. 獲取連線物件 conn = JDBCUtil.getConn(); // 2. 根據連線物件,得到statement st = conn.createStatement(); //3. 執行新增 String sql = "delete from t_stu where name='aobama'"; //影響的行數, ,如果大於0 表明操作成功。 否則失敗 int result = st.executeUpdate(sql); if(result >0 ){ System.out.println("刪除成功"); }else{ System.out.println("刪除失敗"); }
-
query
SELECT * FROM t_stu
// 1. 獲取連線物件 conn = JDBCUtil.getConn(); // 2. 根據連線物件,得到statement st = conn.createStatement(); // 3. 執行sql語句,返回ResultSet String sql = "select * from t_stu"; rs = st.executeQuery(sql); // 4. 遍歷結果集 while (rs.next()) { String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println(name + " " + age); }
-
update
UPDATE t_stu SET age = 38 WHERE id = 1;
// 1. 獲取連線物件 conn = JDBCUtil.getConn(); // 2. 根據連線物件,得到statement st = conn.createStatement(); //3. 執行新增 String sql = "update t_stu set age = 26 where name ='qyq'"; //影響的行數, ,如果大於0 表明操作成功。 否則失敗 int result = st.executeUpdate(sql); if(result >0 ){ System.out.println("更新成功"); }else{ System.out.println("更新失敗"); }
查詢用st.executeQuery(sql) 增加、修改、刪除全部用 st.executeUpdate(sql);
###使用單元測試,測試程式碼
-
定義一個類, TestXXX , 裡面定義方法 testXXX.
-
新增junit的支援。
右鍵工程 — add Library — Junit — Junit4
-
在方法的上面加上註解 , 其實就是一個標記。
@Test或者@org.junit.Test
public void testQuery() {
…
} -
游標選中方法名字,然後右鍵執行單元測試。 或者是開啟outline檢視(大綱檢視), 然後選擇方法右鍵執行。
###Dao模式(宣告和實現分開)用介面
Data Access Object 資料訪問物件
- 新建一個dao的介面, 裡面宣告資料庫訪問規則
public interface UserDao {//定義一個介面
/**
* 查詢所有
*/
void findAll();//介面中的抽象方法
}
-
新建一個dao的實現類,具體實現早前定義的規則
public class UserDaoImpl implements UserDao{//建立一個類實現這個介面 @Override public void findAll() {//重寫介面中的抽象方法 Connection conn = null; Statement st = null; ResultSet rs = null; try { //1. 獲取連線物件 conn = JDBCUtil.getConn(); //2. 建立statement物件 st = conn.createStatement(); String sql = "select * from t_user"; rs = st.executeQuery(sql); while(rs.next()){ String userName = rs.getString("username"); String password = rs.getString("password"); System.out.println(userName+"="+password); } } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtil.release(conn, st, rs); } } }
-
直接使用實現
@Test//先新增junit包,用於測試
public void testFindAll(){
UserDao dao = new UserDaoImpl();//介面類物件=實現類例項
dao.findAll();
}
##Statement安全問題
-
Statement執行 ,其實是拼接sql語句的。 先拼接sql語句,然後在一起執行。
String sql = "select * from t_user where username='"+ username +"' and password='"+ password +"'"; UserDao dao = new UserDaoImpl(); dao.login("admin", "100234khsdf88' or '1=1"); SELECT * FROM t_user WHERE username='admin' AND PASSWORD='100234khsdf88' or '1=1' 前面先拼接sql語句, 如果變數裡面帶有了 資料庫的關鍵字,那麼一併認為是關鍵字。 不認為是普通的字串。 rs = st.executeQuery(sql);
PrepareStatement 更加安全
該物件就是替換前面的statement物件。
-
相比較以前的statement, 預先處理給定的sql語句,對其執行語法檢查。 在sql語句裡面使用 ? 佔位符來替代後續要傳遞進來的變數。 後面進來的變數值,將會被看成是字串,不會產生任何的關鍵字(不再將or看成關鍵字,看成是不同字串)。
// String sql = "select * from t_user where username=? and password=?"; String sql = "insert into t_user values(null , ? , ?)"; ps = conn.prepareStatement(sql); //給佔位符賦值 從左到右數過來,1 代表第一個問號, 永遠你是1開始。 ps.setString(1, userName);//下標從1開始 ps.setString(2, password); rs=ps.executeQuery();
##總結:
-
JDBC入門
-
抽取工具類 ###
-
Statement CRUD ###
演練crud
-
Dao模式 ###
宣告與實現分開
-
PrepareStament CRUD ###
預處理sql語句,解決上面statement出現的問題