[MyBatis]动态sql

目录

if标签

trim标签

choose标签

更新操作

foreach标签

批量增加

内置参数

bind标签

sql标签

所有测试用例


所有接口

package com.yiki.Dao;

import com.yiki.Entity.Person;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface PersonMapperDynamicSQL {

 public List<Person> getPersonConditionIf(Person person);

 public List<Person> getPersonConditionTrim(Person person);

 public List<Person> getPersonConditionChoose(Person person);

 public void updatePerson(Person peson);

 public void addPersons(@Param("persons") List<Person> persons);

 public List<Person> getPersonConditionForeach(@Param("ids") List<Integer> list);

 public List<Person> getPersonByInnerParam(Person person);

}

实体类


public class Department {

 private Integer dId;
 private String dName;
 private List<Person> persons;//这个部门下的所有员工

public class Person {

 private Integer pId;
 private String pName;//当和表里的列名不一致的时候,查询语句应该起别名
 //p_Name(原表里的列名) pname别名
 private String email;
 private Department dept;

if标签

动态拼装sql,哪个合法拼装哪个
【if】里的test:里面写表达式,特殊字符要写转义字符
【and==>&amp;&amp;】
 参考实体类字段:
  Integer pId;
  String pName;//当和表里的列名不一致的时候,查询语句应该起别名
 //p_Name(原表里的列名) pname别名
  String email;
  Department dept;

  转义字符表
  &lt;     <  小于
  &gt;     >  大于
  &amp;        &  与
  &apos;   '  单引号
  &quot;   "  双引号
    <select id="getPersonConditionIf" resultType="com.yiki.Entity.Person">

