mybatis多表连查存在字段重名,造成数据异常

本文详细介绍了在Mybatis中遇到多表查询字段重名导致数据异常的问题,强调了字段重名对数据赋值的影响。提供了解决方案,包括避免字段重名、减少查询字段、使用字段别名以及手动配置映射关系,特别是推荐在mapper.xml中通过别名解决字段冲突,确保查询结果正确无缺失。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:多表查询出现字段重名的情况,在使用懒加载的模式,测试类中直接调用其中的一个字段,显示为null。

Mybatis中做多表联查的时候,不管是一对一、一对多、一对多对多:多对多:都不能有字段重名的情况:不管是主键还是普通字段。一旦字段重名的话,就会造成数据少自动赋值,或者覆盖,甚至重复赋值!

解决方法:
1.尽量不要表间重名,mybatis里处理起来很麻烦!id和普通字段都是。但是在表多的时候,很难不会出现字段重名的情况。主键id最容易重名!

2.在mybatis中写原生SQL进行查询的时候,查的字段尽可能的少,这也影响速率,强烈禁止使用*,用多少查多少!这样也能及时发现字段重名的情况!

3.最后如果真的需要查出重名的字段,并且修改数据库字段名造成的更改过大,这里推荐的方式是给字段取别名,在写resultMap映射的时候,其中的column属性就填写SQL语句中查出字段取的别名,这样就能解决重复问题了!

4.出现相同字段情况,可以根据情况在resultMap映射的时候手动配置一些属性。

修改的过程:

数据库中的表:

gtype表:
在这里插入图片描述
goods表:
在这里插入图片描述
两个表使用联合查询的时候:

GTypeMapper.xml:

<select id="selectById2" resultMap="gTypeResultMap">
          SELECT
            gtype.typeid,
            gtype.typename,
            goods.gid,
            goods.gname,
            goods.gprice,
            goods.gdecs,
            goods.typeid
        FROM
            goods
        INNER JOIN gtype ON goods.typeid = gtype.typeid
        WHERE
            gtype.typeid=#{typeid}
    </select>

    <resultMap id="gTypeResultMap" type="com.gx.model.GType" autoMapping="true">
        <association property="goods"
                     column="typeid"
                     javaType="com.gx.model.Goods"
                     select="com.gx.mapper.GoodsMapper.selectGoodsById"
                     fetchType="lazy">
        </association>
    </resultMap>

GoodsMapper.xml

<select id="selectGoodsById" resultType="goods">
         select
            *
         from
            goods
         where
            typeid=#{typeid}
    </select>

GTypeMapper.xml中的查询语句执行结果
在这里插入图片描述

结果存在两个相同的字段typeid。这个时候使用懒加载的形式进行获取的gtype的typeid的时候,就会出现值为null的情况。但实际上typeid的

值为1,这也是测试类传递的参数。

解决方案1:

修改GType类的属性名称

private Integer typeids;

在mapper.xml中查询语句起别名,对应到设置的属性上面。

<select id="selectById2" resultMap="gTypeResultMap">
          SELECT
            gtype.typeid as typeids,
            gtype.typename,
            goods.gid,
            goods.gname,
            goods.gprice,
            goods.gdecs,
            goods.typeid
        FROM
            goods
        INNER JOIN gtype ON goods.typeid = gtype.typeid
        WHERE
            gtype.typeid=#{typeid}
    </select>

然后重新进行测试,就会得到预想的结果。

解决方案2:(推荐)

多表查询的列如果存在相同的情况,就手动映射。

手动配置mapper的映射关系:

    <select id="selectById2" resultMap="gTypeResultMap">
            select
                *
            from
                gtype
            where
                typeid=#{typeid}
    </select>
    <resultMap id="gTypeResultMap" type="com.gx.model.GType" autoMapping="true">
        <!--手动配置-->
        <id property="typeid" column="typeid"/>
        <association property="goods"
                     column="typeid"
                     javaType="com.gx.model.Goods"
                     select="com.gx.mapper.GoodsMapper.selectGoodsById"
                     fetchType="lazy">
        </association>
    </resultMap>

GoodsMapper.xml

<select id="selectGoodsById" resultType="goods">
         select
            *
         from
            goods
         where
            typeid=#{typeid}
    </select>
总结:

查询的sql结果如果存在重复字段的情况,我们可以通过修改实体类的属性,或者手动配置属性的映射关系,

联合查询:good和gtype的结果。good中并没有相同的typeid的话,可以不用手动配置映射关系。

gtype的属性有typeid值,如果使用联合查询的情况,那么就需要手动配置映射关系。以免造成数据的缺失。

注意:即使没有使用懒加载,但是懒加载查询出来的字段存在相同的属性,也会出现null的情况

不手动配置映射关系

在这里插入图片描述

手动配置映射关系

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值