框架--mybatis框架之动态sql

mybatis框架中的动态sql

  • 为什么要使用动态sql

    • 我们使用mybatis框架进行数据库表进行CRUD操作时,当我们写的 SQL 语句都比较简单,还比较容易实现,但如果有比较复杂的业务,就需要便写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。
  • 我们如何解决这个问题呢

    • 这就是我们要说的使用mybatis 动态SQL,使用if, choose, when, otherwise, trim, where, set, foreach等标签,可以轻松组成非常灵活的SQL语句,这样就可以在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

    • 当不使用动态sql语句时;

    <!--parameterType传入参数数据类型,resultType返回值数据类型,要注意,查询的字段要和po中实体类的属性值对应,否则就睡映射不上-->
    <select id="selectLike" parameterType="string" resultType="com.wdhcr.mybatisSelectLike.po.User">
        <!--         我们不使用动态sql语句时,当传参name为空时,查询也就为空-->
        select * from user01 where name where name= #{name}
    </select>
    
    • 当使用动态sql中的if标签时
     <!--    动态sql中if语句的使用-->
    <select id="selectUserIf" parameterType="java.lang.String" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01 where
        <!-- 如果使用动态sql时 string类型的数据需要使用 _parameter 作为形参名,
        否则就会出现string无get方法,当if中的条件不满足时,if中的语句就不会给主体的sql语句上加-->
        <if test="_parameter != null">
            name = #{_parameter}
        </if>
    </select>
    
    • 当使用动态sql中的 if where标签连用时
        <!--    动态sql中if where连用-->
    <select id="selectUserIfWhere" parameterType="java.lang.String" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <!-- 当有where标签时,第一个if判断中可以不加and 或者or,加上,where也会为我们自动去掉,但后面的if中要加-->
        <where>
            <!-- 如果使用动态sql时 string类型的数据需要使用 _parameter 作为形参,否则就会出现string无get方法-->
            <if test="_parameter != null">
                name = #{_parameter}
            </if>
        </where>
    </select>
    
    • 当使用动态sql中的set ,if, where标签连用,set标签主要是在更新语句中使用充当set使用
        <!--    动态sql中的set ,if where连用-->
    <update id="updateUser" parameterType="com.wdhcr.mybatisDynamicSql.po.User">
        update user01
        <set>
            <!-- 注意这是sql拼接,要注意拼接成功后的sql语句,要和正常的sql语句语法相同,
            当set中有多个字段时每个字段后面要加上","要符合正常的sql语句-->
            <if test="password != null and password != ''">
                user01.password = #{password}
            </if>
        </set>
        <where>
            <if test="name != null and name !=''">
                name = #{name}
            </if>
        </where>
    </update>
    
    • 当使用动态sql中的trim标签
     <!--    动态sql中的trim的使用-->
    <select id="selectTrimUser" parameterType="string" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <!--         prefixOverrides是自动设置前缀的
        suffixOverrides是设置标签中的sql语句后缀自动加上你设置的符号例如','-->
        <trim prefix="where" prefixOverrides="and/or" >
            <if test="_parameter != null">
                name = #{_parameter}
            </if>
        </trim>
    </select>
    
    • 当使用动态sql中的choose ,when,otherwise标签连用
    <select id="selectChoose" parameterType="string" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <where>
    <!--         相当与java里面的switch语句,when相当于case,当条件满足时,执行,-->
    <!--         并且其他的就不会执行了,当所有when都没有时,执行otherwise中的语句-->
            <choose>
                <when test="_parameter == '王大锤'">
                    user01.name  = #{_parameter}
                </when>
                <otherwise>
                    user01.name = "王八羔子"
                </otherwise>
            </choose>
        </where>
    </select>
    
    • 当使用动态sql中的sql片段标签,java开发就是讲究高内聚,低耦合嘛,所以把相同重复度高的sql片段抽取出来。
     <!--    动态sql中的sql片段使用-->
    <!--    创建sql片段-->
    <sql id="choseName">
        <if test="_parameter != null">
            name = #{_parameter}
        </if>
    </sql>
    <select id="selectSqlUser" parameterType="string" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <!-- 调用sql片段-->
        <where>
            <include refid="choseName"></include>
        </where>
    </select>
    
    
    • 我们向数据库中比如需要查询name= zz or name=qq or name=ww的使用,我们可以传过来一个list,我们就可以使用动态sql中的foreach标签
     <!--动态sql中的foreach循环-->
    <!--使用动态sql的sql片段-->
    <sql id="foreach">
        <if test="list != null">
            <!--
                collection:指定输入对象中的集合属性
                item:每次遍历生成的对象
                open:开始遍历时的拼接字符串
                close:结束时拼接的字符串
                separator:遍历对象之间需要拼接的字符串
                select * from user01 where 1=1 and (name=zz or name=qq or name=ww)
              -->
            <foreach collection="list" item="name_item" open="and (" close=")" separator="or">
                name = #{name_item}
            </foreach>
        </if>
    </sql>
    <!--使用动态sql中的foreach查询传入参数为list时-->
    <select id="forSqlUser" parameterType="list" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <where>
            <!--使用where标签它可以自动添加或删除where后面的and或者or-->
            <!--调用sql片段-->
            <include refid="foreach"></include>
        </where>
    </select>
    
    • 用 foreach 来改写 select * from user01 where name in (‘zz’,‘qq’,‘ww’)
    <select id="forUserByName" parameterType="list" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <where>
            <!--
                collection:指定输入对象中的集合属性
                item:每次遍历生成的对象
                open:开始遍历时的拼接字符串
                close:结束时拼接的字符串
                separator:遍历对象之间需要拼接的字符串
                select * from user01 where 1=1 and name in ('aa','qq','ww')
              -->
           <if test="list != null">
            <foreach collection="list" item="id" open="and name in (" close=") " separator=",">
                #{id}
            </foreach>
            </if>
        </where>
    </select>
    
    • 当我们传入的数据类型为hashmap时如下:
       <!--使用动态sql的foreach传入参数为hashmap时-->
    <select id="forUserMap" parameterType="hashmap" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01 where name like concat('%',#{name},'%') and password in
        <if test="list != null">
            <foreach collection="list" item="pass_item" open="(" separator="," close=")">
                #{pass_item}
            </foreach>
        </if>
    </select>
    
  • 以上就是动态sql比较常用的一些操作了

  • 下面是一个完成的案例展示:

    • maven依赖
     <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.8</version>
      </dependency>
    
      <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.4.6</version>
      </dependency>
    
      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>
    
    • 数据库字段结构
      在这里插入图片描述
    • 核心全局配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 	"http://mybatis.org/dtd/mybatis-3-config.dtd">
    	<configuration>
    <environments default="dev">
        <environment id="dev">
    <!--            设置事务类型-->
            <transactionManager type="JDBC"></transactionManager>
    <!--            设置数据源类型-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/一个库"/>
                <property name="username" value="用户名"/>
                <property name="password" value="密码"/>
            </dataSource>
        </environment>
    </environments>
    <!--    注入你的映射文件-->
    <mappers>
        <mapper resource="UserSelectLike.xml"></mapper>
           <mapper resource="UserMapperSql.xml"></mapper>
    </mappers>
    </configuration>
    
    • 映射文件
    <?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">
    <mapper namespace="com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql">
      <!--    动态sql中if语句的使用-->
     <select id="selectUserIf" parameterType="java.lang.String" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01 where
        <!-- 如果使用动态sql时 string类型的数据需要使用 _parameter 作为形参名,
        否则就会出现string无get方法,当if中的条件不满足时,if中的语句就不会给主体的sql语句上加-->
        <if test="_parameter != null">
            name = #{_parameter}
        </if>
    </select>
    <!--    动态sql中if where连用-->
    <select id="selectUserIfWhere" parameterType="java.lang.String" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
          <!-- 当有where标签时,第一个if判断中可以不加and 或者or,加上,where也会为我们自动去掉,但后面的if中要加-->
        <where>
                <!-- 如果使用动态sql时 string类型的数据需要使用 _parameter 作为形参,否则就会出现string无get方法-->
            <if test="_parameter != null">
                name = #{_parameter}
            </if>
            </where>
        </select>
        <!--    动态sql中的set ,if where连用-->
    <update id="updateUser" parameterType="com.wdhcr.mybatisDynamicSql.po.User">
        update user01
        <set>
            <!-- 注意这是sql拼接,要注意拼接成功后的sql语句,要和正常的sql语句语法相同,
            当set中有多个字段时每个字段后面要加上","要符合正常的sql语句-->
            <if test="password != null and password != ''">
                user01.password = #{password}
            </if>
        </set>
        <where>
            <if test="name != null and name !=''">
                name = #{name}
            </if>
        </where>
    </update>
    <!--    动态sql中的trim的使用-->
    <select id="selectTrimUser" parameterType="string" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <!--         prefixOverrides是自动设置前缀的
        suffixOverrides是设置标签中的sql语句后缀自动加上你设置的符号例如','-->
        <trim prefix="where" prefixOverrides="and/or" >
            <if test="_parameter != null">
                name = #{_parameter}
            </if>
        </trim>
    </select>
        <!--    动态sql中使用choose ,when,otherwise-->
    <select id="selectChoose" parameterType="string" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <where>
    <!--         相当与java里面的switch语句,when相当于case,当条件满足时,执行,-->
    <!--         并且其他的就不会执行了,当所有when都没有时,执行otherwise中的语句-->
            <choose>
                <when test="_parameter == '王大锤'">
                    user01.name  = #{_parameter}
                </when>
                <otherwise>
                    user01.name = "王八羔子"
                </otherwise>
            </choose>
        </where>
    </select>
    <!--    动态sql中的sql片段使用-->
    <!--    创建sql片段-->
    <sql id="choseName">
        <if test="_parameter != null">
            name = #{_parameter}
        </if>
    </sql>
    <select id="selectSqlUser" parameterType="string" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <!-- 调用sql片段-->
        <where>
            <include refid="choseName"></include>
        </where>
    </select>
    <!--动态sql中的foreach循环-->
    <!--使用动态sql的sql片段-->
    <sql id="foreach">
        <if test="list != null">
            <!--
                collection:指定输入对象中的集合属性
                item:每次遍历生成的对象
                open:开始遍历时的拼接字符串
                close:结束时拼接的字符串
                separator:遍历对象之间需要拼接的字符串
                select * from user01 where 1=1 and (name=zz or name=qq or name=ww)
              -->
            <foreach collection="list" item="name_item" open="and (" close=")" separator="or">
                name = #{name_item}
            </foreach>
        </if>
    </sql>
    <!--使用动态sql中的foreach查询传入参数为list时-->
    <select id="forSqlUser" parameterType="list" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01
        <where>
            <!--使用where标签它可以自动添加或删除where后面的and或者or-->
            <!--调用sql片段-->
            <include refid="foreach"></include>
        </where>
    </select>
    <!--使用动态sql的foreach传入参数为hashmap时-->
    <select id="forUserMap" parameterType="hashmap" resultType="com.wdhcr.mybatisDynamicSql.po.User">
        select * from user01 where name like concat('%',#{name},'%') and password in
        <if test="list != null">
            <foreach collection="list" item="pass_item" open="(" separator="," close=")">
                #{pass_item}
            </foreach>
        </if>
     </select>
    </mapper>
    
    • po层的实体类
    	/*
    	* po层的实体类。里面的属性值对应数据库表中的字段
    * 并生成它的get set方法 和tostring方法
    * */
    public class User {
    private String name;
    private String password;
    
    public User(String name, String password) {
        this.name =name;
        this.password = password;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
        }
    }
    
    
    • 测试类代码
    import com.wdhcr.mybatisDynamicSql.po.User;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    public class Test {
    public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("ConfigMapper.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession();
        //这是动态sql中用if
    	//        User user= 			sqlSession.selectOne("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.selectUserIf", "王	大锤");
    //        System.out.println(user);
            //这是动态sql中用where 和if
    //        User user= 	sqlSession.selectOne("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.selectUserIfWhere", "王大锤");
    //        System.out.println(user);
            //动态sql中使用set where if set 主要使用在更新语句中
    //        	sqlSession.update("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.updateUser",new 	User("王八羔子","111111"));
    //        //注意进行增删改操作时,一定要提交事务
    //        sqlSession.commit();
        //动态sql中使用trim标签它可以模拟你常用的一些标签
    //        User user = 	sqlSession.selectOne("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.selectTrimUser", "王大锤");
    //        System.out.println(user);
        //动态sql中的choose,when otherwise标签连用
    //        User user=sqlSession.selectOne("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.selectChoose","王大大锤");
    //            System.out.println(user);
        //动态sql中将常用的一些sql片段封装起来,用的使用直接调用
    //        User user= sqlSession.selectOne("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.selectSqlUser","王大锤");
    //        System.out.println(user);
        //动态sql中的foreach循环传入参数为list
    //        List list = new ArrayList<>();
    //        list.add("王大锤");
    //        list.add("王八羔子");
    //        //userVo.setList(list);
    //        List<User> 	userList=sqlSession.selectList("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.forSqlUser",list);
    //        for (User user : userList) {
    //            System.out.println(user);
    //        }
        //动态sql中的foreach循环,传入参数为hashmap
        List list = new ArrayList<>();
        list.add("5678");
        list.add("111111");
        HashMap hashMap = new HashMap();
        hashMap.put("list",list);
        hashMap.put("name","王大锤");
        List<User> userList=sqlSession.selectList("com.wdhcr.mybatisDynamicSql.mapper.UserMapperSql.forUserMap",hashMap);
        for (User user : userList) {
            System.out.println(user);
        }
       }
    }
    
    
  • 以上就是mybatis框架中的动态sql语句的讲解,和具体的代码案例使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值