        select * from person where
        <if test="pId!=null">
            pid=#{pId}
        </if>
        <if test="pName!=null &amp;&amp; pName!=&quot;&quot;">
            and p_name like #{pName}
        </if>
        <if test="email!=null">
            and email=#{email}
        </if>
    </select>

注意:

如果要拼装的变量不符合sql语法,第一种方法 where 1=1 后面在and
第二种方法:用【where】标签包裹【if】或条件判断语句,但是只会去掉第一个and

trim标签

如果and在后面
【prefix】前缀
【prefixOverrides】前缀覆盖
【suffix】后缀
【suffixOverrides】后缀覆盖(去掉拼接后后面多余的字符
    <select id="getPersonConditionTrim" resultType="com.yiki.Entity.Person">
        select * from person

        <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and">
            <if test="pId!=null">
                pid=#{pId} and
            </if>
            <if test="pName!=null &amp;&amp; pName!=&quot;&quot;">
                p_name like #{pName} and
            </if>
            <if test="email!=null">
                email=#{email}
            </if>
        </trim>


    </select>

choose标签

如果带了参数a就用参数a,如果带了参数b就用参数b,只会进去其中一个
    <select id="getPersonConditionChoose" resultType="com.yiki.Entity.Person">
        select * from person
        <where>
            <choose>
                <when test="pId!=null">
                    pid=#{pId}
                </when>
                <when test="pName!=null">
                    p_Name like #{pName}
                </when>
                <when test="email!=null">
                    email=#{email}
                </when>
                <otherwise>
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>

更新操作

 <!--带有哪个字段的更新就更新哪个字段-->
    <update id="updatePerson">
        update person
        <set>
            <if test="pName!=null">
                p_Name=#{pName},
            </if>
            <if test="email!=null">
                email=#{email}
            </if>
        </set>
        where pId=#{pId}
    </update>

foreach标签

【collection】,指定要遍历的集合
list类型的参数会特殊处理封装在map中,map的key就叫list
【item】将当前遍历出的元素赋值给指定的变量
【separator】分隔符
【open】遍历出所有结果拼接一个开始的字符
【close】遍历出所有结果拼接一个结束的字符
【index】索引(list)  key(Map时)
    <select id="getPersonConditionForeach" resultType="com.yiki.Entity.Person">
        select * from person where pid in
        <foreach collection="ids" item="item_id" separator=","
                 open="(" close=")">
            #{item_id}
        </foreach>
    </select>

批量增加

    <insert id="addPersons">
        insert into person(p_Name,email,d_id)
        values
        <foreach collection="persons" item="person" separator=",">
            (#{person.pName},#{person.email},#{person.dept.dId})
        </foreach>

    </insert>

内置参数

【_parameter】代表整个参数
【_databaseId】如果配置了databaseIdProvide标签

    <databaseIdProvider type="DB_VENDOR">
        <!--给数据库厂商起别名-->
        <property name="MySQL" value="mysql"/>
        <property name="Oracle" value="oracle"/>
        <property name="SQL Server" value="sqlserver"/>
    </databaseIdProvider>
    <select id="getPersonByInnerParam" resultType="com.yiki.Entity.Person">
        select * from Person
        <if test="_databaseId=='mysql'">
            select * from Person
            <if test="_parameter!=null">
                where p_name = #{_parameter.pName}
            </if>
        </if>
    </select>

bind标签

【bind】可以将ognl表达式的值绑定到一个变量
    用于拼接
   <bind name="pName" value ="'%'+pName+'%'"

sql标签

抽取可重用的sql片段
引用的时候<include refid="insertColumn">
里面也可以写动态标签
 <sql id="insertColumn">
        pId,pName,email
    </sql>

所有测试用例

package com.yiki.Test;

import com.yiki.Dao.DepartmentMapper;
import com.yiki.Dao.PersonMapperDynamicSQL;
import com.yiki.Dao.PersonMapperPlus;
import com.yiki.Entity.Department;
import com.yiki.Entity.Person;
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 org.apache.log4j.Logger;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestDynamicSQL {
 private String resource;
 private InputStream inputStream;
 private SqlSessionFactory sqlSessionFactory;
 private SqlSession sqlSession;
 private PersonMapperDynamicSQL mapper;
 private Logger log;

 public void start() throws IOException {
  resource = "mybatis.xml";//根据全局配置文件
  inputStream = Resources.getResourceAsStream(resource);
  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  sqlSession = sqlSessionFactory.openSession(true);
  mapper = sqlSession.getMapper(PersonMapperDynamicSQL.class);
  log = Logger.getLogger(this.getClass());
 }

 @Test//动态if标签
 public void test1() throws IOException {
  start();
  //select * from person where pid=?
  Person person1 = new Person(1, null, null);

  //select * from person where pid=? and p_name like ?
  Person person2 = new Person(1, "%t%", null);

  List<Person> list = mapper.getPersonConditionIf(person1);
  System.out.println(list);//
  System.out.println(mapper.getPersonConditionIf(person2));//
  sqlSession.close();
 }

 @Test//trim
 public void test2() throws IOException {
  start();

  // select * from person where p_name like ?
  Person person2 = new Person(null, "%t%", null);

  System.out.println(mapper.getPersonConditionTrim(person2));//
  sqlSession.close();
 }

 @Test//choose
 public void test3() throws IOException {
  start();

  //select * from person WHERE p_Name like ?
  Person person = new Person(null, "%t%", null);

  System.out.println(mapper.getPersonConditionChoose(person));//
  sqlSession.close();
 }

 @Test//更新
 public void test4() throws IOException {
  start();

  //select * from person WHERE p_Name like ?
  Person person = new Person(1, "tiffany", "dddddddd");

  mapper.updatePerson(person);//
  sqlSession.commit();//记得提交
  sqlSession.close();
 }

 @Test//foreach
 public void test5() throws IOException {
  start();
  List<Person> list = mapper.getPersonConditionForeach(Arrays.asList(1, 2, 3, 4));//
  System.out.println(list);
  sqlSession.close();
 }

 @Test//批量保存
 public void test6() throws IOException {
  start();
  List<Person> list = new ArrayList<Person>();
  list.add(new Person(null,"q","@jjj",new Department(1)));
  list.add(new Person(null,"w","@jjj",new Department(2)));
  list.add(new Person(null,"r","@jjj",new Department(1)));
  System.out.println(list);
  mapper.addPersons(list);
  sqlSession.commit();
  sqlSession.close();
 }

}

猜你喜欢

转载自blog.csdn.net/qq_38277033/article/details/81106717