久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

傳智播客-jpa與hibernate(2)-CRUD和關(guān)聯(lián)關(guān)系

 蝸牛手 2011-05-23

傳智播客-jpa與hibernate(2)-CRUD和關(guān)聯(lián)關(guān)系 收藏

(傳智播客ms很多關(guān)于“數(shù)據(jù)”的課程都是徐培成老師講的,,hibernate,、jpa,、后面還有個(gè)數(shù)據(jù)采集課程,,當(dāng)然還有講解其他課 程,,贊一下,,課講得確實(shí)很好,尤其是課上沒(méi)有半句廢話--對(duì)于號(hào)稱筆記狂的本人而言恨不得每個(gè)字都記下來(lái),,而且看得出確實(shí)經(jīng)驗(yàn)豐富,。當(dāng)然,本人博客里提到 的其他老師也都很好~最最起碼的,,能看出大家都很敬業(yè),。本人一直都認(rèn)為,做事最重要的就是看態(tài)度,。常言道:能力可以培養(yǎng),,態(tài)度難以改變 >_<come on!)

CRUD
1,、下面代碼中,,注釋中的“===>”左邊是純jpa規(guī)范的表示,右邊是hibernate表示,。
2,、jpa與hibernate在CRUD中最顯著的區(qū)別在于“U”--更新,即jpa里的merge()方法,,相當(dāng)于hibernate的update(),。
(1)更新是將游離狀態(tài)的數(shù)據(jù)對(duì)象的引用與緩存關(guān)聯(lián),使成持久態(tài),。所謂在緩存里添加一個(gè)對(duì)象,,其實(shí)添加的只是引用。
(2) 只調(diào)用merge()方法不會(huì)有update語(yǔ)句打印,,因?yàn)閙erge()方法是在緩存里新建了一個(gè)對(duì)象的拷貝,,并返回這個(gè)拷貝,merge()操作的也 是這個(gè)拷貝,,所以下面的代碼中,,c.setName("jerry2")其實(shí)并沒(méi)有更新,cc.setName("jerry3")才真正被更新了,。
3,、 EntityManager/Session的CRUD操作只是最基本最簡(jiǎn)單的操作,實(shí)際業(yè)務(wù)邏輯中更多用的是 EntityManager.createQuery()--針對(duì)相應(yīng)業(yè)務(wù)邏輯創(chuàng)建sql語(yǔ)句,,還有 EntityManager.createNamedQuery()/Session.getNamedQuery()--這樣的話查詢語(yǔ)句可以做成配置 信息,,方便統(tǒng)一修改,,而hibernate自身還有一個(gè)Criteria對(duì)象,Session.createCriteria()可以創(chuàng)建更體現(xiàn)00P思 想的sql,。
public class TestCrud {

 private static EntityManagerFactory emf = null;
 
