我在请求请求中提出我的解决方案
这个想法是将Entity更改为:
import com.example.demo.pojo.SamplePojoimport com.vladmihalcea.hibernate.type.json.JsonBinaryTypeimport com.vladmihalcea.hibernate.type.json.JsonStringTypeimport org.hibernate.annotations.Typeimport org.hibernate.annotations.TypeDefimport org.hibernate.annotations.TypeDefsimport javax.persistence.*@Entity@Table(name = "tests")@TypeDefs( TypeDef(name = "json", typeClass = JsonStringType::class), TypeDef(name = "jsonb", typeClass = JsonBinaryType::class))data class SampleEntity ( @Id @GeneratedValue val id: Long?, val name: String?, @Type(type = "jsonb") @Column(columnDefinition = "jsonb") var data: Map<String, Any>?) { constructor(): this(null, null, null)}
- 每个实体都应具有默认构造函数或所有参数都具有默认值
- 而不是保存POJO,另存为
Map<String, Any>
类型
由于我们可以完全控制业务逻辑中的POJO,因此唯一缺少的部分是将POJO转换为Map并将Map转换为POJO
SamplePojo实现
data class SamplePojo( val payload: String, val flag: Boolean) { constructor(map: Map<String, Any>) : this(map["payload"] as String, map["flag"] as Boolean) fun toMap() : Map<String, Any> { return mapOf("payload" to payload, "flag" to flag) }}
这是一种解决方法,但是它允许我们使用任何深度级别的结构。
PS我注意到您使用
Serializer并重新定义了
equals, toString, hashCode。如果使用,则不需要此
dataclass。
更新:
如果您需要比以上更灵活的结构
Map<String,Any>,则可以使用
JsonNode。代码示例
实体:
import com.fasterxml.jackson.databind.JsonNodeimport com.vladmihalcea.hibernate.type.json.JsonBinaryTypeimport com.vladmihalcea.hibernate.type.json.JsonStringTypeimport org.hibernate.annotations.Typeimport org.hibernate.annotations.TypeDefimport org.hibernate.annotations.TypeDefsimport javax.persistence.*@Entity@Table(name = "tests")@TypeDefs( TypeDef(name = "json", typeClass = JsonStringType::class), TypeDef(name = "jsonb", typeClass = JsonBinaryType::class))data class SampleJsonNodeEntity ( @Id @GeneratedValue val id: Long?, val name: String?, @Type(type = "jsonb") @Column(columnDefinition = "jsonb") var data: JsonNode?) { constructor(): this(null, null, null)}
更改存储库中的实体:
import com.example.demo.entity.SampleJsonNodeEntityimport org.springframework.data.jpa.repository.JpaRepositoryinterface SampleJsonNodeRepository: JpaRepository<SampleJsonNodeEntity, Long> {}
测试两种方法:
import com.example.demo.DbTestInitializerimport com.example.demo.entity.SampleJsonNodeEntityimport com.example.demo.entity.SampleMapEntityimport com.example.demo.pojo.SamplePojoimport com.fasterxml.jackson.module.kotlin.jacksonObjectMapperimport junit.framework.Assert.assertEqualsimport junit.framework.Assert.assertNotNullimport org.junit.Beforeimport org.junit.Testimport org.junit.runner.RunWithimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabaseimport org.springframework.boot.test.context.SpringBootTestimport org.springframework.test.context.ContextConfigurationimport org.springframework.test.context.junit4.SpringRunner@RunWith(SpringRunner::class)@SpringBootTest@ContextConfiguration(initializers = [DbTestInitializer::class])@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)class SampleRepositoryTest { @Autowired lateinit var sampleMapRepository: SampleMapRepository @Autowired lateinit var sampleJsonNodeRepository: SampleJsonNodeRepository lateinit var dto: SamplePojo lateinit var mapEntity: SampleMapEntity lateinit var jsonNodeEntity: SampleJsonNodeEntity @Before fun setUp() { dto = SamplePojo("Test", true) mapEntity = SampleMapEntity(null, "POJO1", dto.toMap() ) jsonNodeEntity = SampleJsonNodeEntity(null, "POJO2", jacksonObjectMapper().valueToTree(dto) ) } @Test fun createMapPojo() { val id = sampleMapRepository.save(mapEntity).id!! assertNotNull(sampleMapRepository.getOne(id)) assertEquals(sampleMapRepository.getOne(id).data?.let { SamplePojo(it) }, dto) } @Test fun createJsonNodePojo() { val id = sampleJsonNodeRepository.save(jsonNodeEntity).id!! assertNotNull(sampleJsonNodeRepository.getOne(id)) assertEquals(jacksonObjectMapper().treeToValue(sampleJsonNodeRepository.getOne(id).data, SamplePojo::class.java), dto) }}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)