Hibernate常用增刪改查方法

1.簡單CURD

1.1 session.get(實體類名.class,主鍵值)

  • 根據主鍵值查詢單條數據
  • 先從緩存中查找擁有該主鍵值的對象,如果沒有查找到則發送sql從數據庫查詢

1.2 session.load(實體類名.class,主鍵值)

  • 根據主鍵值查詢單條數據(一般配合lazyload=true[默認]使用)
  • 先從緩存中查找擁有該主鍵值的對象,如果沒有查找到則只會返回只有主鍵值的代理對象,當在session範圍內調用該代理對象除了主鍵值其他之外的屬性,則會發送sql語句到數據庫進行查詢並返回完整的對象;如果再session範圍外調用代理對象,則會直接報錯no session

1.3 session.save(對象)

  • 插入一條數據到數據庫
			//新建實體類對象
			Subject subject = new Subject();
			//設置屬性值
			subject.setName("科目十");
			//插入到數據庫
			session.save(subject);
			
			//插入後可以查看主鍵值
			System.out.println(subject.getId());

1.4 session.update(對象)

  • 更新一條數據到數據庫
  • 要先查詢整條數據,再修改部分數據,最後再更新到數據庫
  • 如果直接新建對象修改部分屬性,更新到數據庫後其他列會有空值(默認更新所有列)
//先查詢
Student student=session.get(Student.class, 1);
//修改數據
student.setName("李九");
//更新數據庫
session.update(student);

1.5 session.saveOrUpdate(對象)

  • 當對象有主鍵標識屬性值時,執行update()方法
  • 當對象沒有主鍵標屬性值時,執行save()方法

1.6 session.delete(對象)

  • 根據主鍵值刪除一條數據
  • 要先查詢再刪除,能避免各種屬性非空報錯,能方便級聯刪除(要改配置)
//1.先查詢
Student student=session.get(Student.class, 2);

//2.刪除數據
session.delete(student);

2.HQL查詢

2.1 Query常用方法

  • List list()

    • 一次性查詢返回多列數據
  • Iterator iterate()

    • 查詢符合條件的每條記錄的主鍵值,其他列不會查詢,當後面需要用到其他屬性時,會根據主鍵值查詢該條記錄
  • Object uniqueResult()

    • 查詢返回單個值
  • Query setParameter(參數名稱或下標,參數值)

    • 設置hql查詢單個條件值
  • Query setProperties(自定義條件類對象)

    • 如果條件對象的屬性與hql的參數名相同,則自動把對應的屬性值賦值到hql中
  • Query setMaxResults(page_size)

    • 設置分頁查詢的每頁顯示的數量
  • Query setFirstResult(startIndex)

    • 設置分頁查詢的起始下標(不包含startIndex),也可以理解爲跳過startIndex條數據後開始讀取
    • startIndex=(當前頁碼-1)*每頁顯示的數量

2.1 hql簡單查詢

  • hql語法跟sql基本一樣的
    • 查詢所有列時可以省略select *
    • 表名要大寫
    • 用到外鍵表的列時要先給主鍵表起別名,再根據java調用對象屬性方式調用
// hql語句
	String hql = "from Student s where sex=:sex and s.grade.id=:grade_id order by id desc";
	// 創建hql查詢
	Query query = session.createQuery(hql);
	// 設置hql參數
	query.setParameter("sex", 1);
	query.setParameter("grade_id", 1);
	// 查詢返回實體對象集合
	List<Student> list = query.list();
	for (Student student : list) {
		System.out.println(student.getName() + "、" + student.getSex());
	}

2.2 hql分組統計查詢

String hql = "select count(*) from Student s group by s.grade.id";
Query query = session.createQuery(hql);

//count()返回的是Long值
List<Long> list=  query.list();
for (Long count : list) {
	System.out.println(count);
}

