Spring Boot - 数据库操作之MongoDB

2018-11-02  本文已影响124人  yuanzicheng

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

上一篇下一篇

猜你喜欢

热点阅读