激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Data MongoDB中實現自定義級聯的方法詳解

Spring Data MongoDB中實現自定義級聯的方法詳解

2021-02-03 11:59WebFuse Java教程

這篇文章主要給大家介紹了關于Spring Data MongoDB中實現自定義級聯的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

前言

Spring Data MongoDB 項目提供與MongoDB文檔數據庫的集成,Spring與Hibernate集成時,Spring提供了org.springframework.orm.hibernate3.HibernateTemplate實現了對數據的CRUD操作, Spring Data MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate對MongoDB的CRUD的操作,包括對集成的對象映射文件和POJO之間的CRUD的操作。

在使用Spring Data操作MongoDB中:

  • 在保存一個實體的時候,如果被@DBRef標識的類只傳入Id,保存后返回的結果并沒有全部的引用類內容,只有Id。
  • 保存實體,不能保存引用實體。

例如:我們有一個實體Person,有一個實體EmailAddress。

?
1
2
3
4
5
6
7
@Document(collection = "test_person")
public class Person {
 private String name;
 @DBRef
 private EmailAddress emailAddress;
 ... getter setter 方法
}
?
1
2
3
4
5
6
7
@Document(collection = "test_email")
public class EmailAddress {
 @Id
 private String id;
 private String value;
 ... getter setter 方法
}

當我們調用保存方法的時候:

?
1
2
3
4
5
6
7
8
9
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,沒有emailAddress的其他值。

?
1
2
3
4
5
6
7
8
9
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,然后重寫這些方法,即可以實現。

代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * MongoDB級聯控制
 * 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));
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * 級聯控制的回調
 * 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);
   }
  }
 }
 /**
  * 級聯查詢
  *
  * @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) { //只處理一個Id
   Object idValue = ReflectionUtil.getFieldValue(fieldValue, idFields.get(0).getName());
   Object value = mongoOperations.findById(idValue, fieldValue.getClass()); //查詢獲得值
   ReflectionUtil.setFieldValue(source, field.getName(), value);
  }
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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);
   }
  }
 }
 /**
  * 級聯保存
  *
  * @param field
  * @throws IllegalAccessException
  */
 private void doCascadeSave(Field field) throws IllegalAccessException {
  if (field.isAnnotationPresent(CascadeSave.class)) { //如果有標識@CascadeSave注解
   Object fieldValue = field.get(source);
   List<Field> idFields = ReflectionUtil.getAnnotationField(fieldValue, Id.class);
   if (idFields.size() == 1) {
    mongoOperations.save(fieldValue);
   }
  }
 }
}
?
1
2
3
4
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CascadeSave {
}
?
1
2
3
4
5
6
7
@Configuration
public class MongoConfig {
 @Bean
 public CascadeControlMongoEventListener userCascadingMongoEventListener() {
  return new CascadeControlMongoEventListener();
 }
}

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

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

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

原文鏈接:http://webfuse.cn/2017/11/10/Spring%20Data%20MongoDB中的自定義級聯

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 久久亚洲成人网 | 午夜精品久久久久久久96蜜桃 | 日韩精品中文字幕在线观看 | 久久久久久久久久久高潮一区二区 | 九九热视频这里只有精品 | 蜜桃一本色道久久综合亚洲精品冫 | 色屁屁xxxxⅹ免费视频 | 日韩一级片免费 | 最新日韩在线观看视频 | 成年人高清视频在线观看 | 精品一区二区三区免费爱 | 免费观看黄色一级视频 | 亚洲免费高清 | 久久久精品视频免费 | 19禁国产精品福利视频 | 久久久入口| 成人在线视频一区 | 中文字幕一区在线观看视频 | 看a级毛片| 国产黄色毛片 | 日韩美女电影 | 一本免费视频 | 久草最新网址 | 国产亚洲欧美一区久久久在 | 天天草夜夜 | 香蕉黄色网 | 天天透天天狠天天爱综合97 | 久久精品视频69 | 性大片1000免费看 | 中文字幕欧美一区二区三区 | 国产精品久久久久久久久久久久午夜 | 黄色免费播放网站 | 国产美女爽到喷白浆的 | 欧美日韩亚州综合 | 黄色美女免费 | 黄色免费av | 26uuu成人人网图片 | 日本中文字幕电影在线观看 | 精品国产一区二区三区成人影院 | 午夜视频观看 | 色婷婷久久久亚洲一区二区三区 |