美文网首页
Spring Boot - 数据库操作之MongoDB

Spring Boot - 数据库操作之MongoDB

作者: yuanzicheng | 来源:发表于2018-11-02 14:56 被阅读124次

    Spring Data提供了对MongDB的支持,在SpringBoot项目中集成MongoDB非常便捷。

    1.快速集成

    添加依赖

    compile('org.springframework.boot:spring-boot-starter-data-mongodb:2.1.0.RELEASE')
    

    application.properties或application.yml中配置mongodb相关项

    spring:
      data:
        mongodb:
          uri: mongodb://name:pass@localhost:27017/test
    

    如果要连接MongoDB副本集,那么连接配置如下,replcaSet参数指定了副本集名称。

    spring:
      data:
        mongodb:
          uri: mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/test?replcaSet=xxx&slaveOk=true&readPreference=primary
    

    使用MongoTemplate操作MongoDB

    
    @RunWith(SpringRunner::class)
    @SpringBootTest
    class ApplicationTests {
    
        @Autowired
        private lateinit var mongoTemplate: MongoTemplate
    
        @Test
        fun test() {
            mongoTemplate.insert(User(name = "jack", age = 16))
            mongoTemplate.find(Query(),User::class.java).forEach { println(it.toString()) }
            mongoTemplate.findAllAndRemove(Query(Criteria.where("name").`is`("jack")),User::class.java)
            mongoTemplate.save(User(name = "tom", age = 17))
            mongoTemplate.updateMulti(Query(Criteria.where("name").`is`("tom")), Update().set("age",18),User::class.java)
        }
    
    }
    
    @Document(collection = "user")
    data class User(
            @Id
            var id: String? = null,
            @Field(value = "name")
            var name: String? = null,
            @Field(value = "age")
            var age: Int? = null
    )
    

    上面的代码使用kotlin在Spring Boot中使用junit测试了MongoTemplate提供的部分函数,MongoTemplate支持的操作非常多,从函数名上看,与MongoDB原生的命令基本接近,这里不做过多展示了,实际应用中根据需要选择。

    另外,除了使用MongoTemplate操作MongoDB数据库,还可以使用MongoRepository快速地实现CURD操作(这点类似JPA)。

    例如使用MongDB实现小文件存储:

    File.kt

    @Document
    data class File(
            @Id
            var id: String? = null,
            var name: String? = null,
            var contentType: String? = null,
            var size: Long? = null,
            var uploadDate: Date? = null,
            var md5: String? = null,
            var path: String? = null,
            var content: Binary? = null
    
    ) {
        override fun equals(other: Any?): Boolean {
            if (this === other) {
                return true
            }
            if (other == null || this::class.java != other::class.java) {
                return false
            }
            val file: File = other as File
            return Objects.equals(size, file.size)
                    && Objects.equals(name, file.name)
                    && Objects.equals(contentType, file.contentType)
                    && Objects.equals(uploadDate, file.uploadDate)
                    && Objects.equals(md5, file.md5)
                    && Objects.equals(id, file.id)
        }
    
        override fun hashCode(): Int {
            return Objects.hash(name, contentType, size, uploadDate, md5, id)
        }
    }
    

    FileRepository.kt

    @Repository
    interface FileRepository: MongoRepository<File,String>
    
    2.事务支持

    MongoDB更新到4.0以后已经支持ACID及多文档事务。

    当我们迫不及待地在Spring Boot项目中尝试这一特性的时候,发现仅仅使用@Transactional注解是不能自动开启事务的。因为Spring Data MongoDB模块在默认情况下并没有注册PlatformTransactionManager,这是为了防止在使用非4.0版本的MongoDB或者项目中已经使用了其它事务管理器的情况下的异常情况,所以需要手动配置事务管理器。

    import org.springframework.context.annotation.Bean
    import org.springframework.context.annotation.Configuration
    import org.springframework.data.mongodb.MongoDbFactory
    import org.springframework.data.mongodb.MongoTransactionManager
    
    @Configuration
    class MongoConfig {
        @Bean
        fun transactionManager(dbFactory: MongoDbFactory): MongoTransactionManager {
            return MongoTransactionManager(dbFactory)
        }
    }
    

    需要说明的是,MongoTransactionManager事务管理器在Spring Data MongoDB 2.1版本后才能支持,详细信息见Spring Data MongoDB参考文档

    有一些操作在MongoDB的事务中是不支持的,如几乎所有元命令、创建集合、创建索引、首次使用集合时隐时创建集合。

    另外,千万不要在JUnit中测试验证MongoDB的事务回滚,因为@Rollback默认为true强制回滚,这样就不知道是因为Junit回滚还是因为事务出现异常回滚,如果设为false又会使得MongoDB事务不会回滚......

    参考
    Hands on MongoDB 4.0 transactions with Spring Data

    https://stackoverflow.com/questions/51977150/spring-data-mongodb-transactional-failure

    相关文章

      网友评论

          本文标题:Spring Boot - 数据库操作之MongoDB

          本文链接:https://www.haomeiwen.com/subject/llccxqtx.html