MyBatis---动态SQL及关联映射

动态SQL是MyBatis的重要特性,能够在映射文件的SQL语句中,加入逻辑判断,自动拼接SQL,从而实现复杂的功能。

动态SQL语句的标签:

  <if>                 基本的条件判断
<where>                配置查询条件
 <set>                 配置update语句
 <trim>                自定义条件配置
<foreach>              循环标签

   <if>标签:

          作用:当条件成立,if中的SQL语句会和外面SQL语句拼接到一起

          语法:   

SQL语句
<if test="条件">
SQL语句
</if>
          示例:
         <select id="selecUser" parameterType="User" >
             select * from tb_user where
             <if test="username != null">
                username = #{username}
             </if>
             <if test="realname != null">
                and realname = #{realname}
             </if>
          <select>

        问题:username为空且realname不为空时,会出现多余的and或where

   <where>标签

        作用:自动添加where,去掉多余的and、or、where

        语法:    

sql语句
<where>
  <if test="条件">
   sql语句
  </if>
</where>                
        示例:
               <select id="selecUser" parameterType="User" >
                     select * from tb_user 
                     <where>
                          <if test="username != null">
                             username = #{username}
                          </if>
                     </where>
                <select >       

    <set>标签

       用于update语句,作用是:自动添加set,去掉多余的,

       语法:
             <update>
                 update tb_user 
                  <set>
                     <if test="username != null  and username !=' ' ">
                        username = #{username}
                     </if>
                     <if test="phone!= null  and phone!=' ' ">
                        and phone= #{phone}
                     </if>
                   </set>
                  where user_id = #{userId}
              </update>            

   <trim>标签

           作用:灵活配置添加前缀、后缀,删除前缀、后缀

           语法:使用<trim>代替<set>

                     <trim prefix="添加前缀" suffix="添加后缀" prefixOverride="删除前缀" suffixOverride="删除后缀">
   示例:
<update id="update" parameterType="com.mx.mybatis.entity.User">
    update tb_user
     <trim prefix="set" suffixOverrides=",">
           <if test="userId!=null and userId!=''">
                user_id = #{userId},
           </if>
           <if test="username!=null and username!=''">
                username = #{username},
           </if>
      </trim>
    where user_id = #{userId}
</update>

   <foreach>标签

     作用:循环添加SQL语句

     语法:<foreach collection="参数集合名" item="变量名" open="开始符号" close="结束符号" 

                   separator="分隔符" index="下标名">        

     注意:集合参数前添加@Param("名称")

               List<User> selectUserByUsernames(@Param("usernames") List<String>  usernames)

  示例:  
  <select id="selectUserByUsernames" resultMap="userMap">
       select * from tb_user
       where username in
         <foreach collection="usernames"  item="name" open="("  close=")"
                  separator="," index="index">
                #{name}
         </foreach>
  </select>

对象的关联映射

  对象之间的关联关系有:

          一对一 如:用户和身份证

          一对多 如:用户和评论,商品和订单

          多对多 如:学生和课程

    通过映射文件,实现对象和对象的关系

  配置方式:

            方式一:子查询

                       1. 查询用户

                       2. 按用户id查询用户所有评论

              方式二:连接查询

                    内连接直接一次查询到两个表的数据

        子查询:

       配置查找用户所有的评论

               1.在用户类添加评论的集合属性,并添加set、get方法

            2.在CommentDao中定义按用户id查询评论的方法并在XML中实现

            3.修改UserMapper.xml

                 在resultMap添加标签<collection>

                 collection 用于配置一对多关系的集合

                 property 配置集合名称 

                 column配置查询集合需要的列

                 select配置查询集合需要的方法   包名.类名.方法名

  

          配置通过评论找到用户

          1.在评论类添加用户对象属性,并添加set、get方法

          2. 在UserDao中定义按用户id查询用户的方法并在XML中实现

          3.修改CommentMapper.xml

             在resultMap添加标签<association>用于配置一对一关系的对象

       <!--配置一对一的用户对象-->

      <association property="user" column="user_id" select="com.qianfeng.mybatis.dao.UserMapper.selectById"/>

连接查询:

        查询用户所有评论

        1.在用户类添加评论的集合属性,并添加set、get方法

        2.修改UserMapper.xml

              在resultMap添加标签<collection>

              ofType配置的是集合中对象的类型

              javaType配置的是集合的类型

<collection property="comments" column="user_id"
ofType="com.qianfeng.mybatis.entity.Comment"
javaType="java.util.ArrayList">
<!--配置主键 property配置Java类的属性名 column表的列名-->
<id property="commentId" column="comment_id"></id>
<!--配置一般的列-->
<result property="time" column="time"></result>
<result property="stars" column="stars"></result>
<result property="userId" column="user_id"></result>
<result property="nannyId" column="nanny_id"></result>
</collection>

   3. 把所有的用户的查询改成内连接        

 <select id="selectById" parameterType="int" resultMap="userMap">
  <!--select * from tb_user where user_id = #{userId}-->
  select * from tb_user u,tb_comment c where u.user_id = c.user_id and u.user_id = #{userId}
 </select>

对比子查询和内连接:

       子查询不用修改每个查询,内连接需要修改每个查询为连接查询

       子查询可以使用延迟加载,内连接不支持延迟加载

       内连接只查询一次,子查询查询多次

posted @ 2020-06-22 15:58  江南大才子  阅读(676)  评论(0编辑  收藏  举报