2.3 hql分頁查詢

	String hql = "from Student";
	
	Query query = session.createQuery(hql);
	
	int page_size=3;  //頁大小
	int page_index=2; //當前頁碼
	
	//開始下標=(當前頁碼-1)*頁大小
	int startIndex=(page_index-1)*page_size;
	
	//設置分頁查詢的開始下標(不包含),即跳過startIndex條記錄後再查詢
	query.setFirstResult(startIndex);
	//設置每頁顯示的記錄數
	query.setMaxResults(page_size);
	
	// 查詢返回實體對象集合
	List<Student> list = query.list();

2.4 投影查詢

//查詢部分列並通過構造方法創建對象,返回該對象的集合
//Student類中需要對應的構造方法public Student(String name,Grade grade)
String hql = "select new Student(name,grade) from Student s";
Query query = session.createQuery(hql);	
List<Student> list = query.list();
for (Student student : list) {			
	System.out.println(student.getName() + "、"+student.getGrade().getId() );
}

2.5 迫切連接

  • 語法from Entity [left|right] join [fetch] Entity.property
  • 瞭解即可,一般直接調用實體類的外鍵類屬性和set子表集合即可獲取所有關聯信息(懶加載,自動查詢)
	//迫切外連接:把主表和子表的數據都一次性查詢出來
	//因爲主表Grade對應着子表的多條記錄,所以這裏需要distinct去掉重複項
	String hql = "select distinct g from Grade g left join fetch g.students";
	Query query = session.createQuery(hql);	
	
	//把子表所有數據封裝到主表的students屬性中
	List<Grade> list = query.list();
	
	for (Grade grade : list) {			
		System.out.println(grade.getName());
		 Set<Student> students = grade.getStudents();
		for (Student student : students) {
			System.out.println(student.getName());
		}	
	}

2.6 子查詢

  • all
    • 如果當前篩選all子查詢內返回0條記錄,任何判斷符號,該判斷都爲true
    • 如果當前篩選all子查詢內返回1條或以上記錄,則返回的所有記錄都符合條件才爲true
//查詢所有成績都及格的學生(沒有成績的學生也不查詢)
//如果不加s.results.size>0這個額外條件,沒有成績的學生也會被查詢到
//因爲沒有成績的學生all()沒有返回記錄,所以無論60>還是60<都是爲true
from Student s where 60<all(select r.score from s.results r) 
and s.results.size>0
  • any
    • 如果當前篩選any子查詢內返回0條記錄,該判斷爲false
    • 如果當前篩選all子查詢內返回1條或以上記錄,則返回的所有記錄只要有一條記錄符合條件即爲true,全部記錄都不符合才爲false
    • some跟any作用一樣
    • in跟=any一樣
//查詢有一次或以上成績及格的學生
from Student s where 60<any(select r.score from s.results r)
  • exists
    • 返回一條或以上記錄則爲true,返回0條記錄則爲false

3.原生SQL查詢

//SQL語句、{s.*}標識一個對象的所有屬性、可以使用佔位符
String sql="select {s.*},{g.*} from Student s join Grade g on g.id=s.grade_id";

//使用createSQLQuery()調用SQL查詢語句,返回SQLQuery類型,繼承Query接口
SQLQuery query=session.createSQLQuery(sql);

//addEntity()可以把返回結果封裝成對象,第一個參數是SQL查詢語句中Student的別名s,第二個參數是需要封裝成的類Student.class
      //addJoin()可以連接查詢的對象封裝成對象,第一個參數是SQL查詢語句中被連接的表的別名g,第二個參數是Student類的grade屬性,是個字符串
query.addEntity("s",Student.class).addJoin("g", "s.grade");

//返回值是一個Object數組集合,數組的第一個元素是Student對象,數組第二個元素是Grade對象
List<Object[]> list = query.list();
for (Object[] objects : list) {
	Student student=(Student) objects[0];
	Grade grade=(Grade)objects[1];
	System.out.println(student.getName()+","+grade.getName());
}		
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章