在我们平常开发操作数据库时,查询、插入数据等操作行为,有时会报数据类型不匹配异常,就可以得知数据的类型是不唯一的必然是多种不同的数据类型。并且我们必须要明确的一点就是java作为一门编程语言有自己的数据类型,数据库也是有自己的数据类型的。
jdbc数据类型:org.apache.ibatis.type.JdbcType 此枚举就是所有的数据库支持类型
java数据类型:int、long、string、…
一定要分清,例如java重的date数据插入到数据库中,应该是已经转换成了数据库的某种类型,必然跟java已经没有关系了。中间有一些我们看不见的操作做了数据处理。
假设此时的java类型与数据库数据类型是一样的,哪么其他语言中的日期数据插入数据库时又该怎么解释,例如C#操作数据库存入时间类型,C#与java肯定没有关系吧。所以每种语言与数据库之间有种数据类型关系对应。
思考:
因为java与数据库各自有数据类型,所以在将java数据存入数据库前中间是否有其他操作,是我们看不见的,不然java数据怎么知道自己与哪个jdbc数据类型匹配?
答:mybatis框架为每种数据类型做了默认的关系对应,BaseTypeHandler的所有实现类,就是来做这些处理的。
例如:java中的date插入数据库时是jdbc哪种类型,怎么就是这种类型? 中间具体有什么操作?
答:DateTypeHandler就是来解决date数据类型的处理。
我们想要自定义去处理Java和JDBC的数据类型转换时,需要实现TypeHandler接口,该接口源码如下:
1 2 3 4 5 6 7 8 9 |
//此接口作用是用于指定jdbc与java的数据类型间对应关系处理。 public interface TypeHandler<T> { // 保存操作,数据入库之前时数据处理 void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; //下面三个则是,从数据库加载数据后,vo对象封装前的数据处理 T getResult(ResultSet rs, String columnName) throws SQLException; T getResult(ResultSet rs, int columnIndex) throws SQLException; T getResult(CallableStatement cs, int columnIndex) throws SQLException; } |
JsonIntegerTypeHandler 实现Integer和字符串互转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public class JsonIntegerTypeHandler extends BaseTypeHandler<Integer> { private static final ObjectMapper mapper = new ObjectMapper();
@Override public void setNonNullParameter(PreparedStatement ps, int i, Integer parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, toJson(parameter)); }
@Override public Integer getNullableResult(ResultSet rs, String columnName) throws SQLException { return this.toObject(rs.getString(columnName)); }
@Override public Integer getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return this.toObject(rs.getString(columnIndex)); }
@Override public Integer getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return this.toObject(cs.getString(columnIndex)); }
private String toJson(Integer params) { try { String copyObject = IotDbUtils.copyObject(params); return copyObject; } catch (Exception e) { e.printStackTrace(); } return ""; }
private Integer toObject(String content) { if (content != null && !content.isEmpty()) { try { System.out.println("1111111111111"+content); return (Integer) mapper.readValue(content, Integer.class); } catch (Exception e) { throw new RuntimeException(e); } } else { return null; } } } |
查询的时候 你转的那个字段就配置哪个字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<resultMap id="DmpDeviceReportResult" type="com.chinaunicom.iotdb.domain.DmpDeviceReportInformation" > <result column="Time" property="timestamp" />
<result column="type" jdbcType="INTEGER" property="type" typeHandler="com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler"/>
</resultMap>
<select id="listDeviceReportInformation" resultMap="DmpDeviceReportResult"> select trace_id, imei, topic, information, interaction_time,type from dmp_device_report_information where imei = #{serialNumber} <if test="beginTime != null and endTime != null"> and interaction_time between #{beginTime} and #{endTime} </if> <if test="traceId != null and traceId != ''"> and trace_id = #{traceId} </if> limit #{pageSize} offset #{pageNum} </select> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<insert id="add" parameterType="com.chinaunicom.iotdb.domain.DmpDeviceReportInformation"> INSERT INTO root.device.dmp_device_report_information <trim prefix="(" suffix=")" suffixOverrides=","> <if test="null != type "> type, </if> <if test="null != traceId and '' != traceId"> trace_id, </if> <if test="null != imei and '' != imei"> imei, </if> <if test="null != topic and '' != topic"> topic, </if> <if test="null != information and '' != information"> information, </if> <if test="null != interactionTime and '' != interactionTime "> interaction_time, </if> <if test="null != organizationId "> organization_id </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="null != type "> #{type,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> <if test="null != traceId and '' != traceId"> #{traceId,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> <if test="null != imei and '' != imei"> #{imei,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> <if test="null != topic and '' != topic"> #{topic,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> <if test="null != information and '' != information"> #{information,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> <if test="null != interactionTime and '' != interactionTime "> #{interactionTime,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> <if test="null != organizationId "> #{organizationId,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler }, </if> </trim> </insert> |
类注解 @TableName(autoResultMap = true)
参数注解 @TableField(typeHandler = JsonIntegerTypeHandler.class)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Data @TableName(autoResultMap = true) public class DmpDeviceReportInformation implements Serializable { private static final long serialVersionUID = 1L;
private Long id;
/** * 消息类型1:消息上报 2:消息下发 */ @TableField(typeHandler = JsonIntegerTypeHandler.class) private Integer type; } |
注意: 如果使用自己的mapper查询 要选择mybaits的形式
1 2 |
mybatis-plus: type-handlers-package: com.chinaunicom.iotdb.handler |