天天看點

JDBC小結:ORM對象關系映射

1.ORM簡介

對象關系映射(Object Relationship Mapping),在我了解看來就是把資料庫内的關系資料轉變為便于程式操作的類的對象的一種機制。它将從資料庫中取出的離散的資料通過類的方式重新組織在一起維持了其原有的關系。

2.ORM執行個體

抽象的東西多說無益,直接上例子:假設在資料庫中有一張student表,表中有三個屬性sno、sname、sage分别對應學生的學号、姓名、年齡,在資料庫中對應的資訊是以資料項的形式存在,三條對應的資料項構成一條學生記錄,所有的學生記錄構成一張student表,而在程式中資訊是以對象及其内部的資料成員的方式存在。在這裡其映射關系是:一張表對應一個類,其中的一條記錄對應一個執行個體對象,每一條記錄中的資料項對應各個對象中的資料成員。

關系表     →        類
記錄         →       對象
資料項     →       資料成員

這樣的對應關系就是具體的映象方式,而我們要做的就是實作這個映象。

首先我們在資料庫中建立student表,并存入相應資料:

create table student(sno char(10),sname char(10),sage int);

insert into student values('001','子鼠',18);
insert into student values('002','醜牛',19);
insert into student values('003','寅虎',17);
insert into student values('004','卯兔',18);
insert into student values('005','辰龍',20);
           

首先,我們可以建立一個SQLOperator類,将所有的資料庫操作封裝為類的方法,屏蔽資料庫操作以及SQL語句,以便将使用者從資料庫操作中解放出來,專注業務邏輯處理。SQLOperator包含兩個資料成員,Connection用于擷取資料庫連接配接,以及PreparedStatement用于存放sql語句(也可以使用Statement,差別為前者為預編譯語句,在資料庫編譯運作時效率較高)。

SQLOperator類架構

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class SQLOperator {
	Connection connection;
	PreparedStatement statement;
	
	//擷取資料庫連接配接
	public SQLOperator(Connection c) {
		this.connection = c;
		try {
			//關閉自動送出,手動送出以確定事務的完整性
			c.setAutoCommit(false);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
           

編寫Student類用于存放從資料庫中讀出的記錄

class Student{
	public String num;
	public String name;
	public int age;
	
	public Student(String num,String name,int age) {
		this.num = num;
		this.name = name;
		this.age = age;
	}
}
           

1、完成SQLOperator的構造方法,連接配接資料庫,資料庫連接配接可參考https://blog.csdn.net/qq_42332204/article/details/95235339

//擷取資料庫連接配接
    public SQLOperator(Connection c) {
		this.connection = c;
		try {
			//關閉自動送出,手動送出以確定事務的完整性
			c.setAutoCommit(false);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
           

2、get()方法,傳入學生學号作為參數,用于擷取資料庫中學生記錄。将sql語句傳入資料庫後傳回一個查詢結果集,存放在ResultSet中,依次周遊結果集内的資料将對應的資料内容傳回給Student對象的各個成員,完成關系映射。由于sql語句封裝在get()方法内部,對使用者不可見,是以使用者無需關注資料庫操作,僅擷取到Student對象即可。

//擷取學生,依照學生的學号擷取學生對象
	public Student get(String num) {
		int age = 0;
		Student s = null;
		String name = null;
		String sql = "select * from student where sno=?";
		//try-with-resource可自動關閉statement
		try (PreparedStatement statement = connection.prepareStatement(sql);) {
			statement.setString(1, num);
			ResultSet rs = statement.executeQuery();
			//當找到學生時傳回學生,否則傳回null
			if(rs.next()) {
				name = rs.getString("sname");
				age = rs.getInt("sage");
				s = new Student(num,name,age);
			}else {
				System.err.println("NotFoundStudent");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return s;
	}
           

3、對資料庫的增加,删除,修改操作。這幾個操作較為類似,通過執行傳入的sql語句,實作對資料庫的操作。其中Statement語句中的“?”代表一個可變的參數,通過調用setString()等方法可以修改對應的"?"代表的值,方法中第一個參數代表語句中第n個“?”表示的參數,第二個參數為其值;傳參後調用execute()方法執行語句,最後commit()送出事務。

//插入,傳入一個student對象,将對象轉換為一條記錄插入到資料庫中
	public void add(Student s) {
		String sql = "insert into student values(?,?,?)";
		try (PreparedStatement statement = connection.prepareStatement(sql);) {
			statement.setString(1, s.num);
			statement.setString(2, s.name);
			statement.setInt(3, s.age);
			statement.execute();
			connection.commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//修改,依照student的學号作為key,找到并修改該學生的其他屬性
	public void update(Student s) {
		String sql = "update student set sname=? , sage=? where sno =?";
		try (PreparedStatement statement = connection.prepareStatement(sql);) {
			statement.setString(1, s.name);
			statement.setInt(2, s.age);
			statement.setString(3, s.num);
			statement.execute();
			connection.commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//删除,依照學生學号删除資料庫内對應記錄
	public void delete(Student s) {
		String sql = "delete from student where sno=?";
		try (PreparedStatement statement = connection.prepareStatement(sql);) {
			statement.setString(1, s.num);
			statement.execute();
			connection.commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
           

4、歸還或關閉資料庫連接配接。由于同一時刻與資料庫建立的連接配接是有限的,是以資料庫連接配接是一個有限資源,當完成資料庫操作以後需要歸還或關閉資料庫連接配接以便其餘使用者對資料庫進行連接配接操作。

//資料庫操作完成後傳回資料庫連接配接
	public Connection returnConnection() {
		return connection;
	}
    
    //關閉資料庫連接配接
	public void closeConnection() {
		try {
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
           

以上是一些常用的資料庫操作,通過類似的方式可以将對資料庫的操作封裝起來,友善使用者使用。最後總結一下,ORM實質是一種将資料庫記錄轉化為類的方式,通過實作由資料庫的表到類的關系映射,便于對資料進行高效的處理,并且使資料庫便于開發者使用。此處的代碼僅作參考,一些細節和健壯性問題尚未考慮的特别周全,讀者可以自行進行完善和加強。

繼續閱讀