Mybatis的动态sql语句,联表实现

动态sql

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

需求:根据性别和名字查询用户
查询sql:select * from user WHERE 1=1 and uname LIKE “%刘%” and uage = 20
If标签
Mapper.xml文件
UserMapper.xml配置sql,如下:(根据姓名模糊,年龄查询)

SELECT * FROM USER
WHERE 1=1
AND uname LIKE “%”#{uname}"%"
AND uage = #{uage}

Mapper接口
编写Mapper接口,如下图:
public interface UserMapper {
/**
* 根据uname模糊,uage 进行查询
*/
List getUsersByNameAge(User user);
}

测试方法
在UserMapperTest添加测试方法,如下:
/**

  • 测试sql动态拼接
    */
    private void fun1() {
    SqlSession session = factory.openSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    List userList =
    mapper.getUsersByNameAge(new User(null, “赵”, 30));
    for(User user : userList){
    System.out.println(user);
    }
    }
    使用if标签
    改造UserMapper.xml,如下:


    SELECT * FROM USER
    WHERE 1=1

    AND uname LIKE “%”#{uname}"%"


    AND uage = #{uage}


注意字符串类型的数据需要要做不等于空字符串校验。
Where标签
上面的sql还有where 1=1 这样的语句,很麻烦
可以使用where标签进行改造

改造UserMapper.xml,如下

SELECT * FROM USER AND uname LIKE "%"#{uname}"%" AND uage = #{uage}

Sql片段

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

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

<sql id="cols">
    uid,uname,uage
</sql>
<!-- 根据uname,uage查询User-->
<select id="getUsersByNameAge" resultType="User">
    <!-- include: 引用sql片段
                refid:sql片段的id-->
  SELECT  <include refid="cols"/>  FROM USER
    <where>
        <if test="uname!=null and uname!=''">
            AND uname LIKE "%"#{uname}"%"
        </if>
        <if test="uage!=null and uage!=''">
            AND uage = #{uage}
        </if>
    </where>
</select>

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

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

根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)

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

Mapper.xml文件
UserMapper.xml添加sql,如下:

SELECT uid,uname,uage FROM USER WHERE uid
<foreach collection="ids2" separator="," item="id" open="IN (" close=")">
    ${id}
</foreach>
;

测试方法如下图:
/**

  • 测试foreach2
    /
    private void fun3() {
    SqlSession sqlSession = factory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    QueryVo queryVo = new QueryVo();
    /
    Integer[] ids = {1,3,4,6,18,11};
    queryVo.setIds1(ids);*/

    List ids = new ArrayList();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    queryVo.setIds2(ids);
    List userList = mapper.getUsersByIds(queryVo);
    for(User user : userList){
    System.out.println(user);
    }
    }
    /**

  • 测试foreach1
    */
    private void fun2() {
    SqlSession sqlSession = factory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

/* Integer[] ids = {1,3,4,6,18,11};
List userList = mapper.getUsersByIds(ids);
for(User user : userList){
System.out.println(user);
}*/

List ids = new ArrayList();
ids.add(1);
ids.add(2);
ids.add(3);
List userList = mapper.getUsersByIds(ids);
for(User user : userList){
System.out.println(user);
}
}

关联查询

商品订单数据模型

一对一查询
需求:查询所有订单信息,关联查询下单用户信息。

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

sql语句:
SELECT user.uid,uname,uage,oid,oname,odate
FROM order1 LEFT JOIN USER
ON order1.uid=user.uid

方法一:使用resultType
使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息
这样返回对象的时候,mybatis自动把用户信息也注入进来了
改造pojo类
OrderUser类继承Order类后OrderUser类包括了Order1类的所有字段,只需要定义用户的信息字段即可,如下:
public class OrderUser extends Order1 implements Serializable {
static final long serialVersionUID = 42L;
private String uname;
private Integer uage;
…… ……
}
OrderMapper.xml
在UserMapper.xml添加sql,如下

SELECT user.uid,uname,uage,oid,oname,odate
FROM user RIGHT JOIN order1
ON order1.uid=user.uid

Mapper接口
在UserMapper接口添加方法,如下图:

测试方法:
在UserMapperTest添加测试方法,如下:
/**

  • 测试

  • 方法一(扩充原实体类)查询order信息对应的信息及用户信息
    */
    private void fun1() {
    // 4.
    SqlSession sqlSession = factory.openSession();
    //
    OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);

    List orderUserList = mapper.getOrderUser();
    for(OrderUser ou : orderUserList){
    System.out.println(ou.getOname() + " ==" + ou.getUname());
    }
    sqlSession.close();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值