GVKun编程网logo

使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?

10

最近很多小伙伴都在问使用SpringDataMongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓

最近很多小伙伴都在问使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展java – Spring mongorepository save抛出重复键异常、java – Spring数据mongoRepository查询排序、Java操作MongoDB采用MongoRepository仓库进行条件查询、MongDB.Net工具库MongoRepository使用方法详解等相关知识,下面开始了哦!

本文目录一览:

使用Spring Data MongoDB在事务中的两个不同ReactiveMongoRepository中调用方法?

使用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事务,例如将a
Person和插入Car同一事务中(使用PersonRepositoryCarRepository大小写)?如果是这样,您该怎么做?

答案1

小编典典

我也一直在努力寻找Mongo DB和Spring Boot的Reactive风格的 事务 支持解决方案

但是幸运的是我自己想通了。尽管Google提供的一些功能也没有帮助,但这些都是无反应的。

  • 您需要使用 ReactiveMongoTransactionManager 沿 ReactiveMongoDatabaseFactory ,大部分的末尾的详细信息,也分享代码回购为同

  • 为了使mongo数据库支持事务,我们需要确保数据库应以副本方式运行

为什么我们需要那个? 因为否则您会得到一些这样的错误:

此客户端连接到的MongoDB集群不支持会话

相同的说明如下:

  1. 使用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
  1. 映像显示后,执行命令(此处 localmongo_docker 是容器的名称):-
docker exec -it localmongo_docker mongo
  1. 复制并粘贴下面的命令并执行
rs.initiate(   {     _id : ''rs0'',     members: [       { _id : 0, host : "mongo:27017" }     ]   } )
  1. 然后通过输入 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抛出重复键异常

java – Spring mongorepository save抛出重复键异常

我正在使用 java和 Spring.作为测试,我通过id查询对象,然后尝试保存同一个对象而不更新任何东西.当我这样做时,我得到一个重复的密钥异常.根据我读过的内容,如果_id为null,则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时更新,并在不填充时插入.

还有什么可以导致这个吗?我的对象中有什么东西?也许我的读取转换器?

更新:
我刚见过这个团队.经过仔细审查,我们确定我们不再需要读取转换器.问题通过另一种方式解决.

解决方法

在数据库端,您可能已创建唯一索引.请查看“ https://docs.mongodb.com/manual/core/index-unique/”了解更多信息.

java – Spring数据mongoRepository查询排序

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注释做到这一点.如果您不需要分页,可以使用存储库方法使用Sort参数:

@Query("{ state:'ACTIVE' }")
Job findOneActive(Sort sort);

并使用它:

yourRepository.findOneActive(new Sort(Sort.Direction.DESC,"created"))

Java操作MongoDB采用MongoRepository仓库进行条件查询

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使用方法详解

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使用方法详解等更多相关知识的信息可以在本站进行查询。

本文标签: