springboot使用json文件对mongo数据进行初始化

功能说明

使用json文件对mongo数据进行初始化,文件保存目录为 resources/mongo/,


json文件规则及dao文件规则

规则可根据实际需求更改代码

1、配置json文件在resources/mongo目录 文件需以_insert.json(Insert.json) 或 _update.json(Update.json)结尾
2、文件命名格式如 新增文件:test_action_insert.json,则对应的dao文件名为 TestActionDao(TestActionRepository) ,dao文件需继承MongoRepository
3、更新逻辑:_insert.json:表中不存在数据则新增 _update.json:表中存在数据则更新,不存在则新增,数据根据id判断 _update.json文件数据最好设置主键


kotlin代码:

这里放的是kotlin代码,java的话与kotlin类似,可以照着样子用java写一遍

逻辑:一个json文件对应一个dao,根据名称来进行匹配。json文件后缀名决定此json是更新或者新增,新增则需要判断表中是否存在数据。

@Configuration
@ConditionalOnClass(value = [MongoRepository::class])
class InitMongoConfig {
    
    

    /**
     * 配置初始化mongo
     *
     * @param objectMapper ObjectMapper 序列化工具
     * @param map Map<String, MongoRepository<*, *>>? 所有继承MongoRepository的类
     * @return AbstractRepositoryPopulatorFactoryBean? AbstractRepositoryPopulatorFactoryBean
     */
    @Bean
    fun repositoryPopulator(objectMapper: ObjectMapper, map: Map<String, MongoRepository<*, *>>?)
            : AbstractRepositoryPopulatorFactoryBean {
    
    
        // 没有类
        if (map == null) {
    
    
            return Jackson2RepositoryPopulatorFactoryBean()
        }
        // 获取所有mongo json文件名
        val paths = getMongoFilePath()
        if (paths.isEmpty()) {
    
    
            return Jackson2RepositoryPopulatorFactoryBean()
        }
        // 去除key后缀 testDao -> test
        val repositories = removeSuffix(map)
        // 所有需要更新的资源文件
        val resources = getClassPathResource(paths, repositories)
        if (resources.isNotEmpty()) {
    
    
            val factory = CustomJackson2RepositoryPopulatorFactoryBean()
            factory.setMapper(objectMapper)
            factory.setResources(resources.toTypedArray())
            return factory
        }
        return Jackson2RepositoryPopulatorFactoryBean()
    }

    /**
     * 获取resources/mongo/ 下所有的json文件名
     * 可根据实际情况更改目录规则
     *
     * @return List<String> json文件名
     */
    private fun getMongoFilePath(): List<String> {
    
    
        val classPathResource = ClassPathResource("mongo")
        if (!classPathResource.exists()) {
    
    
            return Collections.emptyList()
        }
        val listFiles = classPathResource.file.listFiles()
        return listFiles?.map {
    
    
            if (it.name.contains(".json")) {
    
    
                it.name
            } else {
    
    
                ""
            }
        } ?: Collections.emptyList()
    }

    /**
     * 去除后缀
     * key: testDao -> test
     *
     * @param map Map<String, MongoRepository<*, *>> 所有继承MongoRepository的map
     * @return Map<String, MongoRepository<*, *>> key去除后缀的map
     */
    private fun removeSuffix(map: Map<String, MongoRepository<*, *>>): Map<String, MongoRepository<*, *>> {
    
    
        val repositories = mutableMapOf<String, MongoRepository<*, *>>()
        // 去除repository的后缀名
        map.forEach {
    
     (key, value) ->
            val mapsKey = key.replace("Dao", "").replace("Repository", "")
            repositories[mapsKey] = value
        }
        return repositories
    }

    /**
     * 获取所有需要更新的资源
     * 1、资源文件有对应的dao类
     * 2、需要更新
     *
     * @param paths List<String>
     * @param repositories Map<String, MongoRepository<*, *>>
     * @return List<ClassPathResource>
     */
    private fun getClassPathResource(paths: List<String>, repositories: Map<String, MongoRepository<*, *>>)
            : List<ClassPathResource> {
    
    
        // 所有需要更新的资源文件
        val resources = arrayListOf<ClassPathResource>()
        // 检查是否符合条件
        paths.forEach {
    
    
            // 下划线转驼峰 test_inset.json -> testInsert.json
            val name = BeanUtils.lineToHump(it)
            // 初始化新增文件,为inset.json的文件,若表中没有数据则更新
            if (name.endsWith("Insert.json")) {
    
    
                val bean = repositories[name.replace("Insert.json", "")]
                if (bean != null && bean.count() < 1) {
    
    
                    resources.add(ClassPathResource(String.format("mongo/%s", it)))
                }
                // 初始化更新文件,为update.json的文件,若表中有数据则更新,没有则是新增
            } else if (name.endsWith("Update.json")) {
    
    
                val bean = repositories[name.replace("Update.json", "")]
                if (bean != null) {
    
    
                    resources.add(ClassPathResource(String.format("mongo/%s", it)))
                }
            }
        }
        return resources
    }

    /**
     * CustomJackson2ResourceReader
     */
    class CustomJackson2ResourceReader : ResourceReader {
    
    
        private val resourceReader: Jackson2ResourceReader = Jackson2ResourceReader()
        override fun readFrom(resource: Resource, classLoader: ClassLoader?): Any {
    
    
            val result: Any
            result = try {
    
    
                resourceReader.readFrom(resource, classLoader)
            } catch (e: IOException) {
    
    
                logger.warn("Can't read from resource", e)
                return Collections.EMPTY_LIST
            }
            return result
        }

        companion object {
    
    
            private val logger = LoggerFactory.getLogger(CustomJackson2ResourceReader::class.java)
        }
    }

    /**
     * CustomJackson2RepositoryPopulatorFactoryBean
     */
    class CustomJackson2RepositoryPopulatorFactoryBean : Jackson2RepositoryPopulatorFactoryBean() {
    
    

        override fun getResourceReader(): ResourceReader {
    
    
            return CustomJackson2ResourceReader()
        }
    }
}

json文件

user_insert.json

[
  {
    
    
    "_class": "com.test.pojo.po.UserPO",
    "id": "132132123",
    "name": "小明",
    "age": "18"
  }
]

必须指定 “_class” 实体类,id在新增时可不指定,指定之后框架会判断这条记录为更新操作,虽然会新增一条记录,但是会影响@CreatedDate等标签的使用


userPO

@Document("user")
data class UserPO(
        /**
         * 主键
         */
        @Id
        val id: Long,
        /**
         * 应用id
         */
        val name: String,
	    /**
         * 年龄
         */
        val age: Int
}

UserDAO

interface UserDao : MongoRepository<UserPO, Long> 

Guess you like

Origin blog.csdn.net/qq_43278717/article/details/119273340