当前位置: 首页 > news >正文

红安建设局投诉网站大气好寓意的广告公司名字

红安建设局投诉网站,大气好寓意的广告公司名字,html国外网站源码,wordpress新建页面转载自 芋道 Spring Boot MongoDB 入门 1. 概述 可能有一些胖友对 MongoDB 不是很了解#xff0c;这里我们引用一段介绍#xff1a; FROM 《分布式文档存储数据库 MongoDB》 MongoDB 是一个介于关系数据库和非关系数据库之间的产品#xff0c;是非关系数据库当中功能最…转载自  芋道 Spring Boot MongoDB 入门 1. 概述 可能有一些胖友对 MongoDB 不是很了解这里我们引用一段介绍 FROM 《分布式文档存储数据库 MongoDB》 MongoDB 是一个介于关系数据库和非关系数据库之间的产品是非关系数据库当中功能最丰富最像关系数据库的。 他支持的数据结构非常松散是类似 json 的 bjson 格式因此可以存储比较复杂的数据类型。 Mongo 最大的特点是他支持的查询语言非常强大其语法有点类似于面向对象的查询语言几乎可以实现类似关系数据库单表查询的绝大部分功能而且还支持对数据建立索引。 MongoDB 中的许多概念在 MySQL 中具有相近的类比。本表概述了每个系统中的一些常见概念。 对于不熟悉的胖友可以先看下该表然后开始本文的旅程。 MySQLMongoDB库 Database库 Database表 Table集合 Collection行 Row文档 Document列 Column字段 Fieldjoins嵌入文档或者链接 在早期在项目中 MongoDB 的 ORM 框架使用 Morphia 较多。随着 Spring Data MongoDB 的日趋完善更为主流。目前艿艿手头所有的项目都从 Morphia 该用 Spring Data MongoDB 。 在 Spring Data MongoDB 中有两种方式进行 MongoDB 操作 Spring Data Repository 方式 MongoTemplate 艿艿如果胖友还没安装 MongoDB 可以参考下 《芋道 MongoDB 安装部署》 文章先进行下安装。 2. 快速入门 示例代码对应仓库lab-16-spring-data-mongodb 。 MongoDB 版本号4.2.1 本小节我们会使用 spring-boot-starter-data-mongodb 自动化配置 Spring Data MongoDB 主要配置。同时使用 Spring Data Repository 实现的 MongoDB 的 CRUD 操作。 2.1 引入依赖 在 pom.xml 文件中引入相关依赖。 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.1.3.RELEASE/versionrelativePath/ !-- lookup parent from repository --/parentmodelVersion4.0.0/modelVersionartifactIdlab-16-spring-data-mongodb/artifactIddependencies!-- 自动化配置 Spring Data Mongodb --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-mongodb/artifactId/dependency!-- 方便等会写单元测试 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies/project具体每个依赖的作用胖友自己认真看下艿艿添加的所有注释噢。 2.2 Application 创建 Application.java 类配置 SpringBootApplication 注解即可。代码如下 // Application.javaSpringBootApplication(exclude {ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class}) public class Application { }2.3 MongoDBConfig 在 cn.iocoder.springboot.lab16.springdatamongodb.config 包路径下创建 MongoDBConfig 配置类。代码如下 // MongoDBConfig.javaConfiguration public class MongoDBConfig {Bean // 目的就是为了移除 _class field 。参考博客 https://blog.csdn.net/bigtree_3721/article/details/82787411public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory,MongoMappingContext context,BeanFactory beanFactory) {// 创建 DbRefResolver 对象DbRefResolver dbRefResolver new DefaultDbRefResolver(factory);// 创建 MappingMongoConverter 对象MappingMongoConverter mappingConverter new MappingMongoConverter(dbRefResolver, context);// 设置 conversions 属性try {mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));} catch (NoSuchBeanDefinitionException ignore) {}// 设置 typeMapper 属性从而移除 _class field 。mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));return mappingConverter;}}通过在自定义 MappingMongoConverter Bean 对象避免实体保存到 MongoDB 中时会多一个 _class 字段存储实体的全类名。 2.4 配置文件 在 application.yml 中添加 MongoDB 配置如下 spring:data:# MongoDB 配置项对应 MongoProperties 类mongodb:host: 127.0.0.1port: 27017database: yourdatabaseusername: test01password: password01# 上述属性也可以只配置 urilogging:level:org:springframework:data:mongodb:core: DEBUG # 打印 mongodb 操作的具体语句。生产环境下不建议开启。2.5 UserDO 在 cn.iocoder.springboot.lab16.springdatamongodb.dataobject 包路径下创建 UserDO 类。代码如下 Document(collection User) public class UserDO {/*** 用户信息*/public static class Profile {/*** 昵称*/private String nickname;/*** 性别*/private Integer gender;// ... 省略 setting/getting 方法}Idprivate Integer id;/*** 账号*/private String username;/*** 密码*/private String password;/*** 创建时间*/private Date createTime;/*** 用户信息*/private Profile profile;// ... 省略 setting/getting 方法}在 UserDO 类中我们内嵌了一个 profile 属性它是 Profile 类。这里仅仅作为示例实际场景下还是建议把 User 和 Profile 拆分开。 推荐阅读 《你应该知道的 MongoDB 最佳实践》 文章。对于初用 MongoDB 的开发者往往错误的使用内嵌属性需要去理解一下。 2.6 UserRepository 在 cn.iocoder.springboot.lab16.springdatamongodb.repository 包路径下创建 UserRepository 接口。代码如下 // ProductRepository.javapublic interface UserRepository extends MongoRepositoryUserDO, Integer { }继承 org.springframework.data.mongodb.repository.MongoRepository 接口第一个泛型设置对应的实体是 UserDO 第二个泛型设置对应的主键类型是 Integer 。 因为实现了 MongoRepository 接口Spring Data MongoDB 会自动生成对应的 CRUD 等等的代码。 是不是很方便。 MongoRepository 类图如下 每个接口定义的方法胖友可以点击下面每个链接自己瞅瞅简单~ org.springframework.data.repository.CrudRepository org.springframework.data.repository.PagingAndSortingRepository org.springframework.data.repository.query.QueryByExampleExecutor 定义基于 org.springframework.data.domain.Example.Example 的查询操作。在 「4. 基于 Example 查询」 中我们再来详细介绍。 org.springframework.data.mongodb.repository.MongoRepository 主要重写 PagingAndSortingRepository 和 CrudRepository 接口将 findXXX 方法返回的结果从 Iterable 放大成 List 同时增加 insert 插入方法。 艿艿如果胖友看过艿艿写的 《芋道 Spring Boot JPA 入门》 文章会发现和 Spring Data JPA 的使用方式基本一致。这就是 Spring Data 带给我们的好处使用相同的 API 统一访问不同的数据源。o(▽) 点赞。 2.7 简单测试 创建 UserRepositoryTest 测试类我们来测试一下简单的 UserRepositoryTest 的每个操作。代码如下 // UserRepositoryTest.javaRunWith(SpringRunner.class) SpringBootTest(classes Application.class) public class UserRepositoryTest {Autowiredprivate UserRepository userRepository;Test // 插入一条记录public void testInsert() {// 创建 UserDO 对象UserDO user new UserDO();user.setId(1); // 这里先临时写死一个 ID 编号后面演示自增 ID 的时候在修改这块user.setUsername(yudaoyuanma);user.setPassword(buzhidao);user.setCreateTime(new Date());// 创建 Profile 对象UserDO.Profile profile new UserDO.Profile();profile.setNickname(芋道源码);profile.setGender(1);user.setProfile(profile);// 存储到 DBuserRepository.insert(user);}// 这里要注意如果使用 save 方法来更新的话必须是全量字段否则其它字段会被覆盖。// 所以这里仅仅是作为一个示例。Test // 更新一条记录public void testUpdate() {// 查询用户OptionalUserDO userResult userRepository.findById(1);Assert.isTrue(userResult.isPresent(), 用户一定要存在);// 更新UserDO updateUser userResult.get();updateUser.setUsername(yutou);userRepository.save(updateUser);}Test // 根据 ID 编号删除一条记录public void testDelete() {userRepository.deleteById(1);}Test // 根据 ID 编号查询一条记录public void testSelectById() {OptionalUserDO userDO userRepository.findById(1);System.out.println(userDO.isPresent());}Test // 根据 ID 编号数组查询多条记录public void testSelectByIds() {IterableUserDO users userRepository.findAllById(Arrays.asList(1, 4));users.forEach(System.out::println);}}每个测试单元方法胖友自己看看方法上的注释。 具体的胖友可以自己跑跑妥妥的。 3. 基于方法名查询 示例代码对应仓库lab-16-spring-data-mongodb 。 在 《芋道 Spring Boot JPA 入门》 文章的「4. 基于方法名查询」小节中我们已经提到 在 Spring Data 中支持根据方法名作生成对应的查询WHERE条件进一步进化我们使用 JPA 具体是方法名以 findBy、existsBy、countBy、deleteBy 开头后面跟具体的条件。具体的规则在 《Spring Data JPA —— Query Creation》 文档中已经详细提供。如下 关键字方法示例JPQL snippetAndfindByLastnameAndFirstname… where x.lastname ?1 and x.firstname ?2OrfindByLastnameOrFirstname… where x.lastname ?1 or x.firstname ?2Is, EqualsfindByFirstname,findByFirstnameIs,findByFirstnameEquals… where x.firstname ?1BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2LessThanfindByAgeLessThan… where x.age ?1LessThanEqualfindByAgeLessThanEqual… where x.age ?1GreaterThanfindByAgeGreaterThan… where x.age ?1GreaterThanEqualfindByAgeGreaterThanEqual… where x.age ?1AfterfindByStartDateAfter… where x.startDate ?1BeforefindByStartDateBefore… where x.startDate ?1IsNull, NullfindByAge(Is)Null… where x.age is nullIsNotNull, NotNullfindByAge(Is)NotNull… where x.age not nullLikefindByFirstnameLike… where x.firstname like ?1NotLikefindByFirstnameNotLike… where x.firstname not like ?1StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)OrderByfindByAgeOrderByLastnameDesc… where x.age ?1 order by x.lastname descNotfindByLastnameNot… where x.lastname ?1InfindByAgeIn(Collection ages)… where x.age in ?1NotInfindByAgeNotIn(Collection ages)… where x.age not in ?1TruefindByActiveTrue()… where x.active trueFalsefindByActiveFalse()… where x.active falseIgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) UPPER(?1)注意如果我们有排序需求可以使用 OrderBy 关键字。 下面我们来编写一个简单的示例。 艿艿IDEA 牛逼提供的插件已经能够自动提示上述关键字。太强了~ 3.1 UserRepository02 在 cn.iocoder.springboot.lab16.springdatamongodb.repository 包路径下创建 UserRepository02 接口。代码如下 // UserRepository02.javapublic interface UserRepository02 extends MongoRepositoryUserDO, Integer {UserDO findByUsername(String username);PageUserDO findByUsernameLike(String username, Pageable pageable);}对于分页操作需要使用到 Pageable 参数需要作为方法的最后一个参数。 注意噢基于方法名查询不支持内嵌对象的属性。(⊙o⊙)… 至少在网上翻了一波资料没有提及这块。 3.2 简单测试 创建 UserRepository02Test 测试类我们来测试一下简单的 UserRepository02Test 的每个操作。代码如下 // UserRepository02Test.javaRunWith(SpringRunner.class) SpringBootTest(classes Application.class) public class UserRepository02Test {Autowiredprivate UserRepository02 userRepository;Test // 根据名字获得一条记录public void testFindByName() {UserDO user userRepository.findByUsername(yutou);System.out.println(user);}Test // 使用 username 模糊查询分页返回结果public void testFindByNameLike() {// 创建排序条件Sort sort new Sort(Sort.Direction.DESC, id); // ID 倒序// 创建分页条件。Pageable pageable PageRequest.of(0, 10, sort);// 执行分页操作PageUserDO page userRepository.findByUsernameLike(yu, pageable);// 打印System.out.println(page.getTotalElements());System.out.println(page.getTotalPages());}}每个测试单元方法胖友自己看看方法上的注释。 具体的胖友可以自己跑跑妥妥的。 4. 基于 Example 查询 示例代码对应仓库lab-16-spring-data-mongodb 。 实际场景下我们并不会基于 Example 查询。所以本小节胖友可以选择性看看即可。 对于大多数胖友可能不了解 Spring Data Example 。我们先来一起看看官方文档的介绍 Query by Example (QBE) is a user-friendly querying technique with a simple interface. 使用 Example 进行查询是一种友好的查询方式可以使用便捷的 API 方法。 It allows dynamic query creation and does not require to write queries containing field names. 它允许创建动态查询而无需编写包含字段名的查询。 In fact, Query by Example does not require to write queries using store-specific query languages at all. 事实上在使用 Example 进行查询的时候我们无需使用特定的存储器数据库的查询语言。 请原谅艿艿蹩脚的翻译。简单来说我们可以通过 Example 进行编写动态的查询条件而无需使用每个不同的 Spring Data 实现类的 Query 对象。例如说 Spring Data JPA 提供的 javax.persistence.criteria.Predicate Spring Data MongoDB 提供的 org.springframework.data.mongodb.core.query.Query 。 相当于说不同 Spring Data 实现框架会将 Spring Data Example 条件翻译成对应的查询对象。例如说 Spring Data JPA 将 Example 转换成 Predicate 。 Spring Data MongoDB 将 Example 转换成 Query 。 当然并不是所有 Spring Data 实现都支持 Spring Data Example 。例如说Spring Data Elasticsearch 并不支持。一般情况下支持 Spring Data Example 的 Spring Data 实现框架它们的 Repository 都继承了 org.springframework.data.repository.query.QueryByExampleExecutor 接口。例如说 Spring Data JPA 的 JpaRepository 接口。 Spring Data MongoDB 的 MongoRepository 接口。 Example API 一共包含三部分 Probe 含有对应字段的实体对象。通过设置该实体对象的字段作为查询字段。 注意Probe 并不是一个类而是实体对象的泛指。 ExampleMatcher ExampleMatcher 可以定义特定字段的匹配模式。例如说全模糊匹配、前缀模糊匹配等等。 简单来说通过实体对象的字段作为查询条件只能满足相等的情况对于 ! 、LIKE 等等情况需要通过 ExampleMatcher 特殊指定。如果不理解没事看了示例会更容易明白。 Example 是 Probe 和 ExampleMatcher 的组合构成查询对象。 当然Example 有它的限制条件 No support for nested/grouped property constraints like firstname ?0 or (firstname ?1 and lastname ?2) 不支持嵌套或分组约束。例如说firstname ?0 or (firstname ?1 and lastname ?2) 。 Only supports starts/contains/ends/regex matching for strings and exact matching for other property types 对于字符串只支持 tarts/contains/ends/regex 匹配方式对于其它类型只支持精确匹配。 4.1 UserRepository03 在 cn.iocoder.springboot.lab16.springdatamongodb.repository 包路径下创建 UserRepository02 接口。代码如下 // UserRepository03.javapublic interface UserRepository03 extends MongoRepositoryUserDO, Integer {// 使用 username 精准匹配default UserDO findByUsername01(String username) {// 创建 Example 对象使用 username 查询UserDO probe new UserDO();probe.setUsername(username); // 精准匹配 username 查询ExampleUserDO example Example.of(probe);// 执行查询return findOne(example).orElse(null); // 如果为空则返回 null}// 使用 username 模糊匹配default UserDO findByUsernameLike01(String username) {// 创建 Example 对象使用 username 查询UserDO probe new UserDO();probe.setUsername(username); // 这里还需要设置ExampleMatcher matcher ExampleMatcher.matching().withMatcher(username, ExampleMatcher.GenericPropertyMatchers.contains()); // 模糊匹配 username 查询ExampleUserDO example Example.of(probe, matcher);// 执行查询return findOne(example).orElse(null); // 如果为空则返回 null}}4.2 简单测试 创建 UserRepository03Test 测试类我们来测试一下简单的 UserRepository03Test 的每个操作。代码如下 // UserRepository03Test.javaRunWith(SpringRunner.class) SpringBootTest(classes Application.class) public class UserRepository03Test {Autowiredprivate UserRepository03 userRepository;Testpublic void testFindByUsername01() {UserDO user userRepository.findByUsername01(yutou);System.out.println(user);}Testpublic void testFindByUsernameLike01() {UserDO user userRepository.findByUsernameLike01(yu);System.out.println(user);}}每个测试单元方法胖友自己看看方法上的注释。 具体的胖友可以自己跑跑妥妥的。更多示例可以看看如下文章 《Spring Data JPA Query by Example》 《Spring Data JPA 使用 Example 快速实现动态查询》 5. MongoTemplate 示例代码对应仓库lab-16-spring-data-mongodb 。 在 Spring Data MongoDB 中有一个 MongoTemplate 类提供了 MongoDB 操作模板方便我们操作 MongoDB 。 5.1 UserDao 在 cn.iocoder.springboot.lab16.springdatamongodb.dao 包路径下创建 UserDao 类。代码如下 // UserDao.javaRepository public class UserDao {Autowiredprivate MongoTemplate mongoTemplate;public void insert(UserDO entity) {mongoTemplate.insert(entity);}public void updateById(UserDO entity) {// 生成 Update 条件final Update update new Update();// 反射遍历 entity 对象将非空字段设置到 Update 中ReflectionUtils.doWithFields(entity.getClass(), new ReflectionUtils.FieldCallback() {Overridepublic void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {// 排除指定条件if (id.equals(field.getName()) // 排除 id 字段因为作为查询主键|| field.getAnnotation(Transient.class) ! null // 排除 Transient 注解的字段因为非存储字段|| Modifier.isStatic(field.getModifiers())) { // 排除静态字段return;}// 设置字段可反射if (!field.isAccessible()) {field.setAccessible(true);}// 排除字段为空的情况if (field.get(entity) null) {return;}// 设置更新条件update.set(field.getName(), field.get(entity));}});// 防御避免有业务传递空的 Update 对象if (update.getUpdateObject().isEmpty()) {return;}// 执行更新mongoTemplate.updateFirst(new Query(Criteria.where(_id).is(entity.getId())), update, UserDO.class);}public void deleteById(Integer id) {mongoTemplate.remove(new Query(Criteria.where(_id).is(id)), UserDO.class);}public UserDO findById(Integer id) {return mongoTemplate.findOne(new Query(Criteria.where(_id).is(id)), UserDO.class);}public UserDO findByUsername(String username) {return mongoTemplate.findOne(new Query(Criteria.where(username).is(username)), UserDO.class);}public ListUserDO findAllById(ListInteger ids) {return mongoTemplate.find(new Query(Criteria.where(_id).in(ids)), UserDO.class);}}使用 MongoTemplate 实现了 CRUD 的功能。其它 findAndModify/findAndRemove/count/upsert 等操作胖友可以自己尝试下。 对于 #updateById(UserDO entity) 方法胖友可以自己抽象成一个通用的 #updateEntityFieldsById(Object id, Object entity) 方法封装在一个 BaseMongoDao 抽象类中。 友情提示此处暂时有个问题对于 UserDO 内嵌的 profile 对象一旦设置了值是整个 Profile 对象覆盖更新。所以使用时需要注意下。 目前艿艿自己项目里大多数内嵌对象全量更新不存在问题。如果存在问题的提供了另外的方法解决。 当然也可以进一步封装 #updateEntityFieldsById(Object id, Object entity, String... fields) 方法只更新指定字段。 5.2 简单测试 创建 UserDaoTest 测试类我们来测试一下简单的 UserDaoTest 的每个操作。代码如下 // UserDaoTest.javaRunWith(SpringRunner.class) SpringBootTest(classes Application.class) public class UserDaoTest {Autowiredprivate UserDao userDao;Test // 插入一条记录public void testInsert() {// 创建 UserDO 对象UserDO user new UserDO();user.setId(1); // 这里先临时写死一个 ID 编号后面演示自增 ID 的时候在修改这块user.setUsername(yudaoyuanma);user.setPassword(buzhidao);user.setCreateTime(new Date());// 创建 Profile 对象UserDO.Profile profile new UserDO.Profile();profile.setNickname(芋道源码);profile.setGender(1);user.setProfile(profile);// 存储到 DBuserDao.insert(user);}// 这里要注意如果使用 save 方法来更新的话必须是全量字段否则其它字段会被覆盖。// 所以这里仅仅是作为一个示例。Test // 更新一条记录public void testUpdate() {// 创建 UserDO 对象UserDO updateUser new UserDO();updateUser.setId(1);updateUser.setUsername(nicai);// 执行更新userDao.updateById(updateUser);}Test // 根据 ID 编号删除一条记录public void testDelete() {userDao.deleteById(1);}Test // 根据 ID 编号查询一条记录public void testSelectById() {UserDO userDO userDao.findById(1);System.out.println(userDO);}Test // 根据 ID 编号数组查询多条记录public void testSelectByIds() {ListUserDO users userDao.findAllById(Arrays.asList(1, 4));users.forEach(System.out::println);}}每个测试单元方法胖友自己看看方法上的注释。 具体的胖友可以自己跑跑妥妥的。 6. 自增主键 示例代码对应仓库lab-16-spring-data-mongodb 。 MongoDB 自带的主键选择是 ObjectId 类型需要占用 12 字节。相比 Int 4 字节或者 Long 8 字节占用更多的内存空间。而绝大多数业务场景下Int 或 Long 足够使用所以我们更加偏向使用 Int 或 Long 作为自增 ID 主键。 当然我们在日志记录上我们还是采用 ObjectId 为主。 我们在实现 MongoDB 自增主键时会创建一个名为 sequence 的集合。字段如下 sequence 集合名也可以取其它名字看自己喜好。 _id String 类型集合的实体类名。 value Long 类型存储每个集合的自增序列。 在程序中每次插入实体对象到 MongoDB 之前通过 $inc 操作从 sequence 自增获得最新的 ID 然后将该 ID 赋值给实体对象最终在插入到 MongoDB 之中。 当然考虑到并不是所有实体都需要使用自增 ID 所以我们要有方式去标记 方式一创建自定义 AutoIncKey 注解添加到 ID 属性上。 方式二创建 IncIdEntity 抽象基类这样需要自增的实体继承它。 对于方式一网上博客比较多胖友可以看看 《Java 中实现 MongoDB 主键自增》 文章。 对于方式二目前艿艿项目采用这种方式主要是我们自己的 BaseMongoDao 提供的很多方法是基于 IncIdEntity 抽象类的。例如说#updateEntityFieldsById(final IncIdEntity entity, String... fields) 方法这样可以方便的直接获取到 ID 属性。 当然无论方式一还是方式二实现原理是一致的差异仅仅在于获取 ID 属性不同。下面本小节我们就来实现下方式二。 6.1 IncIdEntity 在 cn.iocoder.springboot.lab16.springdatamongodb.mongo 包路径下创建 IncIdEntity 类。代码如下 // IncIdEntity.java/*** 自增主键实体** param T 主键泛型*/ public abstract class IncIdEntityT extends Number {Idprivate T id;public T getId() {return id;}public void setId(T id) {this.id id;}}6.2 ProductDO 在 cn.iocoder.springboot.lab16.springdatamongodb.dataobject 包路径下创建 ProductDO 类。代码如下 // ProductDO.javaDocument(collection Product) public class ProductDO extends IncIdEntityInteger {/*** 商品名*/private String name;public String getName() {return name;}public ProductDO setName(String name) {this.name name;return this;}}继承 IncIdEntity 抽象类使用 Integer 自增主键。 6.3 MongoInsertEventListener 在 cn.iocoder.springboot.lab16.springdatamongodb.dataobject 包路径下创建 MongoInsertEventListener 类。代码如下 // MongoInsertEventListener.javaComponent public class MongoInsertEventListener extends AbstractMongoEventListenerIncIdEntity {/*** sequence - 集合名*/private static final String SEQUENCE_COLLECTION_NAME sequence;/*** sequence - 自增值的字段名*/private static final String SEQUENCE_FIELD_VALUE value;Autowiredprivate MongoTemplate mongoTemplate;Overridepublic void onBeforeConvert(BeforeConvertEventIncIdEntity event) {IncIdEntity entity event.getSource();// 判断 id 为空if (entity.getId() null) {// 获得下一个编号Number id this.getNextId(entity);// 设置到实体中// noinspection uncheckedentity.setId(id);}}/*** 获得实体的下一个主键 ID 编号** param entity 实体对象* return ID 编号*/private Number getNextId(IncIdEntity entity) {// 使用实体名的简单类名作为 ID 编号String id entity.getClass().getSimpleName();// 创建 Query 对象Query query new Query(Criteria.where(_id).is(id));// 创建 Update 对象Update update new Update();update.inc(SEQUENCE_FIELD_VALUE, 1); // 自增值// 创建 FindAndModifyOptions 对象FindAndModifyOptions options new FindAndModifyOptions();options.upsert(true); // 如果不存在时则进行插入options.returnNew(true); // 返回新值// 执行操作SuppressWarnings(unchecked)HashMapString, Object result mongoTemplate.findAndModify(query, update, options,HashMap.class, SEQUENCE_COLLECTION_NAME);// 返回主键return (Number) result.get(SEQUENCE_FIELD_VALUE);}}MongoDB 实体对象在插入之前会发布 BeforeConvertEvent 事件。所以我们可以通过创建 MongoInsertEventListener 监听器监听该事件生成自增主键 ID 主键设置到实体对象中。 如果胖友想要使用集合名作为 sequence 集合的 id 可以使用 BeforeConvertEvent.collectionName 属性。 6.4 ProductRepository 在 cn.iocoder.springboot.lab16.springdatamongodb.repository 包路径下创建 ProductRepository 接口。代码如下 // ProductRepository.javapublic interface ProductRepository extends MongoRepositoryProductDO, Integer { }6.5 简单测试 创建 ProductRepositoryTest 测试类我们来测试一下简单的 ProductRepositoryTest 的每个操作。代码如下 // ProductRepositoryTest.javaRunWith(SpringRunner.class) SpringBootTest(classes Application.class) public class ProductRepositoryTest {Autowiredprivate ProductRepository productRepository;Testpublic void testInsert() {// 创建 ProductDO 对象ProductDO product new ProductDO();product.setName(芋头);// 插入productRepository.insert(product);// 打印 IDSystem.out.println(product.getId());}}666. 彩蛋 艿艿的项目中只采用 MongoTemplate 。主要是我们封装了 BaseMongoDao 提供了一些我们日常开发需要的功能例如说 #insertToMongo(Object objectToSave) 方法插入实体使用自增 ID 主键。 #updateEntityFieldsById(final IncIdEntity entity, String... fields) 方法只更新实体指定字段。 推荐阅读 《性能测试 —— MongoDB 基准测试》
http://www.zqtcl.cn/news/355598/

