MyBatis高级

一、 动态SQL

概念:
   mybatis核心对sql语句进行灵活操作,通过表达式进行判断,
    对sql进行灵活拼接、组装。
 多条件的查询,需要使用SQL的拼接
 String sql="select * from book where 1=1";
 if(条件){
 sql+=" and 条件";
 }

存在问题:

  1. SQL中出现1=1条件可读性比较低
  2. 拼接容易出错
  3. 在DAO层出现大量if语句,代码比较乱
动态SQL的标签
<if>        进行条件判断
<where>     sql条件配置
<set>       update语句的配置
<trim>      添加和删除前缀和后缀文字
<foreach>   循环


<if>标签
  语法:
  SQL语句  <if test="条件">SQL语句</if>
   判断条件成立后,会将if内部的SQL语句和外部的SQL语句拼接起来

  <select id="selectByBook" parameterType="com.hp.mybatis.bean.Book">
     select * from book where
     <if test="bookName!=null and b_name!=''">
           b_name=#{b_name}
     </if>
  </select>
补充:MyBatis配置文件中配置启动日志
  <settings>
    <!--配置启动日志-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
  </settings>
问题:会出现多余的where和and

<where>标签
    作用是去掉多余的where、and、or
    语法:
      SQL语句:<where>
                 <if></if>
              </where>
<set>标签  
    作用是配置update语句中的set部分,帮助去掉多余的逗号
    举个例子:
        <update id="updateBook"parameterType="com.hp.bean.Book">
        update book
        <set>
            <if test="b_name!=null and b_name != ''">
                b_name=#{b_name},
            </if>
            <if test="b_author!=null and b_author != ''">
                b_author=#{b_author},
            </if>
            <if test="b_price > 0">
                and b_price=#{b_price};
            </if>
            <if test="b_image!=null and b_image != ''">
                b_image=#{b_image},
            </if>
            <if test="b_publish_date!=null and b_publish_date != ''">
                b_publish_date=#{b_publish_date},
            </if>
        </set>
        where b_id=#{b_id}
    </update>
<trim>标签
    作用是:添加和删除前缀和后缀
    语法:
    <trim prefix="添加的前缀" suffix="添加的后缀" prefixOverrides="删除的前缀" suffixOverrides="删除的后缀">
    </trim>
<foreach>标签
    作用是用于循环拼接SQL
    查询多个作者的书:
    select * from tb_book where book_author in ('张三','李四','王五')
    语法:
        <foreach collection="集合参数名" item="变量名" open="开始符号" close="结束符号" separator="分隔符" index="下标">
            #{变量名}
        </foreach>
    <select id="selectByAuthorNames" parameterType="java.util.List"
        resultMap="bookMap">
    select * from tb_book
    <where>
        book_author in
        <foreach collection="authorNames" item="name"
                 open="(" close=")" separator=",">
            #{name}
        </foreach>
    </where>
</select>
注意:集合参数需要使用@Param注解配置名称

二、关联查询

关系型数据库中表和表之间存在关系的
关系有三种:

  1. 一对一 (用户和身份证)
  2. 一对多 (一个人对应多门成绩)
  3. 多对多 (学生和课程,老师和学生)
    实现对象和对象之间关系(书籍和订单)
    书籍对象包含多个订单(订单集合)
    订单对象包含一个书籍对象
    配置方法:
    1)子查询
    查询两次:
    1)通过书籍id查询书籍
    2)通过书籍id查询订单
    2)关联查询
    查询一次,通过连接查询将书籍和订单一起查询
    子查询配置:
    1)在书籍类中定义订单集合属性,在订单类中定义书籍属性
    2)添加OrderMapper接口,定义根据书籍id查询订单的方法
        /**
 * 订单映射接口
 */
public interface OrderMapper {

    /**
     * 根据书籍id查订单
     * @param bookId
     * @return
     */
    List<TbOrder> selectOrdersByBookId(
            @Param("bookId")long bookId);
}
<?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">
<!--配置接口的映射,namespace命名空间设置为包名+接口名-->
<mapper namespace="com.hopu.mybatis.dao.OrderMapper">

    <!--配置结果映射 id是名称,type是实体类类名-->
    <resultMap id="orderMap" type="com.hopu.mybatis.entity.TbOrder">
        <!--配置主键,property是对象属性名,column表的列名,javatype是属性类型,jdbcType是列类型-->
        <id property="orderId" column="order_id" javaType="java.lang.Long" />
        <!--配置非主键列-->
        <result property="orderBookId" column="order_book_id"/>
        <result property="orderTime" column="order_time"/>
        <result property="orderNum" column="order_num"/>
        <result property="orderCustomerId" column="order_customer_id"/>
    </resultMap>

    <select id="selectOrdersByBookId" resultMap="orderMap"
            parameterType="java.lang.Long">
        select * from tb_order where order_book_id = #{bookId}
    </select>
</mapper>

3 ) 在书籍的映射文件中,在ResultMap中添加标签:

<collection>标签	配置一对多关系
<!--配置订单集合 property是集合属性名 ofType配置集合中对象的类型
        javaType配置集合的类型 select配置实现集合查询的方法 column是用于查询的集合的列-->
    <collection property="bookOrders"
            ofType="com.hopu.mybatis.entity.TbOrder"
            javaType="java.util.ArrayList"
            select="com.hopu.mybatis.dao.OrderMapper.selectOrdersByBookId"
            column="book_id"/>
4 ) 实现订单类中书籍属性的配置

```java
```java
    <association>标签	配置一对一关系
    <!--配置书籍对象一对一-->
<association property="orderBook"
             javaType="com.hopu.mybatis.entity.TbBook"
             select="com.hopu.mybatis.dao.BookMapper.selectById"
             column="order_book_id"/>

关联查询:
1)将所有的查询都改为关联查询
select * from tb_book b join tb_order o
    on b.book_id = o.order_book_id where book_id=#{bookId}
2)修改collection或association标签
   <collection property="bookOrders"
            ofType="com.hopu.mybatis.entity.TbOrder"
            javaType="java.util.ArrayList"
            column="book_id">
    <!--配置订单的映射-->
    <id property="orderId" column="order_id" javaType="java.lang.Long" />
    <!--配置非主键列-->
    <result property="orderBookId" column="order_book_id"/>
    <result property="orderTime" column="order_time"/>
    <result property="orderNum" column="order_num"/>
    <result property="orderCustomerId" column="order_customer_id"/>
</collection>

对比子查询和关联查询方式:
1)子查询执行两次,关联查询执行一次
2)子查询不需要修改查询语句,关联查询需要将所有查询语句改为关联查询
3)子查询支持延迟加载,关联查询不支持

延迟加载
也叫懒加载,按需加载,是MyBatis中的一种优化机制
当对象调用对应属性时,才执行属性的查询语句
在子查询可以使用,关联查询无法使用
默认情况下延迟加载是关闭的
配置方法:

    <!--启动延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--关闭积极加载-->
<setting name="aggressiveLazyLoading" value="false"/>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值