 @BeforeClass
 public static void iniEmf(){
  try {
   emf = Persistence.createEntityManagerFactory("jpa");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 @Test
 public void findCustomer(){
  //em ===> session
  EntityManager em = emf.createEntityManager();
  EntityTransaction tx = em.getTransaction();
  tx.begin();
  //em.find() ===> session.get(), 不能產(chǎn)生代理
  CustomerBackup c = em.find(CustomerBackup.class, 4);
  System.out.println(c); //如果c不存在,,不報(bào)錯(cuò),直接返回null
  tx.commit();
  em.close();
 }
 
 @Test
 public void getReference(){
  EntityManager em = emf.createEntityManager();
  EntityTransaction tx = em.getTransaction();
  tx.begin();
  //em.getReference() ===> session.load()
  CustomerBackup c = em.getReference(CustomerBackup.class, 4); //返回的是代理對(duì)象
  System.out.println(c); //如果c不存在,,會(huì)報(bào)找不到實(shí)體c的錯(cuò)誤
  tx.commit();
  em.close();
 }
 
 @Test
 public void updateCustomer(){
  EntityManager em = emf.createEntityManager();
  EntityTransaction tx = em.getTransaction();
  tx.begin();
  //em.find() ===> session.load()
  CustomerBackup c = em.find(CustomerBackup.class, 1); //持久化數(shù)據(jù)的更新,,緩存里有快照,即副本
  c.setName("jay");
  tx.commit();
  em.close();
 }
 
 @Test
 public void updateCustomer2(){
  EntityManager em = emf.createEntityManager();
  EntityTransaction tx = em.getTransaction();
  tx.begin();
  //em.find() ===> session.load()
  CustomerBackup c = em.find(CustomerBackup.class, 1);
  tx.commit();
  em.close();
  
  em = emf.createEntityManager();
  tx = em.getTransaction();
  tx.begin();
  //em.merge()合并 ===> session.update()
  CustomerBackup cc = em.merge(c); //將游離狀態(tài)對(duì)象的引用和緩存關(guān)聯(lián),,使其變?yōu)槌志没癄顟B(tài)
  //這一句放em.merge(c)前后都無(wú)所謂,因?yàn)閏這時(shí)還在緩存里,,而merge關(guān)聯(lián)的只是引用
  c.setName("jerry2");
  //merge方法實(shí)際上是新建一個(gè)對(duì)象的拷貝,,然后對(duì)這個(gè)拷貝操作,所以對(duì)merge返回的對(duì)象拷貝進(jìn)行操作才能真正執(zhí)行更新
  cc.setName("jerry3"); //這句才真正被更新了
  tx.commit();
  em.close();
 }
 
 @Test
 public void removeCustomer(){
  EntityManager em = emf.createEntityManager();
  EntityTransaction tx = em.getTransaction();
  tx.begin();
  CustomerBackup c = em.find(CustomerBackup.class, 1);
  //em.remove(c) ===> session.delete(c)
  em.remove(c);
  tx.commit();
  em.close();
 }
 
 @Test
 public void findAllCustomer(){
  EntityManager em = emf.createEntityManager();
  EntityTransaction tx = em.getTransaction();
  tx.begin();
  //jpql
  //只寫(xiě)from Customer c也可以,,但是這種語(yǔ)法(可能)只有hibernate才支持,,為了提高程序可移植性,應(yīng)當(dāng)完整寫(xiě)明
  Query q = em.createQuery("select c from CustomerBackup c");
  //q.getResultList()(jpa) ===> q.list()(hibernate)
  q.getResultList();
  tx.commit(); //這一句才在真正執(zhí)行了查詢,,前面只是構(gòu)建生成sql語(yǔ)句
  em.close();
 }
}

4,、jpa里的@Embedded注釋相當(dāng)于hibernate里的component元素,是一個(gè)實(shí)體類的實(shí)體類型屬性(相對(duì)于值類型屬性而言,,從java的角度來(lái)看,,就是一個(gè)類與另一個(gè)類的組成關(guān)系)
(1)屬性重寫(xiě):如果實(shí)體類(例如Customer類)里有多個(gè)同一實(shí)體類型(例如Address類)的屬性(例如homeAddress,comAddress),,那么原有實(shí)體類型里面的屬性(相對(duì)于表的字段)需要重寫(xiě),。
(2) 空指針判斷:以(1)為例,如果數(shù)據(jù)庫(kù)里homeAddress或comAddress相關(guān)內(nèi)容字段全為null,,那么jpa直接將查找的 customer對(duì)象的homeAddress或comAddress屬性值置為null,,而不會(huì)為這個(gè)屬性new一個(gè)新對(duì)象(空間),所以更新該屬性數(shù) 據(jù)時(shí),,應(yīng)該事先做一下空指針判斷,,并將指針移位,以增強(qiáng)程序的健壯性(當(dāng)然,,如果只要有一個(gè)字段值不為null,,jpa就會(huì)new個(gè)新對(duì)象了~~~)。
@Test
public void findCustomer(){
 EntityManager em = emf.createEntityManager();
 EntityTransaction tx = em.getTransaction();
 tx.begin();
 Customer c = em.find(Customer.class, 1);
 Address ca = c.getComAddress();
 if(ca == null){
//空指針判斷
  ca = new Address();
  c.setComAddress(ca);
//c原來(lái)指向null的 指針 轉(zhuǎn)移到ca對(duì)象
 }
 tx.commit();
 em.close();
}

關(guān)聯(lián)關(guān)系
(級(jí)聯(lián)--指數(shù)據(jù)信息傳播的支持程度,,即使只CUD操作一個(gè)實(shí)體,,相關(guān)的也會(huì)CUD。)
1,、多對(duì)一和一對(duì)多
(1)@ManyToOne一方(例如Order),,不加@JoinColumn的話,,hibernate會(huì)自動(dòng)添加一個(gè)連接字段,字段名為“many類中one類型的屬性名_對(duì)端主鍵字段值”,。
(2)查詢order的話打印出的sql語(yǔ)句為左外連接:Order left outer join Customer,。
(3)@OneToMany一方,jpa默認(rèn)采用中間表來(lái)實(shí)現(xiàn),,所以通常情況應(yīng)該指定一個(gè)連接列,,但是因?yàn)樵趍any一方中不用維護(hù)關(guān)聯(lián)關(guān)系,一般由one一方維護(hù),,所以應(yīng)該使用@OneToMany(MappedBy="customer"),。
(4)下列代碼運(yùn)行后,order表的業(yè)務(wù)數(shù)據(jù)可以插入,,但是負(fù)責(zé)關(guān)聯(lián)關(guān)系的customer_id外鍵值為null,,因?yàn)閏ustomer_id的值應(yīng)該由有關(guān)系控制權(quán)的customer來(lái)指派。
//order.setCustomer(customer);
customer.getOrders().add(order);
entityManager.persist(customer);
//entityManager.persist(order);

2,、一對(duì)一
(1)外鍵關(guān)聯(lián)
public class Customer{
 @OneToOne
 @JoinColumn(name="aid",referencedColumnName="id") //"id"是指Address的id屬性值
 private Address addr;
 ......
}
public class Address{
 @OneToOne(MappedBy="aid",unique=true) //加了unique=true才能保證一對(duì)一關(guān)聯(lián)的雙向唯一性
 private Customer customer;
 ......
}
(2)主鍵關(guān)聯(lián)
主鍵關(guān)聯(lián)中必有一方為自然主鍵,,保存前必須手動(dòng)為其賦值。(具體如何使用請(qǐng)參見(jiàn)相關(guān)文檔,,代碼就不貼了,,不過(guò)官方文檔中不推薦這種做法)

3、多對(duì)多
一般是建一個(gè)中間表關(guān)聯(lián)雙方,,表內(nèi)字段為雙方主鍵字段,。其實(shí)也可以看成多對(duì)一和一對(duì)多的復(fù)合,這個(gè)就不多寫(xiě)了,。,。(手又酸了呀。,。,。)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多