栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis开发中遇到的问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis开发中遇到的问题

最近在使用Mybatis的过程中遇到了一些问题,感觉有必要总结一下。前面一段时间简单的看了一点Mybatis的源码,对Mybatis在项目启动过程中以及启动后执行查询的工作流程有了一个大概的了解。这周开始我又到另一个项目,这是一个微服务项目,不过我只参与了一个服务的开发,项目使用的是Mybatis,但是并不是使用xml的方式,而是注解的方式,这也是我第一次在项目中使用注解的方式开发,中间也遇到了一些问题,这里做一个总结。
其实在前面Mybatis源码分析(一)的过程中有提到过Mybatis的注解,但是我一直习惯使用xml方式,所以并没有专门去了解注解的方式。这次总结主要还是专注于使用中遇到的问题。

一、一对多查询问题。

开发这么久也是我第一次需要使用一对多查询,为了方便我自己写了一点简单的代码,来模拟这样一个问题。首先我有2个model,分别是order和product,从业务上来讲我一个订单可能有多个product,所以model的定义如下:

@Data
public class Order {
    private String userid;

    private String province;

    private String city;

    private String street;

    private String orderid;
}

@Data
public class Product {
    private String orderid;

    private String productname;

    private Integer count;

    private String price;

    private String skucode;

}
@Data
public class CustomOrder {
    private String userid;

    private String province;

    private String city;

    private String street;

    private String orderid;

    private List productList;
}

CustomOrder中有一个productList的属性,存储的是某订单所有Product的skucode属性。当然productList也可以是所有商品的全部属性。

1、使用Mapper.xml文件 1.1 多表查询

其实首先容易想到的就是关联表查询,sql如下:

select o.*,p.skucode from t_order o left join t_product p on o.orderid = p.orderid  where o.userid = ?;

查询的结果如下:

图-1.png

其实这个结果并不是我想要的,我希望最后一列的skucode多行数据转一行数据,即根据userid等列分组,也就是这种结果:

图-2.png


这个方式可以直接通过sql的方式实现,我们如果使用Mybatis的xml方式又该如何实现呢?其实查询的sql并不需要改变,只需要在进行结果映射的时候将查询的skucode放入到映射的model的productList属性即可,即映射到CustomOrder的productList属性中,xml如下:


  
    
    
    
    
    
    
      
    
  

  
    userid, province, city, street, orderid
  

  
    select o.*,p.skucode
    from t_order o left join t_product p on o.orderid = p.orderid where o.userid = #{userId}
  

上面的xml中最主要的就是""标签,"property"表示的是映射的model的属性,即CustomOrder的属性名称,ofType表示的是映射的集合中类型的名称,javaType表示的是集合类型,里面的还有多个标签,""标签中表示的是查询结果,这个需要sql中的列对应,比如sql中查询的列是skucode,那么"result"的column也必须是skucode。接下来通过一个接口测试一下,结果如下图:

图-3.png


下面是控制台输出的sql:

图-4.png


其实根据上图输出的sql就可以看出来,这种方式和我们一开始使用sql进行查询的结果是完全一样的(废话,sql的都一样,结果肯定一样),唯一的区别就是Mybati在输出结果的映射上帮我们进行了处理,即将skucode这一列的结果帮我们转成了一个List

另外xml中除了""标签,也可以使用""标签,这两个标签的作用应该是相同的。感兴趣的可以试一下。
如果productList存放的就是Product的所有属性,CustomOrder的productList改为List。然后将sql和""标签内容修改一下即可,xml修改如下:


  
    
    
    
    
    
    
      
      
      
      
      
    
  

  
    userid, province, city, street, orderid
  

  
    select *
    from t_order o where o.userid = #{userId}
  

根据上面的OrderMapper.xml文件可以看出,sql变成了单表查询,之查询t_order表,而在结果映射里面依然是使用""标签,但是添加了一个"select"和"column"属性。先说"column"属性,这个表示的是"select"查询事需要传入的参数的列名,因Order和Product是通过orderid属性关联的,因此"column"的属性值就是orderid列;"select"表示的是执行的具体sql,因为我这里跨了不同的xml文件,所以必须使用namespace + id。需要在ProductMapper.xml添加一个查询方法,ProductMapper.xml如下:


  
    
    
    
    
    
  

  
    orderid, productname, count, price, skucode