數據持久化 數據持久化就是將記憶體中的數據模型轉換為存儲模型,以及將存儲模型轉換為記憶體中的數據模型的統稱。數據模型可以是任何數據結構或對象模型,存儲模型可以是關係模型、XML、二進位流等。 瞬時狀態 保存在記憶體的程式數據,程式退出,數據就消失了 持久狀態 保存在磁碟上的程式數據,程式退出後依然存在 數 ...
數據持久化
數據持久化就是將記憶體中的數據模型轉換為存儲模型,以及將存儲模型轉換為記憶體中的數據模型的統稱。數據模型可以是任何數據結構或對象模型,存儲模型可以是關係模型、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 = 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介面定義方法的具體實現。
- 實體類:用於存放與傳輸對象數據。
- 資料庫連接和關閉工具類: 避免了資料庫連接和關閉代碼的重覆使用,方便修改