mybatis常用操作

mybatis多个张表关联查询

订单的聚合根,一般情况下,一个订单的聚合根包括订单,收获地址,订单商品项,订单折扣,订单返利,卖家订单,支付信息等信息。那么我们如何通过mybatis把这些数据用一个sql查出来呢?

首先定义一个聚合根对象

@Data
public class PurchaseOrderAggregate implements Serializable {
    private PurchaseOrder purchaseOrder;
    private OrderAddress orderAddress;
    private List<OrderItem> orderItemList;
    private List<OrderDiscount> orderDiscountList;
    private List<OrderRebate> orderRebateList;
    private SaleOrder saleOrder;
    private OrderPayment orderPayment;
}

其次就是写关联关系的sql了

<?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.ytx.trade.domain.infrastructure.domain.BatchQueryMapper">
    <resultMap id="purchaseOrderAggregate" type="PurchaseOrderAggregate">
        <!-- 一对一的关系 -->
        <association property="purchaseOrder" javaType="PurchaseOrder">
            <id column="po_id" property="id"/>
            <result column="po_user_account_id" property="userAccountId"/>
        </association>
        <!-- 一对一的关系 -->
        <association property="orderPayment" javaType="OrderPayment">
            <result column="op_id" property="id"/>
            <result column="op_purchase_order_id" property="purchaseOrderId"/>
        </association>
        <!-- 一对一的关系 -->
        <association property="saleOrder" javaType="SaleOrder">
            <result column="so_id" property="id" />
            <result column="so_purchase_order_id" property="purchaseOrderId"/>
        </association>
        <!-- 一对一的关系 -->
        <association property="orderAddress" javaType="OrderAddress">
            <result column="oa_id"  property="id"/>
            <result column="oa_country_code" property="countryCode"/>
        </association>
        <!-- 一对多的关系 -->
        <collection property="orderDiscountList" ofType="OrderDiscount">
            <result column="od_id" property="id"/>
            <result column="od_purchase_order_id" property="purchaseOrderId"/>
        </collection>
        <!-- 一对一的关系 -->
        <collection property="orderItemList" ofType="OrderItem">
            <result column="oi_id" property="id"/>
            <result column="oi_purchase_order_id" property="purchaseOrderId"/>
        </collection>
    </resultMap>
    <!-- select语句 -->
    <select id="findOrdersByOrderNos" resultMap="purchaseOrderAggregate">
      SELECT
        po.id as po_id,
        po.serial_number as  po_serial_number,
        so.id as so_id,
        so.purchase_order_id as  so_purchase_order_id ,
        oi.id as  oi_id,
        oi.purchase_order_id as  oi_purchase_order_id ,
        op.id as op_id ,
        op.purchase_order_id as  op_purchase_order_id,
        oa.id as  oa_id ,
        oa.country_code as  oa_country_code,
        od.id as od_id,
        od.purchase_order_id as  od_purchase_order_id
      from purchase_order po
        LEFT JOIN sale_order so on po.id=so.purchase_order_id
        LEFT JOIN order_item oi on po.id=oi.purchase_order_id
        LEFT JOIN order_payment op on po.id=op.purchase_order_id
        LEFT JOIN order_address oa on po.order_address_id=oa.id
        LEFT JOIN order_discount od on po.id=od.purchase_order_id
      WHERE  po.serial_number in
        <foreach item="item" collection="list" separator="," open="(" close=")">
            #{item}
        </foreach>
    </select>
</mapper>

顺便提一个Lambda表达式转Map的案例

        List<PurchaseOrderAggregate> purchaseOrderAggregates = new ArrayList<>();

        PurchaseOrderAggregate purchaseOrderAggregate = new PurchaseOrderAggregate();
        PurchaseOrder purchaseOrder = new PurchaseOrder();
        purchaseOrder.setSerialNumber("ok");
        purchaseOrderAggregate.setPurchaseOrder(purchaseOrder);

        OrderAddress orderAddress = new OrderAddress();
        purchaseOrderAggregate.setOrderAddress(orderAddress);
        purchaseOrderAggregates.add(purchaseOrderAggregate);

        Map<String, PurchaseOrderAggregate> ss = 
            purchaseOrderAggregates.stream().collect(
            Collectors.toMap(x -> x.getPurchaseOrder().getSerialNumber(), x -> x));

mybatis字符串拼接问题

是关于#和$的使用的区别

name like  表达式  and  falg=#{falg}

本次示例中共两个条件,一个是name like 表达式, 还有flag相等,这个是使用#{}占位符,没有任何问题,关键问题就是 表达式的书写.下面来研究下表达式的书写:
如果写成’%#{name}%’ ,就会报错

