mybatis的resultMap的属性设置问题

mybatis的resultMap的属性设置问题,第1张

<resultMap id="checkAccountReturn" type="java.util.HashMap">

<id property="account_id" column="account_id" />

<result property="sub_account_id" column="sub_account_id"/>

<result property="status" column="status"/>

<result property="account_status" column="account_status"/>

<result property="total_count" column="total_count"/>

<result property="sms_sign" column="sms_sign"/>

</resultMap>

<select id="checkSub_account" resultMap="checkAccountReturn">

SELECT account_id,sub_account_id,status,account_status,total_count,sms_sign

FROM sub_account

<where>

<if test="account_id!=null">

account_id=#{account_id}

</if>

<if test="sub_account_id!=null">

and sub_account_id = #{sub_account_id} and status=1 and total_count!=0 and account_status=1

</if>

</where>

</select>

不知道你看得懂吗,看不懂call 我,O(∩_∩)O哈哈~!

MyBatis-Plus 对 MyBatis 基本零侵入,完全可以与 MyBatis 混合使用,这点很赞。

在涉及到关系型数据库增删查改的业务时,我比较喜欢用 MyBatis-Plus ,开发效率极高。具体的使用可以参考官网,或者自己上手摸索感受一下。

下面简单总结一下在 MyBatis-Plus 中如何使用 ResultMap 。

先看个例子:

有如下两张表:

其中, tb_hero 中的 bid 关联 tb_book 表的 id 。

下面先看 Hero 实体类的代码,如下:

注意了,我特地把 tb_hero 表中的 bid 字段映射成实体类 Hero 中的 bookId 属性

MyBatis-Plus 打印出的 SQL 为:

没毛病, MyBatis-Plus 会根据 @TableField 指定的映射关系,生成对应的 SQL 。

MyBatis-Plus 打印出的 SQL 为:

也没毛病,可以看到生成的 SELECT 中把 bid 做了别名 bookId 。

比如现在我想连接 tb_hero 与 tb_book 这两张表,如下:

查询 MyBatis-Plus 打印出的 SQL 为:

SQL没啥问题,过滤与分页也都正常,但是此时你会发现 bookId 属性为 null ,如下:

为什么呢?

调用 BaseMapper 中内置的 selectById() 方法并没有出现这种情况啊???

回过头来再对比一下在 HeroMapper 中自己定义的查询与 MyBatis-Plus 自带的 selectById() 有啥不同,还记得上面的刚刚的测试吗,生成的SQL有啥不同?

原来, MyBatis-Plus 为 BaseMapper 中内置的方法生成SQL时,会把 SELECT 子句中 bid 做别名 bookId ,而自己写的查询 MyBatis-Plus 并不会帮你修改 SELECT 子句,也就导致 bookId 属性为 null 。

在这里就是 tb_hero 表中的 bid 字段映射成实体类 Hero 中的 bid 属性。这样当然可以解决问题,但不是本篇讲的重点。

在 @TableName 设置 autoResultMap = true

然后在自定义查询中添加 @ResultMap 注解,如下:

这样,也能解决问题。

下面简单看下源码, @ResultMap("mybatis-plus_实体类名") 怎么来的。

详情见: com.baomidou.mybatisplus.core.metadata.TableInfo#initResultMapIfNeed()

注意看上面的字符串 id 的构成,你应该可以明白。

思考: 这种方式的 ResultMap 默认是强绑在一个 @TableName 上的,如果是某个聚合查询或者查询的结果并非对应一个真实的表怎么办呢?有没有更优雅的方式?

基于上面的思考,我做了下面简单的实现:

关键代码其实没有几行,耐心看下应该不难懂。

还是用例子来说明更直观。

下面是一个聚合查询:

其中 BookAgg 的定义如下,在实体类上使用了 @AutoResultMap 注解:

resultMap属性:type为java实体类;id为此resultMap的标识:<resultMap id="BaseResultMap" type="com.test.mybatis.vo.MybatisOrder" >

resultMap的子元素:

id – 一般对应到数据库中该行的ID,设置此项可以提高Mybatis性能.

result – 映射到JavaBean 的某个"简单类型"属性,String,int等.

association – 映射到JavaBean 的某个"复杂类型"属性,其他JavaBean类.

collection –复杂类型集合,a collection of complex types

比如现在有一个Order表,Customer表和OrderItem表,它们之间的关系为:一个Order关联到一个Customer(单向关联),一个Order有多个OrderItem(双向关联).

对应的Java对象文件为,public class MybatisOrder { .... private Mybatiscustomer customerprivate List<MybatisOrderItem>itemList.... public class MybatisOrderItem { private MybatisOrder order...对应的mapper文件为:

MybatiscustomerMapper.xml: <resultMap id="AssociationSelectMap" type="com.test.mybatis.vo.MybatisOrder" ><id column="ORDERID" property="orderid" jdbcType="DECIMAL" /><result column="ORDERTYPE" property="ordertype" jdbcType="VARCHAR" /><result column="ORDERDATE" property="orderdate" jdbcType="DATE" /><association property="customer" column="CUSTOMERID" select="com.test.mybatis.mapper.MybatiscustomerMapper.getCustomerByID"/><collection property="itemList" column="ORDERID" javaType="ArrayList" ofType="MybatisOrderItem" select="com.test.mybatis.mapper.MybatisOrderItemMapper.selectItemsByOrderID"/></resultMap><select id="getOrderByID" resultMap="AssociationSelectMap" parameterType="java.math.BigDecimal" >select *from MYBATISORDER where ORDERID = #{orderid,jdbcType=DECIMAL} </select>MybatisOrderItemMapper.xml: <resultMap id="AssociationMap" type="com.test.mybatis.vo.MybatisOrderItem" ><id column="ITEMID" property="itemid" jdbcType="DECIMAL" /><result column="ITEMTYPE" property="itemtype" jdbcType="VARCHAR" /><result column="ITEMQUANTITY" property="itemquantity" jdbcType="VARCHAR" /><result column="ITEMCOST" property="itemcost" jdbcType="VARCHAR" /><association property="order" column="ORDERID" select="com.test.mybatis.mapper.MybatisOrderMapper.getOrderByID"/></resultMap><select id="selectItemByID" resultMap="AssociationMap" parameterType="java.math.BigDecimal" >select *from MYBATISORDERITEMwhere ITEMID = #{itemid,jdbcType=DECIMAL} </select>MybatiscustomerMapper.xml:因为不和别的表做关联,只有简单的id,result配置. <resultMap id="BaseResultMap" type="com.test.mybatis.vo.Mybatiscustomer" ><id column="ID" property="id" jdbcType="DECIMAL" /><result column="NAME" property="name" jdbcType="VARCHAR" /></resultMap><select id="getCustomerByID" resultMap="BaseResultMap" parameterType="java.math.BigDecimal" >select *from MYBATISCUSTOMER where ID = #{id,jdbcType=DECIMAL} </select>MybatisOrderMapper的getOrderByID会先从MYBATISORDER取数据,然后根据CUSTOMERID调用MybatiscustomerMapper.getCustomerByID,然后根据ORDERID调用MybatisOrderItemMapper.selectItemsByOrderID,对应每一条MYBATISORDER数据,都会分别访问另外两个表各一次.

通过将association和collection的select功能替换为resultMap,再用join方式的SQL可以用一条SQL语句将关联数据取出来:


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/tougao/11238679.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-14
下一篇2023-05-14

发表评论

登录后才能评论

评论列表(0条)

    保存