第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁(yè) 慕課教程 Hibernate 入門教程 Hibernate 入門教程 Hibernate 自動(dòng)生成 SQL 語(yǔ)句

Hibernate 如何自動(dòng)生成 SQL 語(yǔ)句

1. 前言

本節(jié)課和大家一起聊聊 Hibernate 是如何自動(dòng)生成 SQL 語(yǔ)句的。通過(guò)本節(jié)課程的學(xué)習(xí),你將了解到:

  • 反射在框架中的重要性;
  • 元數(shù)據(jù)描述對(duì) Hibernate 的重要性。

2. 理想狀態(tài)

Hibernate 是全自動(dòng)的 JDBC 框架,能自動(dòng)構(gòu)建 SQL 語(yǔ)句、能自動(dòng)封裝數(shù)據(jù)。

做為開(kāi)發(fā)者,不能在使用的便利性中迷失自己,應(yīng)該要學(xué)會(huì)多思考:Hibernate 是如何自動(dòng)構(gòu)建 SQL 語(yǔ)句的?

答案本身很簡(jiǎn)單:使用反射機(jī)制。

先來(lái)一個(gè)最理想化的構(gòu)建實(shí)例:假設(shè)實(shí)體類名和表名相同、實(shí)體類中的屬性和表中的字段命名相同。

編寫自己的 Session 類:

public class MySession<T> {

	public T  get(Class clz,Serializable id) {	
		String sql=createSql(clz,id);
		//其它操作……	
		return null;
	}
	private String createSql(Class clz, Serializable id) {		
		return null;
	}
}

get()方法接受 2 個(gè)參數(shù),這 2 個(gè)參數(shù)便是構(gòu)建 SQL 的核心。傳遞給內(nèi)部的 createSql()方法用來(lái)進(jìn)行 SQL 語(yǔ)句構(gòu)造。

關(guān)注 createSql() 方法中的代碼:

  1. 聲明變量;
 // SQL 查詢模板
 String sql = "select {0} from {1} where {2}= {3}";
 // 表名
 String tableName = null;
 // 字段列表
 StringBuffer selFields = new StringBuffer();
 // 主鍵字段
 String keyField = null;
  1. 看來(lái)就是要為 SQL 查詢模板中的占位符找到具體值。因?yàn)轭惷捅砻嗤?,所以表名很容易找到?/li>
 // 類名就是表名
 tableName = clz.getSimpleName();
  1. 因?yàn)閷傩悦c表中的字段名相同,所以表的字段信息也很容易找到;
 // 屬性名就是查詢的字段名,找到屬性等于找到字段信息
 Field[] fields = clz.getDeclaredFields();
  1. 這里有一個(gè)較麻煩的地方,怎么找到主鍵字段,這里假設(shè)第一個(gè)屬性對(duì)應(yīng)的是主鍵字段;
 Field[] fields = clz.getDeclaredFields();
 for (int i = 0; i < fields.length; i++) {
 	if (i == 0)
 		keyField = fields[i].getName();
 		selFields.append(fields[i].getName()).append(",");
 	}
 // 刪除最后一個(gè),
 selFields.deleteCharAt(selFields.length() - 1);
  1. 最后構(gòu)建 SQL ;
 sql = MessageFormat.format(sql, new Object[] {selFields,tableName,keyField,id});

測(cè)試輸出大家自己去完成。

3. 非理想狀態(tài)

前面假設(shè)了一種特別理想的狀態(tài)。但是,現(xiàn)實(shí)總比理想殘酷。

很多情況下,表名與類名、屬性名和字段名都不同名,主鍵字段對(duì)應(yīng)的屬性也不一定放在第一個(gè)。

這種情形下,又如何構(gòu)建 SQL 。此時(shí),注解就起到了作用。大家還記得常用的注解嗎?

  • @Table;
  • @Id;
  • @Column。

有了這 3 個(gè)注解,查找表名、字段信息、主鍵字段就不需要再靠強(qiáng)制性的代碼規(guī)范了。

重構(gòu) createSql() 方法中的代碼。

本質(zhì)上沒(méi)有發(fā)生改變,還是為 SQL 查詢模板中的占位符找到所有具體值。

  1. 找到表名。其本思路是,如果有 @Table 注解,表名就是注解提供的名字,如果沒(méi)有注解,則表名與類名相同;
 // 查找類上面是否有 @Table 注解
 Table tableAnnotaion= (Table) clz.getAnnotation(Table.class);
 if(tableAnnotaion==null) 
  //則認(rèn)為類名與表名相同
 	tableName = clz.getSimpleName();
 else 
 	//表名為注解中提供的值
 	tableName=tableAnnotaion.name();
  1. 找到表的所有字段信息。為了簡(jiǎn)化代碼,假設(shè) @Id 或 @Column 注解直接標(biāo)注在屬性上面。即使標(biāo)注在 get()方法上面也不難;
 // 屬性信息
 Field[] fields = clz.getDeclaredFields();
 //是否存在 @Id 注解
 boolean ishasIdAnnotation = false;
 Id idAnnotation=null;
 Column columnAnnotation = null;
 String fieldName = null;
 for (Field field : fields) {
 	// @Id 注解
 	idAnnotation = field.getAnnotation(Id.class);
 	// @ Column 注解
     columnAnnotation = field.getAnnotation(Column.class);
 	if (idAnnotation != null) {
 		keyField = field.getName();
 		ishasIdAnnotation = true;
 	}
 	if (columnAnnotation == null)
          // 有 @Column 注解則從注解中取值
 		fieldName = field.getName();
 	else
          //沒(méi)有 @Column 注解則和屬性表相同
 		fieldName = columnAnnotation.name();
 	selFields.append(fieldName).append(",");
 }
 if (!ishasIdAnnotation) {
 	throw new Exception("@Id 注解是必須的!");
 }
 // 刪除最后一個(gè),
 selFields.deleteCharAt(selFields.length() - 1);
  1. 構(gòu)建 SQL 語(yǔ)句。
 sql = MessageFormat.format(sql, new Object[] { selFields, tableName, keyField, id });

測(cè)試 createSql()方法,在控制臺(tái)可看到通過(guò)反射自動(dòng)構(gòu)建的 SQL 語(yǔ)句:

select stuId,stuName,stuSex,stuPassword from student where stuId= 1

測(cè)試結(jié)果需要以你自己的實(shí)體類和表做參考。

4. 小結(jié)

本課程給出了 2 種情形下構(gòu)建 SQL 語(yǔ)句的實(shí)現(xiàn)。

一種對(duì)編碼規(guī)范要求非常嚴(yán)格,因?yàn)榫幋a規(guī)范有很多人為因素,很難保證類結(jié)構(gòu)和表結(jié)構(gòu)如同鏡像,不出現(xiàn)差異性。顯然,在這種嚴(yán)格的編碼規(guī)范下,構(gòu)建 SQL 的性能消耗是最低的,所以,一入職場(chǎng),第一堂課就是培訓(xùn)編碼規(guī)范性。

第二種情形應(yīng)該是一種常態(tài),所以需要使用注解的方式標(biāo)識(shí)差異性,當(dāng)然,反射時(shí)付出的性能代價(jià)會(huì)增加。

本課程沒(méi)有討論構(gòu)建多表查詢的實(shí)現(xiàn),有了這些基礎(chǔ),相信都將不會(huì)很難。