最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Data MongoDB中實(shí)現(xiàn)自定義級(jí)聯(lián)的方法詳解

 更新時(shí)間:2017年11月13日 11:36:34   作者:WebFuse  
這篇文章主要給大家介紹了關(guān)于Spring Data MongoDB中實(shí)現(xiàn)自定義級(jí)聯(lián)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。

前言

Spring Data MongoDB 項(xiàng)目提供與MongoDB文檔數(shù)據(jù)庫(kù)的集成,Spring與Hibernate集成時(shí),Spring提供了org.springframework.orm.hibernate3.HibernateTemplate實(shí)現(xiàn)了對(duì)數(shù)據(jù)的CRUD操作, Spring Data MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate對(duì)MongoDB的CRUD的操作,包括對(duì)集成的對(duì)象映射文件和POJO之間的CRUD的操作。

在使用Spring Data操作MongoDB中:

  • 在保存一個(gè)實(shí)體的時(shí)候,如果被@DBRef標(biāo)識(shí)的類只傳入Id,保存后返回的結(jié)果并沒(méi)有全部的引用類內(nèi)容,只有Id。
  • 保存實(shí)體,不能保存引用實(shí)體。

例如:我們有一個(gè)實(shí)體Person,有一個(gè)實(shí)體EmailAddress。

@Document(collection = "test_person")
public class Person {
 private String name;
 @DBRef
 private EmailAddress emailAddress;
 ... getter setter 方法
}
@Document(collection = "test_email")
public class EmailAddress {
 @Id
 private String id;
 private String value;
 ... getter setter 方法
}

當(dāng)我們調(diào)用保存方法的時(shí)候:

public Person test() {
 Person person = new Person();
 person.setName("test");
 EmailAddress emailAddress = new EmailAddress();
 emailAddress.setId("5a05108d4dcc5dece03c9e69");
 person.setEmailAddress(emailAddress);
 testRepository.save(person);
 return person;
}

上述的代碼中,返回的person只有id,沒(méi)有emailAddress的其他值。

public Person test() {
 Person person = new Person();
 person.setName("test");
 EmailAddress emailAddress = new EmailAddress();
 emailAddress.setName("afafa");
 person.setEmailAddress(emailAddress);
 testRepository.save(person);
 return person;
}

上述的代碼中,emailAddress不能被保存。

解決

生命周期事件

Spring Data MongoDB中存在一些生命周期事件,如:onBeforeConvert, onBeforeSave, onAfterSave, onAfterLoad and onAfterConvert等。我們可以繼承AbstractMappingEventListener,然后重寫(xiě)這些方法,即可以實(shí)現(xiàn)。

代碼

/**
 * MongoDB級(jí)聯(lián)控制
 * Created by guanzhenxing on 2017/11/9.
 */
public class CascadeControlMongoEventListener extends AbstractMongoEventListener<Object> {
 @Autowired
 private MongoOperations mongoOperations;
 @Override
 public void onAfterSave(AfterSaveEvent<Object> event) {
 super.onAfterSave(event);
 Object source = event.getSource();
 ReflectionUtils.doWithFields(source.getClass(), new CascadeAfterSaveCallback(source, mongoOperations));
 }
 @Override
 public void onBeforeConvert(BeforeConvertEvent<Object> event) {
 super.onBeforeConvert(event);
 Object source = event.getSource();
 ReflectionUtils.doWithFields(source.getClass(), new CascadeBeforeConvertCallback(source, mongoOperations));
 }
}
/**
 * 級(jí)聯(lián)控制的回調(diào)
 * Created by guanzhenxing on 2017/11/10.
 */
public class CascadeAfterSaveCallback implements ReflectionUtils.FieldCallback {
 private Object source;
 private MongoOperations mongoOperations;
 public CascadeAfterSaveCallback(final Object source, final MongoOperations mongoOperations) {
  this.source = source;
  this.mongoOperations = mongoOperations;
 }
 @Override
 public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
  ReflectionUtils.makeAccessible(field);
  if (field.isAnnotationPresent(DBRef.class)) {
   final Object fieldValue = field.get(source); //獲得值
   if (fieldValue != null) {
    doCascadeLoad(field);
   }
  }
 }
 /**
  * 級(jí)聯(lián)查詢
  *
  * @param field
  */
 private void doCascadeLoad(Field field) throws IllegalAccessException {
  Object fieldValue = field.get(source);
  List<Field> idFields = ReflectionUtil.getAnnotationField(fieldValue, Id.class); //該方法是為了獲得所有的被@Id注解的屬性
  if (idFields.size() == 1) { //只處理一個(gè)Id
   Object idValue = ReflectionUtil.getFieldValue(fieldValue, idFields.get(0).getName());
   Object value = mongoOperations.findById(idValue, fieldValue.getClass()); //查詢獲得值
   ReflectionUtil.setFieldValue(source, field.getName(), value);
  }
 }
}
public class CascadeBeforeConvertCallback implements ReflectionUtils.FieldCallback {
 private Object source;
 private MongoOperations mongoOperations;
 public CascadeBeforeConvertCallback(Object source, MongoOperations mongoOperations) {
  this.source = source;
  this.mongoOperations = mongoOperations;
 }
 @Override
 public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
  ReflectionUtils.makeAccessible(field);
  if (field.isAnnotationPresent(DBRef.class)) {
   final Object fieldValue = field.get(source); //獲得值
   if (fieldValue != null) {
    doCascadeSave(field);
   }
  }
 }
 /**
  * 級(jí)聯(lián)保存
  *
  * @param field
  * @throws IllegalAccessException
  */
 private void doCascadeSave(Field field) throws IllegalAccessException {
  if (field.isAnnotationPresent(CascadeSave.class)) { //如果有標(biāo)識(shí)@CascadeSave注解
   Object fieldValue = field.get(source);
   List<Field> idFields = ReflectionUtil.getAnnotationField(fieldValue, Id.class);
   if (idFields.size() == 1) {
    mongoOperations.save(fieldValue);
   }
  }
 }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CascadeSave {
}
@Configuration
public class MongoConfig {
 @Bean
 public CascadeControlMongoEventListener userCascadingMongoEventListener() {
  return new CascadeControlMongoEventListener();
 }
}

以上是核心代碼。至此,我們就可以解決上述的問(wèn)題了。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

參考:http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb

相關(guān)文章

  • Mybatis的核心配置文件使用方法

    Mybatis的核心配置文件使用方法

    Mybatis的核心配置文件有兩個(gè),一個(gè)是全局配置文件,它包含了會(huì)深深影響Mybatis行為的設(shè)置和屬性信息;一個(gè)是映射文件,它很簡(jiǎn)單,讓用戶能更專注于SQL代碼,本文主要介紹了Mybatis的核心配置文件使用方法,感興趣的可以了解一下
    2023-11-11
  • 詳解Spring Boot中初始化資源的幾種方式

    詳解Spring Boot中初始化資源的幾種方式

    這篇文章主要介紹了詳解Spring Boot中初始化資源的幾種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • java實(shí)現(xiàn)文件和base64相互轉(zhuǎn)換

    java實(shí)現(xiàn)文件和base64相互轉(zhuǎn)換

    這篇文章主要為大家詳細(xì)介紹了java如何實(shí)現(xiàn)文件和base64相互轉(zhuǎn)換,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • Springboot整合Redis的詳細(xì)教程分享

    Springboot整合Redis的詳細(xì)教程分享

    這篇文章主要為大家詳細(xì)介紹了如何利用SpringBoot整合Redis,文中的示例代碼講解詳細(xì),具有很好的參考價(jià)值,希望對(duì)大家有所幫助
    2022-08-08
  • MyBatis快速入門之環(huán)境搭建和單表映射

    MyBatis快速入門之環(huán)境搭建和單表映射

    一說(shuō)起對(duì)象關(guān)系映射框架,大家第一時(shí)間想到的肯定是Hibernate。Hibernate作為一個(gè)著名的框架,功能十分強(qiáng)大。但是由于Hibernate如此強(qiáng)大的功能,導(dǎo)致了它的缺點(diǎn)。好吧,不多說(shuō)了,具體詳情大家通過(guò)本文一起學(xué)習(xí)吧
    2017-03-03
  • Java(SpringBoot)項(xiàng)目打包(構(gòu)建)成Docker鏡像的幾種常見(jiàn)方式

    Java(SpringBoot)項(xiàng)目打包(構(gòu)建)成Docker鏡像的幾種常見(jiàn)方式

    在對(duì)Spring Boot應(yīng)用程序進(jìn)行Docker化時(shí),為應(yīng)用程序選擇正確的基礎(chǔ)鏡像非常重要,下面這篇文章主要給大家介紹了關(guān)于Java(SpringBoot)項(xiàng)目打包(構(gòu)建)成Docker鏡像的幾種常見(jiàn)方式,需要的朋友可以參考下
    2023-12-12
  • 如何在java中使用SFTP協(xié)議安全的傳輸文件

    如何在java中使用SFTP協(xié)議安全的傳輸文件

    這篇文章主要介紹了如何在java中使用SFTP協(xié)議安全的傳輸文件,幫助大家更好的理解和使用JSch,感興趣的朋友可以了解下
    2020-10-10
  • JDBC 與 MyBatis從基礎(chǔ)到實(shí)踐

    JDBC 與 MyBatis從基礎(chǔ)到實(shí)踐

    JDBC(Java Database Connectivity)即 Java 數(shù)據(jù)庫(kù)連接,是 Java 語(yǔ)言中用來(lái)規(guī)范客戶端程序如何來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的應(yīng)用程序接口,提供了諸如查詢和更新數(shù)據(jù)庫(kù)中數(shù)據(jù)的方法,這篇文章主要介紹了JDBC 與 MyBatis從基礎(chǔ)到實(shí)踐,需要的朋友可以參考下
    2025-04-04
  • Java 隨機(jī)取字符串的工具類

    Java 隨機(jī)取字符串的工具類

    隨機(jī)數(shù)在實(shí)際中使用很廣泛,比如要隨即生成一個(gè)固定長(zhǎng)度的字符串、數(shù)字?;蛘唠S即生成一個(gè)不定長(zhǎng)度的數(shù)字、或者進(jìn)行一個(gè)模擬的隨機(jī)選擇等等。Java提供了最基本的工具,可以幫助開(kāi)發(fā)者來(lái)實(shí)現(xiàn)這一切
    2014-01-01
  • 基于jdk1.8的Java源碼詳解 Integer

    基于jdk1.8的Java源碼詳解 Integer

    這篇文章主要介紹了基于jdk1.8的Java源碼詳解 Integer,Integer是int的Warpper類,是面向?qū)ο蟮募碠OP的對(duì)象類型,,需要的朋友可以參考下
    2019-06-06

最新評(píng)論

临西县| 大埔区| 葵青区| 遵化市| 浑源县| 西乌珠穆沁旗| 泸水县| 安庆市| 庄河市| 清徐县| 邻水| 南通市| 板桥市| 鄂托克前旗| 太仆寺旗| 江门市| 勐海县| 九龙城区| 高平市| 宁都县| 浏阳市| 佛坪县| 溧水县| 桐乡市| 紫金县| 武陟县| 安丘市| 沙河市| 内丘县| 新宾| 吴忠市| 吴江市| 苗栗县| 吴川市| 新余市| 凤山市| 阳新县| 灌云县| 凤冈县| 姜堰市| 格尔木市|