資料持久化
資料持久化就是將記憶體中的資料模型轉換為存盤模型,以及將存盤模型轉換為記憶體中的資料模型的統稱,資料模型可以是任何資料結構或物件模型,存盤模型可以是關系模型、XML、二進制流等,
瞬時狀態
保存在記憶體的程式資料,程式退出,資料就消失了
持久狀態
保存在磁盤上的程式資料,程式退出后依然存在
資料持久化技術
Hibernate、JPA、==JDBC(Java Datebase Connectivity)==等
JDBC框架
Driver 介面
java.sql.Driver 介面是所有 JDBC 驅動程式需要實作的介面,這個介面是提供給資料庫廠商使用的,不同資料庫廠商提供不同的實作
在程式中不需要直接去訪問實作了 Driver 介面的類,而是由**驅動程式管理器類(java.sql.DriverManager)**去呼叫這些Driver實作
連接、操作資料庫步驟
Connection conn = null;
Statement st=null;
ResultSet rs = null;
try {
//獲得Connection
//創建Statement
//處理查詢結果ResultSet
}catch(Exception e){
e.printStackTrance();
} finally {
//釋放資源ResultSet, Statement,Connection
}
一、獲取資料庫連接物件步驟
1、匯入jar包
1、在專案中創建lib檔案夾
2、將jar檔案放置到lib檔案夾
3、集成到專案中,右鍵build(eclipse)、add as library(idea)
2、注冊驅動(Java代碼中加載驅動類)
將com.mysql.jdbc包下的Driver類的位元組碼檔案從本地磁盤加載到方法區中
==Oracle的驅動==:oracle.jdbc.driver.OracleDriver
==mySql的驅動==: com.mysql.jdbc.Driver
方式一:加載 JDBC 驅動需呼叫 Class 類的靜態方法 forName(),向其傳遞要加載的 JDBC 驅動的類名
//將com.mysql.jdbc包下的Driver類的位元組碼檔案從本地磁盤加載到方法區中
Class.forname("com.mysql.jdbc.Driver")
方式二:DriverManager 類是驅動程式管理器類,負責管理驅動程式
DriverManager.registerDriver(com.mysql.jdbc.Driver);
通常不用顯式呼叫 DriverManager 類的 registerDriver() 方法來注冊驅動程式類的實體,原因:
1、該方法,過于依賴jar包的存在
2、該方法,會造成二次注冊
3、使用Class.forname可以降低耦合性
3、獲取連接物件
//本機IP:localhost 本機埠號:3306
String url = "jdbc:mysql://IP地址:埠號/庫名?serverTimezone=Asia/Shanghai&characterEncoding=utf-8";
String user = "用戶名";
String passWord = "密碼";
Connection conn = DriverManager.getConnection(url,user,passWord);
協議:JDBC URL中的協議總是jdbc
子協議:子協議用于標識一個資料庫驅動程式
子名稱:一種標識資料庫的方法,子名稱可以依不同的子協議而變化,用子名稱的目的是為 了定位資料庫提供足夠的資訊,包含主機名(對應服務端的ip地址),埠號,資料庫名
幾種常用資料庫的JDBC URL
對于 Oracle 資料庫連接,采用如下形式:
jdbc:oracle:thin:@localhost:1521:庫名
對于 SQLServer 資料庫連接,采用如下形式:
jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=庫名
對于 MYSQL 資料庫連接,采用如下形式:
jdbc:mysql://localhost:3306/庫名
二、執行sql陳述句
1、獲取Statement物件
Statement statement = conn.createStatement();
2、執行sql陳述句
int result = statement.executeUpdate("sql陳述句字串物件")
Statement類方法分類
- int executeUpdate(sql);
- 針對資料庫的增(insert into)、刪(delete from)、改(update set)操作
- 回傳值型別:實際影響的行數
- ResultSet executeQuery(sql);
- 針對資料庫的查詢(select from)操作
- 回傳值型別:一個結果集型別
- boolean execute(sql);
- 針對資料庫的增刪改查操作,一般我們不會使用,jdbc的底層代碼會使用
- 如果執行的sql陳述句是增刪改,回傳false
- 如果執行的sql陳述句是查詢,回傳true
3、處理執行結果(ResultSet)
//使用Statement類的方法ResultSet executeQuery(String sql);獲得結果集型別的物件
ResultSet set = statement.executeQuery(sql);
while(set.next()){
//形參可以直接寫欄位名,欄位名不區分大小寫
String id = set.getInt("book_id");
//也可以寫欄位索引,索引從1開始
String id = set.getInt(1);
}
4、釋放資源
resultSet.close();
statement.close();
connection.close();
實作JDBC工具類
將獲取連接和關閉資源等公共、重復的代碼封裝成一個工具類
import java.sql.*;
public class JDBCUtil {
private static String driver;
private static String url;
private static String user;
private static String passWord;
//決議組態檔.properties
static {
try {
Properties properties = new Properties();
properties.load(new FileInputStream(".properties檔案路徑"));
driver = (String) properties.get("driver");
url = (String) properties.get("url");
user = (String) properties.get("user");
passWord = (String) properties.get("passWord");
}catch (Exception e){
e.printStackTrace();
}
}
//獲得Connection物件
public static Connection getConnection(){
Connection connection = null;
try{
Class.forName(driver);
connection = DriverManager.getConnection(url,user,passWord);
}catch (Exception e){
e.printStackTrace();
}
return connection;
}
//關閉資源 -- 針對查詢
public static void close(ResultSet resultset,Statement statement,Connection connection){
try {
if (resultset != null) {
resultset.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
//關閉資源 -- 針對增刪改
public static void close(Statement statement,Connection connection){
close(null,statement,connection);
}
//針對DML陳述句--增刪改
public static boolean executeUpdate(String sql,List<Object> list){
Connection connection = getConnection();
PreparedStatement pre = null;
try {
pre = connection.prepareStatement(sql);
for (int i = 0;i < list.size();i++){
pre.setObject(i + 1,list.get(i));
}
return (pre.executeUpdate() > 0)? true : false;
}catch (Exception e){
e.printStackTrace();
}finally {
close(pre,connection);
}
return false;
}
//針對查DQL陳述句
public static <T> List<T> executeQuery(String sql,List<Object> list,Class<T> tClass){
Connection connection = getConnection();
PreparedStatement statement = null;
ResultSet resultSet = null;
List<T> li = new ArrayList<>();
try {
statement = connection.prepareStatement(sql);
for (int i = 0;i < list.size();i++){
statement.setObject(i + 1,list.get(i));
}
resultSet = statement.executeQuery();
ResultSetMetaData resultSetMetaData = https://www.cnblogs.com/am0304/p/resultSet.getMetaData();
//獲取列數
int count = resultSetMetaData.getColumnCount();
//遍歷所有行
while (resultSet.next()){
T t = tClass.newInstance();
for (int i = 1;i <= count;i++){
//獲取每一列列名
String keyName = resultSetMetaData.getColumnLabel(i);
//獲取每一列對應的值
Object value = resultSet.getObject(keyName);
//T中對應的屬性
Field key = tClass.getDeclaredField(keyName);
key.setAccessible(true);
key.set(t,value);
}
li.add(t);
}
}catch (Exception e){
e.printStackTrace();
}finally {
close(connection,statement,resultSet);
}
return li;
}
}
封裝查詢回傳值遍歷方式
List<Map> list = JDBCUtils.executeQuery(sql,new ArrayList());
for (Map<String,Object> map : list){
for (Map.Entry<String,Object> entry : map.entrySet()){
String s = entry.getKey();
Object o = entry.getValue();
System.out.print(s + "=" + o + ",");
}
System.out.println();
}
sql注入攻擊
SQL 注入是利用某些系統沒有對用戶輸入的資料進行充分的檢查,而在 用戶輸入資料中注入非法的 SQL 陳述句段或命令,如下,從而利用系統的 SQL 引擎完成惡意行為的做法,
SELECT user, password FROM user_table WHERE user='a' OR 1 = ' AND password = ' OR '1' = '1'
對于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(繼承于Statement) 取代 Statement 就可以了
PreparedStatement類
1、可以通過呼叫 Connection 物件的 preparedStatement() 方法獲取 PreparedStatement 物件
2、PreparedStatement 介面是 Statement 的子介面,它表示一條預編譯過的 SQL 陳述句
PreparedStatement類和Statement的比較
1、代碼的可讀性和可維護性
2、PreparedStatement 能最大可能提高性能
3、PreparedStatement 可以防止 SQL 注入
4、如果拼接表名、列名、關鍵字,必須使用Statement,防止sql陳述句錯誤
ResultSet類
1、通過呼叫 PreparedStatement 物件的 excuteQuery() 方法創建該物件
2、代表結果集
3、ResultSet 回傳的實際上就是一張資料表.,有一個指標指向資料表的第一條記錄的前面,
ResultSetMetaData 類
1、通過呼叫ResultSet物件的getMetaData()方法創建改物件
2、可用于獲取關于 ResultSet 物件中列的型別和屬性資訊的物件
常用方法
JDBC封裝Dao
**DAO (Data Access objects 資料存取物件)**是指位于業務邏輯和持久化資料之間實作對持久化資料的訪問,通俗來講,就是將資料庫操作都封裝起來,能夠是代碼的結構更加清晰化,
DAO 模式組成
- DAO介面: 把對資料庫的所有操作定義成抽象方法,可以提供多種實作,
- DAO 實作類: 針對不同資料庫給出DAO介面定義方法的具體實作,
- 物體類:用于存放與傳輸物件資料,
- 資料庫連接和關閉工具類: 避免了資料庫連接和關閉代碼的重復使用,方便修改
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/499798.html
標籤:MySQL
下一篇:MySQL實戰45講 1,2
