MongoDB进阶(十)去除Spring Data生成的_class字段并同时配置类型转换器
【前言】
实不相瞒,当初在使用MongoDB的时候这个问题我也遇到过,但因为项目着急,就暂且的没去管它。直到昨天有个小伙伴儿问起我这个问题,我才想起来Word天,我也没解决,今天有空摸索了一下,最终有了答案,在此感谢这位小伙伴~!
1.心路历程
老司机温馨提示:本模块无重点,解决方案请直奔最后一题!
用过MongoDB以及Spring Data MongoDB(以下就简称Spring Data吧,太长惹....)的童鞋,可能都知道这个情况:在往数据库中保存一条记录时,Spring Data会自动帮我们生成一个字段就是“_class”,官方文档中介绍:……算了,巴拉一堆,说白了,就是存储了一个长类名,目的就是方便转换为Java实体对象的具体类;
但有时候我们确实不需要这个字段的存在(自动脑补出“不存在的”表情包...),于是乎,百度吧,balabala....就有了如下方案:
这种配置确实行得通,可以完美去除“_class”字段,但如果你又同时有以下的需求,就尴尬了.....
因为Spring Data默认不支持从java.util.Date 转换为java.sql.Timestamp,所以需要自定义转换器,于是又有了下面的配置:
辣么问题来了,这两个配置怎么合并?继续翻官方,就给了这么一个简单的配置啊喂?
诶,等等,type-mapper-ref属性什么鬼,好像可以搞搞事情,接着加到配置里面,发现……
WTF?属性不支持?那应该就是xsd文件约束的问题,果然....
2.问题原因
这完全就是spring-mongo-1.0.xsd在作怪好伐!打开 这里 可以看到如下几个版本的xsd文件:
是xsd文件的版本不一致造成的 type-mapper-ref 属性不能使用,经测,1.10.2以上全部都支持type-mapper-ref属性,但是!在某些如1.6、1.9、2.0版本的xsd文件中,一些其他的标签属性也做了改变,比如<mongo:mongo>换成了<mongo:mongo-client>等等,也是醉了,官方能不能都统一一下?
3.解决方案
将spring配置文件schema中的spring-mongo-1.0.xsd改为spring-mongo-1.3.xsd(我这里用1.3版本比较合适,可自行尝试),最终配置完成的整个xml文件如***意注释部分:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mongo="http://www.springframework.org/schema/data/mongo"
- xsi:schemaLocation="http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/data/mongo
- http://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <!-- 读取属性文件 -->
- <context:property-placeholder location="classpath:db.properties" />
- <!-- 启用注解支持 -->
- <context:annotation-config />
- <!-- 扫描组件包 -->
- <context:component-scan base-package="com.jastar.demo" />
- <!-- 默认Mongo类型映射类 -->
- <bean name="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
- <!-- 去除默认生成“_class”字段的关键,即:将该类带有typeKey参数的构造函数的参数值设置为null即可 -->
- <constructor-arg name="typeKey"><null/></constructor-arg>
- </bean>
- <!-- MongoDB类型转换器,可自定义扩展类型之间的转换,注意“type-mapper-ref”属性 -->
- <mongo:mapping-converter id="mongoConverter" type-mapper-ref="defaultMongoTypeMapper">
- <mongo:custom-converters>
- <mongo:converter>
- <bean class="com.jastar.demo.converter.TimestampConverter" />
- </mongo:converter>
- <!-- allow more... -->
- </mongo:custom-converters>
- </mongo:mapping-converter>
- <!--
- MongoDB配置部分
- 1.mongo:连接配置
- 2.db-factory:相当于sessionFactory
- 3.mongoTemplate:与数据库接口交互的主要实现类
- -->
- <mongo:mongo host="${mongo.host}" port="${mongo.port}">
- <mongo:options
- connections-per-host="${mongo.connectionsPerHost}"
- threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
- connect-timeout="${mongo.connectTimeout}"
- max-wait-time="${mongo.maxWaitTime}"
- auto-connect-retry="${mongo.autoConnectRetry}"
- socket-keep-alive="${mongo.socketKeepAlive}"
- socket-timeout="${mongo.socketTimeout}"
- slave-ok="${mongo.slaveOk}"
- write-number="${mongo.writeNumber}"
- write-timeout="${mongo.writeTimeout}"
- write-fsync="${mongo.writeFsync}" />
- </mongo:mongo>
- <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongo" />
- <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
- <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
- <constructor-arg name="mongoConverter" ref="mongoConverter" />
- </bean>
- </beans>