相关文章:

  • c 网站开发培训怎么做网站的站点地图
  • html 网站模板简单网站制作北京海淀
  • 大庆做网站找谁珠海网站搭建
  • 网站建设方面的外文宿迁房产网找房
  • 运营 网站遵义网站开发制作公司
  • 动力论坛源码网站后台地址是什么网站上微信支付功能
  • 网站需求分析模板深圳3d制作
  • 宿迁网站建设推广公司wordpress忘记密码了
  • 成都双语网站开发flat wordpress
  • 大连做公司网站的公司网络营销的网站
  • 做网站 人工智能怎么做商业服务网站
  • 自助建站公司四平市住房和城乡建设部网站
  • 淄博网站seo价格世界新闻最新消息
  • 网站开发 毕业答辩pptwordpress qq邮箱订阅
  • 国家icp备案网站群辉域名登录wordpress
  • 仙居住房和城乡建设规划局网站可以做思维导图的网站
  • 企业网站建设费怎么入账石家庄定制网站建设服务
  • 遂宁建设网站如何搭建微信公众号平台
  • 咖啡网站源码公司网站手机版
  • 新能源网站开发网站做5级分销合法吗
  • 西安建设网站排名简约风网站首页怎么做
  • 安远做网站做服务网站要多少钱
  • 功能网站模板电商平台项目商业计划书
  • 阿里巴巴国际站入驻费用及条件广州做网站比较好的公司
  • 淄博营销网站建设阳泉营销型网站建设费用
  • 珠海网站开发定制常德网站建设详细策划
  • 做电影网站侵权哈尔滨网站开发
  • 中国联通网站备案系统Wordpress建立空白页面
  • 郑州网站建设 郑州网站制作wordpress删除模板
  • 北京网站设计培训wordpress vps 伪静态