Parameter index out of range (2> number of parameters, which is 1). 

为什么是这个错误呢?

1.表达式: name like”%”#{name}”%”

==>  Preparing: select * from bbs_brand WHERE namelike"%"?"%"and falg=? limit 0 , 10
==>Parameters: 莲(String), 1(Integer)

能够查询出来,没有问题,这是使用了占位符来占位,写成SQL就是: name like “%”’莲’”%”没有问题
2.表达式: name like ‘%${name}%’

Preparing:select count(0) from (select * from bbs_brand WHERE name like'%莲%' and falg=?) as total
Parameters: 1(Integer)

使用$进行字符串的拼接,直接把传入的值,拼接上去了,没有任何问题
3.表达式: name likeconcat(concat(‘%’,#{username}),’%’)

==>  Preparing: select count(0) from (select *from bbs_brand WHERE name like concat(concat('%',?),'%') and falg=?) as total
==>Parameters: 莲(String), 1(Integer)

这是使用了cancat进行字符串的连接,同时使用了#进行占位,转换成SQL就是:

name like CONCAT(CONCAT('%','莲'),'%')

3.表达式:name like CONCAT(‘%’,’${name}’,’%’)

==>  Preparing: select count(0) from (select *from bbs_brand WHERE name likeCONCAT('%','莲','%') and falg=?) astotal
==>Parameters: 1(Integer)

对上面的表达式进行了简化,更方便了
4.表达式:name like ‘%’||#{name}||’%’
这个不能满足要求,直接把数据库中的所有数据查询出来了,不符合我的要求,在mysql中||代表是or的意思

==>  Preparing: select count(0) from (select *from bbs_brand WHERE name like'%'||?||'%' and falg=?) as total
==>Parameters: 莲(String), 1(Integer)

关于$和#使用的第二个问题:
接口中方法:void deleteBrandByIds(@Param(“ids”)String ids);
xml中:

<!-- brand delete  -->
<delete id="deleteBrandByIds">
         <!-- update bbs_brand set is_display=0 where id IN (#{ids}) -->
update bbs_brand set is_display=0 where id IN (${ids})
</delete>

这里只能够使用$ 进行字符串的拼接,而不是#.
当我们传入的字符串是1,3,5,7的时候,用#只能删除id为1的品牌,其他的就不能删除了,这是因为,使用了#,就是一个占位符了,经过编译后是
where id in(?) 加入字符串后是 where id in(‘1,3,5,7’) 这种,在SQL中就只会删除一个,我们来看SQL的执行效果也是只是删除一条记录的,
所以如果想使用#,请在xml中使用动态的SQL,,传递的参数使用List来进行循环遍历.

foreach

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
foreach元素的属性主要有 item,index,collection,open,separator,close。

item表示集合中每一个元素进行迭代时的别名,
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔 符,
close表示以什么结束。

在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:

1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可

以封装成map,实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key 下面分别来看看上述三种情况的示例代码:
1.单参数List的类型:

<select id="dynamicForeachTest" parameterType="java.util.List" resultType="Blog">
    select * from t_blog where id in
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
        #{item}       
    </foreach>    
</select>

上述collection的值为list,对应的Mapper是这样的

public List dynamicForeachTest(List ids);
@Test
public void dynamicForeachTest() {
    SqlSession session = Util.getSqlSessionFactory().openSession();      
    BlogMapper blogMapper = session.getMapper(BlogMapper.class);
    List ids = new ArrayList();
    ids.add(1);
    ids.add(3);
    ids.add(6);
    List blogs = blogMapper.dynamicForeachTest(ids);
    for (Blog blog : blogs)
        System.out.println(blog);
    session.close();
}

2.单参数array数组的类型:

<select id="dynamicForeach2Test" parameterType="java.util.ArrayList" resultType="Blog">
     select * from t_blog where id in
     <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
          #{item}
     </foreach>
</select>

上述collection为array,对应的Mapper代码:

public List dynamicForeach2Test(int[] ids);

对应的测试代码:

@Test
public void dynamicForeach2Test() {
    SqlSession session = Util.getSqlSessionFactory().openSession();
    BlogMapper blogMapper = session.getMapper(BlogMapper.class);
    int[] ids = new int[] {1,3,6,9};
    List blogs = blogMapper.dynamicForeach2Test(ids);
    for (Blog blog : blogs)
        System.out.println(blog);    
    session.close();
}

3.自己把参数封装成Map的类型

<select id="dynamicForeach3Test" parameterType="java.util.HashMap" resultType="Blog">
    select * from t_blog where title like "%"#{title}"%" and id in
    <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
    #{item}
    </foreach>
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值