Mybatis 进阶学习

Mybatis 进阶学习

衔接上一篇 Mybatis基础

Mybatis简单入门:https://blog.csdn.net/qq_28863191/article/details/100847350

目录

resultMap

使用resultMap

动态sql

If 标签

Where 标签

Sql片段

 foreach 标签

关联查询

一对一查询

一对多查询


resultMap

resultType可以指定将查询结果映射为pojo,当pojo对象的属性名和 sql 中相应的表中对应的字段名一致时,才可以

Mybatis 进阶学习_第1张图片

当有属性名和 sql 中字段名不一致时,resultType无法获取该字段,输出null,这时我们就需要用 resultMap 来进行手动映射。

resultMap可以实现将查询结果映射为复杂类型的pojo(多表查询),resultType不行,它只能通过构建新的pojo对象的方式将多表联合起来。

例如:

数据库表如下图:

Mybatis 进阶学习_第2张图片

Order对象:

public class Order {
	// 订单id
	private int id;
	// 用户id
	private Integer userId;
	// 订单号
	private String number;
	// 订单创建时间
	private Date createtime;
	// 备注
	private String note;
get/set。。。
}

创建OrderMapper.xml配置文件,如下:

<mapper namespace="cn.itcast.mybatis.mapper.OrderMapper">

   

    <select id="queryOrderAll" resultType="order">

       SELECT id, user_id,

       number,

       createtime, note FROM `order`

    select>

mapper>

查询后因为 pojo 中是 userId, sql 中是 user_id,不能自动映射输出时就会得到 null 的结果

Mybatis 进阶学习_第3张图片

使用resultMap

由于上边的mapper.xml中sql查询列(user_id)和Order类属性(userId)不一致,所以查询结果不能映射到pojo中。

需要定义resultMap,把orderResultMap将sql查询列(user_id)和Order类属性(userId)对应起来

<mapper namespace="cn.itcast.mybatis.mapper.OrderMapper">

 

   

   

    <resultMap type="order" id="orderResultMap">

      

      

      

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

 

      

       <result property="userId" column="user_id" />

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

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

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

    resultMap>

 

   

    <select id="queryOrderAll" resultMap="orderResultMap">

       SELECT id, user_id,

       number,

       createtime, note FROM `order`

    select>

mapper>

注意:如果resultMap中只是单表的话,中可以将pojo对象的属性名和sql中字段名相同的属性省略不写,因为可以自动映射,但是resultMap中是多表时,不可省略

动态sql

通过mybatis提供的各种标签方法实现动态拼接sql。

需求:根据性别和名字查询用户

UserMapper.xml配置sql,如下:

<select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT id, username, birthday, sex, address FROM `user`

    WHERE sex = #{sex} AND username LIKE

    '%${username}%'

select>

If 标签

改造UserMapper.xml,如下:

<select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT id, username, birthday, sex, address FROM `user`

    <if test="sex != null and sex != ''">

       AND sex = #{sex}

    if>

    <if test="username != null and username != ''">

       AND username LIKE

       '%${username}%'

    if>

select>

上表中sex或者username没有时sql语句就会变成

    SELECT id, username, birthday, sex, address FROM `user` AND sex = #{sex}(或者 AND username LIKE           %${username}%')

虽然可以根据自己有没有传sex或者username来改变查询语句,但是and这个关键字会多出来导致sql语法错误,怎么办?

这时就需要 Where标签

Where 标签

<select id="queryUserByWhere" parameterType="user" resultType="user">

    SELECT id, username, birthday, sex, address FROM `user`

    <where>

       <if test="sex != null">

           AND sex = #{sex}

       if>

       <if test="username != null and username != ''">

           AND username LIKE

           '%${username}%'

       if>

    where>

select>

Where 标签 会将第一个有值的中的sql语句前面的and去掉,这样就不能报语法错误了

Sql片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

把上面例子中的 ----id, username, birthday, sex, address---- 提取出来,作为sql片段,如下:

<sql id="userFields">

    id, username, birthday, sex, address

sql>

 

<select id="queryUserByWhere" parameterType="user" resultType="user">

   

   

    SELECT <include refid="userFields" /> FROM `user`

   

    <where>

       <if test="sex != null">

           AND sex = #{sex}

       if>

       <if test="username != null and username != ''">

           AND username LIKE

           '%${username}%'

       if>

    where>

select>

如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xml的namespace

例如下图

Mybatis 进阶学习_第4张图片

 foreach 标签

向sql传递数组或List,mybatis使用foreach解析,如下:

根据多个id查询用户信息

查询sql:

SELECT * FROM user WHERE id IN (1,10,24)

 

 

改造QueryVo

如下图在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法

Mybatis 进阶学习_第5张图片

 

 

Mapper.xml文件

UserMapper.xml添加sql,如下:

<select id="queryUserByIds" parameterType="queryVo" resultType="user">

    SELECT * FROM `user`

    <where>

      

      

      

      

      

      

       <foreach collection="ids" item="item" open="id IN (" close=")"

           separator=",">

           #{item}

       foreach>

    where>

select>

关联查询

商品订单数据模型

 

Mybatis 进阶学习_第6张图片

一对一查询

通过order查询user,因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

SELECT

       o.id,

       o.user_id userId,

       o.number,

       o.createtime,

       o.note,

       u.username,

       u.address

FROM

       `order` o

LEFT JOIN `user` u ON o.user_id = u.id

使用resultMap,定义专门的resultMap用于映射一对一查询结果

改造pojo类

在Order类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。

改造Order如下图:

Mybatis 进阶学习_第7张图片

Mapper.xml

这里resultMap指定orderUserResultMap,如下:

<resultMap type="order" id="orderUserResultMap">

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

    <result property="userId" column="user_id" />

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

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

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

 

   

   

   

    <association property="user" javaType="user">

      

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

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

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

    association>

resultMap>

 

<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">

    SELECT

    o.id,

    o.user_id,

    o.number,

    o.createtime,

    o.note,

    u.username,

    u.address

    FROM

    `order` o

    LEFT JOIN `user` u ON o.user_id = u.id

select>

Mapper接口

编写UserMapper如下图:

Mybatis 进阶学习_第8张图片

测试方法,如下:

@Test

public void testQueryOrderUserResultMap() {

    // mybatis和spring整合,整合之后,交给spring管理
    SqlSession sqlSession = this.sqlSessionFactory.openSession();
    // 创建Mapper接口的动态代理对象,整合之后,交给spring管理
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    // 使用userMapper执行根据条件查询用户
    List list = userMapper.queryOrderUserResultMap();
    for (Order o : list) {
       System.out.println(o);

    }
    // mybatis和spring整合,整合之后,交给spring管理
    sqlSession.close();
}

一对多查询

案例:查询所有用户信息及用户关联的订单信息。

用户信息和订单信息为一对多关系。

sql语句:

SELECT

       u.id,

       u.username,

       u.birthday,

       u.sex,

       u.address,

       o.id oid,

       o.number,

       o.createtime,

       o.note

FROM

       `user` u

LEFT JOIN `order` o ON u.id = o.user_id

修改pojo类

在User类中加入List orders属性,如下图:

Mybatis 进阶学习_第9张图片

在UserMapper.xml添加sql,如下:

<resultMap type="user" id="userOrderResultMap">

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

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

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

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

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

 

   

    <collection property="orders" javaType="list" ofType="Order"(这是list中每一个元素的类型)>

      

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

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

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

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

    collection>

resultMap>

 

<select id="queryUserOrder" resultMap="userOrderResultMap">

    SELECT

    u.id,

    u.username,

    u.birthday,

    u.sex,

    u.address,

    o.id oid,

    o.number,

    o.createtime,

    o.note

    FROM

    `user` u

    LEFT JOIN `order` o ON u.id = o.user_id

select>

Mapper接口

编写UserMapper接口,如下图:

Mybatis 进阶学习_第10张图片

测试方法

在UserMapperTest增加测试方法,如下

@Test

public void testQueryUserOrder() {

    // mybatis和spring整合,整合之后,交给spring管理

    SqlSession sqlSession = this.sqlSessionFactory.openSession();

    // 创建Mapper接口的动态代理对象,整合之后,交给spring管理

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

 

    // 使用userMapper执行根据条件查询用户

    List list = userMapper.queryUserOrder();

 

    for (User u : list) {

       System.out.println(u);

    }

 

    // mybatis和spring整合,整合之后,交给spring管理

    sqlSession.close();

}

你可能感兴趣的:(Mybatis)