最近很多小伙伴都在问使用SpringDataMongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓
最近很多小伙伴都在问使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展java – Spring mongorepository save抛出重复键异常、java – Spring数据mongoRepository查询排序、Java操作MongoDB采用MongoRepository仓库进行条件查询、MongDB.Net工具库MongoRepository使用方法详解等相关知识,下面开始了哦!
本文目录一览:- 使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?
- java – Spring mongorepository save抛出重复键异常
- java – Spring数据mongoRepository查询排序
- Java操作MongoDB采用MongoRepository仓库进行条件查询
- MongDB.Net工具库MongoRepository使用方法详解
使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?
在Spring Data MongoDB中使用反应式编程模型时,可以执行如下事务:
Mono<DeleteResult> result = template.inTransaction() .execute(action -> action.remove(query(where("id").is("step-1")), Step.class));
但是Spring Data MongoDB也支持“反应性存储库”,例如:
public interface PersonRepository extends ReactiveMongoRepository<Person, String> Flux<Person> findByLocationNear(Point location, Distance distance);}
和
public interface CarRepository extends ReactiveMongoRepository<Car, String> Flux<Car> findByYear(int year);}
我的问题是,假设您拥有,您是否ReactiveMongoRepository
可以以某种方式利用MongoDB事务,例如将aPerson
和插入Car
同一事务中(使用PersonRepository
和CarRepository
大小写)?如果是这样,您该怎么做?
答案1
小编典典我也一直在努力寻找Mongo DB和Spring Boot的Reactive风格的 事务 支持解决方案
但是幸运的是我自己想通了。尽管Google提供的一些功能也没有帮助,但这些都是无反应的。
您需要使用 ReactiveMongoTransactionManager 沿 ReactiveMongoDatabaseFactory ,大部分的末尾的详细信息,也分享代码回购为同
为了使mongo数据库支持事务,我们需要确保数据库应以副本方式运行 。
为什么我们需要那个? 因为否则您会得到一些这样的错误:
此客户端连接到的MongoDB集群不支持会话
相同的说明如下:
- 使用docker-compose.yml运行基于docker-compose的mongo数据库服务器,如下所示:-
version: "3"services: mongo: hostname: mongo container_name: localmongo_docker image: mongo expose: - 27017 ports: - 27017:27017 restart: always entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs0" ] volumes: - ./mongodata:/data/db # need to create a docker volume named as mongodata first
- 映像显示后,执行命令(此处 localmongo_docker 是容器的名称):-
docker exec -it localmongo_docker mongo
- 复制并粘贴下面的命令并执行
rs.initiate( { _id : ''rs0'', members: [ { _id : 0, host : "mongo:27017" } ] } )
- 然后通过输入 exit* 退出执行 *
重要 -代码仓库可以在我的github上找到-https: //github.com/krnbr/mongo-spring-boot-
template
该代码的重要说明如下:-
- **config 包中的 MongoConfiguration 类是使事务正常运行的重要部分,链接到配置类在这里
- 主要部分是 豆
@BeanReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {return new ReactiveMongoTransactionManager(dbFactory);}
- 为了检查代码的事务性需求的工作情况,您可以在此处查看服务包中的UserService类
如果链接对某人无效,请共享代码:-
配置和Bean内部
@Configurationpublic class MongoConfiguration extends AbstractMongoClientConfiguration { @Autowired private MongoProperties mongoProperties; @Bean ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) { return new ReactiveMongoTransactionManager(dbFactory); } @Override protected String getDatabaseName() { return mongoProperties.getDatabase(); } @Override public MongoClient mongoClient() { return MongoClients.create(mongoProperties.getUri()); }}
application.properties (与mongo db有关)
spring.data.mongodb.database=mongospring.data.mongodb.uri=mongodb://localhost:27017/mongo?replicaSet=rs0
文件类别
角色类别
@Getter@Setter@Accessors(chain = true)@Document(collection = "roles")@TypeAlias("role")public class Role implements Persistable<String> { @Id private String id; @Field("role_name") @Indexed(unique = true) private String role; @CreatedDate private ZonedDateTime created; @LastModifiedDate private ZonedDateTime updated; private Boolean deleted; private Boolean enabled; @Override @JsonIgnore public boolean isNew() { if(getCreated() == null) return true; else return false; }}
用户类别
@Getter@Setter@Accessors(chain = true)@Document(collection = "users")@JsonInclude(JsonInclude.Include.NON_NULL)@TypeAlias("user")public class User implements Persistable<String> { @Id() private String id; @Field("username") @Indexed(unique = true) @JsonProperty("username") private String userName; @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String password; @CreatedDate private ZonedDateTime created; @LastModifiedDate private ZonedDateTime updated; private Boolean deleted; private Boolean enabled; @DBRef(lazy = true) @JsonProperty("roles") private List<Role> roles = new ArrayList(); @Override @JsonIgnore public boolean isNew() { if(getCreated() == null) return true; else return false; }}
UserProfile类别
@Getter@Setter@Accessors(chain = true)@Document(collection = "user_profiles")@JsonInclude(JsonInclude.Include.NON_NULL)@TypeAlias("user_profile")public class UserProfile implements Persistable<String> { @Id private String id; @Indexed(unique = true) private String mobile; @Indexed(unique = true) private String email; private String address; private String firstName; private String lastName; @DBRef private User user; @CreatedDate private ZonedDateTime created; @LastModifiedDate private ZonedDateTime updated; private Boolean deleted; private Boolean enabled; @Override @JsonIgnore public boolean isNew() { if(getCreated() == null) return true; else return false; }}
ReactiveMongoRepository接口
角色库
public interface RoleRepository extends ReactiveMongoRepository<Role, String> { Mono<Role> findByRole(String role); Flux<Role> findAllByRoleIn(List<String> roles);}
用户资料库
public interface UserRepository extends ReactiveMongoRepository<User, String> { Mono<User> findByUserName(String userName);}
UserProfileRepository
public interface UserProfileRepository extends ReactiveMongoRepository<UserProfile, String> {}
用户服务类 需要在这里创建自己的RuntimeException类,这里是AppRuntimeException类,我一直在使用
@Slf4j@Servicepublic class UserService { @Autowired private RoleRepository roleRepository; @Autowired private UserRepository userRepository; @Autowired private UserProfileRepository userProfileRepository; @Transactional public Mono<UserProfile> saveUserAndItsProfile(final UserRequest userRequest) { Mono<Role> roleMono = roleRepository.findByRole("USER"); Mono<User> userMono = roleMono.flatMap(r -> { User user = new User() .setUserName(userRequest.getUsername()) .setPassword(userRequest.getPassword()); user.setRoles(Arrays.asList(r)); return userRepository.save(user); }).onErrorResume(ex -> { log.error(ex.getMessage()); if(ex instanceof DuplicateKeyException) { String errorMessage = "The user with the username ''"+userRequest.getUsername()+"'' already exists"; log.error(errorMessage); return Mono.error(new AppRuntimeException(errorMessage, ErrorCodes.CONFLICT, ex)); } return Mono.error(new AppRuntimeException(ex.getMessage(), ErrorCodes.INTERNAL_SERVER_ERROR, ex)); }); Mono<UserProfile> userProfileMono = userMono.flatMap(u -> { UserProfile userProfile = new UserProfile() .setAddress(userRequest.getAddress()) .setEmail(userRequest.getEmail()) .setMobile(userRequest.getMobile()) .setUser(u); return userProfileRepository.save(userProfile); }).onErrorResume(ex -> { log.error(ex.getMessage()); if(ex instanceof DuplicateKeyException) { String errorMessage = "The user with the profile mobile''"+userRequest.getMobile()+"'' and/or - email ''"+userRequest.getEmail()+"'' already exists"; log.error(errorMessage); return Mono.error(new AppRuntimeException(errorMessage, ErrorCodes.CONFLICT, ex)); } return Mono.error(new AppRuntimeException(ex.getMessage(), ErrorCodes.INTERNAL_SERVER_ERROR, ex)); }); return userProfileMono; }}
控制器和模型类
UserRequest 模型类别
@Getter@Setter@Accessors(chain = true)@Slf4j@JsonInclude(JsonInclude.Include.NON_NULL)public class UserRequest { private String username; private String password; private String mobile; private String email; private String address; private String firstName; private String lastName;}
UserProfileApisController 类
@Slf4j@RestController@RequestMapping("/apis/user/profile")public class UserProfileApisController { @Autowired private UserService userService; @PostMapping public Mono<UserProfile> saveUserProfile(final @RequestBody UserRequest userRequest) { return userService.saveUserAndItsProfile(userRequest); }}
java – Spring mongorepository save抛出重复键异常
一点代码:
// Succeeds Datatype sut = mongoRepository.findOne("569eac0dd4c623dc65508679"); // Fails with duplicate key. mongoRepository.save(sut);
为什么?重复上面的其他类的对象,他们工作.我怎么能麻烦拍这个呢?我不知道如何分解并解决问题.
谢谢
错误:
27906 [http-bio-8080-exec-3] 2016-05-02 13:00:26,304 DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [ public gov.nist.healthcare.tools.hl7.v2.igamt.lite.web.DatatypeSaveResponse gov.nist.healthcare.tools.hl7.v2.igamt.lite.web.controller.DatatypeController.save( gov.nist.healthcare.tools.hl7.v2.igamt.lite.domain.Datatype) throws gov.nist.healthcare.tools.hl7.v2.igamt.lite.web.exception.DatatypeSaveException ]: org.springframework.dao.DuplicateKeyException: { "serverUsed" : "127.0.0.1:27017","ok" : 1,"n" : 0,"err" : "E11000 duplicate key error index: igl.datatype.$_id_ dup key: { : ObjectId('569eac0dd4c623dc65508679') }","code" : 11000}; nested exception is com.mongodb.MongoException$DuplicateKey: { "serverUsed" : "127.0.0.1:27017","code" : 11000}
……重复
我刚刚发现了一个.如上所示保存时,spring会尝试插入,即使填充了_id也是如此.
保存其他对象(未显示但类似)时,弹簧执行,更新,并再次填充是_id.
为什么不同?文档说弹簧应该在填充_id时更新,并在不填充时插入.
还有什么可以导致这个吗?我的对象中有什么东西?也许我的读取转换器?
更新:
我刚见过这个团队.经过仔细审查,我们确定我们不再需要读取转换器.问题通过另一种方式解决.
解决方法
java – Spring数据mongoRepository查询排序
我想看看如何在我拥有的存储库方法中将一个排序引入Query注释.
我已经在谷歌和这里看到了这段代码,但我无法使其有效
@Query("find({state:'ACTIVE'}).sort({created:-1}).limit(1)")
Job findOneActiveOldest();
@Query("{ state:'ACTIVE',$orderby: {created:-1},$limit:1 }")
Job findOneActiveOldest();
我知道通过分页我可以做到,但在某些情况下我不需要分页,所以我想知道如何使用Query注释.
有什么建议吗?
@Query("{ state:'ACTIVE' }")
Job findOneActive(Sort sort);
并使用它:
yourRepository.findOneActive(new Sort(Sort.Direction.DESC,"created"))
Java操作MongoDB采用MongoRepository仓库进行条件查询
Java操作MongoDB采用MongoRepository仓库进行条件查询
1.实体类:
public class Person implements Serializable{
private static final long serialVersionUID = -8288372263395673353L;
private String id;
private String name;
private int age;
// set/get ...
}
2.仓库: 如果只是用简单的CRUD操作,则不需要添加其他的方法,MongoRepository提供的方法足够我们使用。
public interface PersonRepository extends MongoRepository<Person, String>{
}
3.利用MongoRepository中的查询进行操作 首先,在service层中,将PersonRepository注入到service类中
public class PersonServiceImpl implements IPersonService{
@Autowired
private PersonRepository personRepository;
}
1)查询所有的数据:
public List<Person> queryAll() throws Exception {
return personRepository.findAll();
}
2)查询所有的数据带分页: 方法为:Page<?> findAll(Pageable pageable); 该方法中的参数是一个借口,我们需要构造一个子对象,即:PageRequest对象,这个对象中有两个属性,第一个是页码,第二个是页面大小。注意:页码在mongodb中是从0开始的。
public Page<Person> queryAllByPage(int page,int rows) throws Exception {
PageRequest pageRequest = new PageRequest(page-1,rows);
return personRepository.findAll(pageRequest);
}
3)查询所有的数据的数量:
public int count() throws Exception {
long size = personRepository.count();
int count = Integer.valueOf(String.valueOf(size));
return count;
}
4)根据实体类中的属性进行查询: 当需要根据实体类中的属性查询时,MongoRepository提供的方法已经不能满足,我们需要在PersonRepository仓库中定义方法,定义方法名的规则为:find + By + 属性名(首字母大写),如:根据姓名查询Person 仓库中添加的方法:
public Person findByName(String name);
它会自动根据name查询。 service中的方法:
public void queryByFirstName(String name) throws Exception {
Person person = personRepository.findByName(name);
}
若根据其他属性查询,方法类似!
5)根据实体类中的属性进行模糊查询: 当需要根据实体类中的属性进行模糊查询时,我们也需要在PersonRepository仓库中定义方法,模糊查询定义方法名的规则为:find + By + 属性名(首字母大写) + Like,如:根据姓名进行模糊查询Person 仓库中添加的方法:
public List<Person> findByNameLike(String name);
service中的方法: 在service中直接调用仓库中我们刚才定义的方法即可!
public List<Person> queryByFirstNameLike(String name) throws Exception {
return personRepository.findByNameLike(name);
}
6)根据实体类中的属性进行模糊查询带分页: 带分页的模糊查询,其实是把模糊查询以及分页进行合并,同时我们也需要在PersonRepository仓库中定义方法,定义方法名的规则和模糊查询的规则一致,只是参数不同而已。 仓库中添加的方法:
public Page<Person> findByNameLike(String name,Pageable pageable);
在service中对仓库中的方法的调用:
public List<Person> queryByNameAndPage(int page, int rows, String name) throws Exception {
PageRequest pageRequest = new PageRequest(page-1,rows);
return personRepository.findByNameLike(name, pageRequest).getContent();
}
7)根据实体类中的属性进行模糊查询带分页,同时指定返回的键(数据库中的key,实体类中的属性): 解释一下什么是指定返回的键:也就是说当我们进行带分页的模糊查询时,不想返回数据库中的所有字段,只是返回一部分字段。例如:只返回Person中的id和name,不返回age. 若想指定返回的键,我们需要在PersonRepository中添加方法,同时使用注解@Query。 仓库中定义的方法:
@Query(value="{''name'':?0}",fields="{''name'':1}")
public Page<Person> findByNameLike(String name,Pageable pageable);
其中value是查询的条件,?0这个是占位符,对应着方法中参数中的第一个参数,如果对应的是第二个参数则为?1。fields是我们指定的返回字段,其中id是自动返回的,不用我们指定,bson中{''name'':1}的1代表true,也就是代表返回的意思。 在service中对仓库中的方法的调用:
public List<Person> queryByNameAndPage(int page, int rows, String name) throws Exception {
PageRequest pageRequest = new PageRequest(page-1,rows);
return personRepository.findByNameLike(name, pageRequest).getContent();
}
特殊查询: 1)需要查询所有数据,同时指定返回的键 当我们需要查询所有数据,同时需要指定返回的键时,则不能使用仓库中自带的findAll()方法了。我们可以查询所有id不为空的数据,同时指定返回的键。当我们需要根据一个key且该key不为空进行查询,方法名的定义规则为:find + By + 属性名(首字母大写) + NotNull。 仓库中定义的方法:
@Query(value="{''_id'':{''$ne'':null}}",fields="{''name'':1}")
public Page<Person> findByIdNotNull(Pageable pageable);
service中调用仓库中的方法:
public List<Person> queryAll(int page, int rows) throws Exception {
PageRequest pageRequest = new PageRequest(page-1,rows);
return personRepository.findByIdNotNull(pageRequest).getContent();
}
2)MongoDB的其他查询不一一列举,但将java中的仓库定义的方法名的规则列举如下,使用时将仓库中方法上的注解@Query中的value进行适当泰欧正即可。
GreaterThan(大于) 方法名举例:findByAgeGreaterThan(int age) query中的value举例:{"age" : {"$gt" : age}}
LessThan(小于) 方法名举例:findByAgeLessThan(int age) query中的value举例:{"age" : {"$lt" : age}}
Between(在...之间) 方法名举例:findByAgeBetween(int from, int to)
query中的value举例:{"age" : {"$gt" : from, "$lt" : to}}
Not(不包含) 方法名举例:findByNameNot(String name) query中的value举例:{"age" : {"$ne" : name}}
Near(查询地理位置相近的) 方法名举例:findByLocationNear(Point point) query中的value举例:{"location" : {"$near" : [x,y]}}
MongDB.Net工具库MongoRepository使用方法详解
MongDB .Net工具库MongoRepository的简单使用。
最近研究了一下MongoDB数据库,并使用了开源的在.net环境下的一个类库,Mongo仓库。对于数据的一些简单的操作非常好用,特记录供后期参考。
具体的使用过程如下:
一、新建项目,在Nuget上获取库。
二、在配置文件中设置数据库地址
三、新建数据实体,并继承Entity,定义需要的字段
四、注意常见的几种字段属性的使用
[BsonElement("reName")] 用来重命名数据库中字段的名称。
[BsonIgnore] 此属性用于将字段忽略,不在数据库中生成。
[BsonIgnoreifNull] 此属性一般用在集合对象上,当集合为空的时候忽略字段,不在数据库中生成。
[CollectionName("collectionName")] 次属性用于命名表名,数据库的表名不是实体名,而是此处的名称。
[BsonKNowTypes(typeof(class))] 此属性用于定义已知的类型
五、数据交互操作
1、实例实体对象
2、根据实体添加数据
或者:
3、根据id更新数据
4、删除数据,根据指定的条件进行删除,
5、获取数据,获取数据可以根据条件获取,或者获取所有的数据,并返回多种形式。
到此为止,基本的数据增删改查就完成了,GitHub地址:https://github.com/RobThree/MongoRepository
不足之处还望同行指正。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
您可能感兴趣的文章:
- RedisRepository 分享和纠错
- DevExpress根据条件设置GridControl RepositoryItem是否可编辑
今天关于使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?的介绍到此结束,谢谢您的阅读,有关java – Spring mongorepository save抛出重复键异常、java – Spring数据mongoRepository查询排序、Java操作MongoDB采用MongoRepository仓库进行条件查询、MongDB.Net工具库MongoRepository使用方法详解等更多相关知识的信息可以在本站进行查询。
本文标签: