byodian / all-in-github

Manage All Personal Data with Github
https://all-in-github-byodian.vercel.app
MIT License
2 stars 0 forks source link

日志 #24

Open byodian opened 5 months ago

byodian commented 5 months ago

mybatis-plus 将 Java 对象保存为 json 类型数据。使用 typeHandler 类型处理器处理 JavaType 与 JdbcType 之间的转换

借助 TableField 注解快速注入 typeHandler 到 mybatis 容器中。这种注解的方式需要开启类型映射注解 @TableName(autoResultMap = true)

实际测试发现 mybatis-plus BaseMapper 接口定义的方法会自动使用 typeHandler 处理 JavaType 与 JdbcType 的转换。

@TableName(value = "user", autoResultMap = true)
@Data
public User {
    private Long id;
    // com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Object userInfo;
}

Mybatis 动态 SQL 语句不会自动应用 typeHandler,需要 Java 类型中单独指定 typeHandler,这种方式不需要开启自动映射注解。比如在批量插入中,将 Object 对象值插入到类型为 json 的字段中。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserMapper">
    <insert id="batchInsert" >
        INSERT INTO user (username, userinfo)
        VALUES
        <foreach collection="userList" item="user" separator=",">
            (#{user.username},
            #{user.userinfo, typeHandler = com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler})
        </foreach>
    </insert>
</mapper>
// com.example.demo.dao.UserMapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
    void batchInsert(@Param("userList") List<User> userList);
}
@TableName(value = 'user')
@Data
public User {
    private Long id;
    private String username;
    private Object userinfo;
}

如果没有指定 typeHandler 会报错: org.apache.ibatis.type.TypeException: Error setting non null for parameter with JdbcType null. Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.sql.SQLException: Invalid argument value: java.io.NotSerializableException

byodian commented 5 months ago

Mybaits-plus 默认开启 mapunderscoretocamelcase 驼峰命名规则映射。当 mapunderscoretocamelcasetrue ,java 类中的字段定义为小写下划线规则时,这个 java 类不能成功接收到 mybatis 查询的结果。比如:

<select id="getAlarmCountToday" resultType="com.example.demo.device.model.SomeResponse">
    SELECT
        SUM(IF(DATE(alarm_time) = CURRENT_DATE AND alarm_type = 'c_alms', 1, 0)) AS c_alms,
        SUM(IF(DATE(alarm_time) = CURRENT_DATE AND alarm_type = 'b_alms', 1, 0)) AS b_alms,
        SUM(IF(DATE(alarm_time) = CURRENT_DATE AND alarm_type = 'n_alms', 1, 0)) AS n_alms
    FROM device_alarm_record
    WHERE tenant_id = #{tenantId}
</select>
@Data
public SomeResponse {
    private String n_alms;
    private String c_alms;
    private String b_alms;
}