baomidou / mybatis-plus

An powerful enhanced toolkit of MyBatis for simplify development
https://baomidou.com
Apache License 2.0
16.41k stars 4.31k forks source link

@TableField的typeHandler = JacksonTypeHandler.class 映射数据库中的json字段到java 实体类只对BaseMapper中的查询方法有效 #6049

Closed ghost closed 7 months ago

ghost commented 7 months ago

当前使用版本(必填,否则不予处理)

implementation 'com.baomidou:mybatis-plus-spring-boot3-starter:3.5.6'

该问题是如何引起的?(确定最新版也有问题再提!!!)

@TableField的typeHandler = JacksonTypeHandler.class 映射数据库中的json字段到java 实体类只对BaseMapper中的查询方法有效 自定义的查询方法没有映射json字段

重现步骤(如果有就写完整)


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import org.apache.ibatis.type.JdbcType;

import java.util.List;

@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
@ToString
@TableName(autoResultMap = true)
public class Test {
    @TableId(type = IdType.AUTO)
    private long id;
    private String name;
    private byte age;

    @TableField(typeHandler = JacksonTypeHandler.class, jdbcType = JdbcType.VARCHAR)
    private List<TestListEntry> list;
    @TableField(typeHandler = JacksonTypeHandler.class, jdbcType = JdbcType.VARCHAR)
    private TestMap map;
}

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
public class TestMap {
    private long left;
    private long right;
}

import lombok.*;

@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
@ToString
public class TestListEntry {
    private long width;
    private long height;
}

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface TestMapper extends BaseMapper<Test> {

    List<Test> selectAll();

}
<?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="TestMapper">

    <select id="selectAll" resultType="Test">
        select * from test
    </select>
</mapper>

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @Autowired
    private TestMapper testMapper;

    public void test() {

        testMapper.selectAll();
        System.out.println(testMapper.selectAll());

    }

}
#test.json

create table test
(
    id           bigint auto_increment
        primary key,
    name         varchar(32)     default ''                 not null,
    age          tinyint         default 0                  not null,
    list         json            default (json_array())     not null,
    map          json            default (json_object())    not null,
    creationTime bigint unsigned default (unix_timestamp()) not null
);

INSERT INTO v3.test (id, name, age, list, map, creationTime) VALUES (1, 'ok', 2, '[{"width": 100, "height": 200}]', '{"left": 20, "right": "56"}', 1712707965);
INSERT INTO v3.test (id, name, age, list, map, creationTime) VALUES (2, 'jjjj', 4, '[{"width": 300, "height": 300}, {"width": 150, "height": 600}, {"width": 100, "height": 900}, {"width": 75, "height": 1200}, {"width": 60, "height": 1500}, {"width": 50, "height": 1800}, {"width": 42, "height": 2100}, {"width": 37, "height": 2400}, {"width": 33, "height": 2700}, {"width": 30, "height": 3000}]', '{"left": 666, "right": 777}', 1712721060);

报错信息

testMapper.selectAll();查询到的数据list和map字段都是null [Test(id=1, name=ok, age=2, list=null, map=null), Test(id=2, name=jjjj, age=4, list=null, map=null)]

如果想让自己的写的查询方法也能自动映射json字段 只有在mapper.xml文件中明确设置ResultMapper的typehandler


<?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="TestMapper">

    <resultMap id="testObj" type="Test">
        <result column="map" property="map" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
        <result column="list" property="list" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
    </resultMap>

    <select id="selectAll" resultMap="testObj">
        select * from test
    </select>
</mapper>
nieqiurong commented 7 months ago

必须用resultmap