Mybatis介绍之 动态SQL

来源:这里教程网 时间:2026-03-02 12:09:14 作者:

  动态 SQL  动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。  使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis显著地提升了这一特性的易用性。  如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。  if  choose (when, otherwise)  trim (where, set)  foreach  一、MyBatis动态语句分为4种元素:  MyBatis的动态SQL语句是基于OGNL表达式的。可以方便的在SQL语句中实现某些逻辑,总体说来MyBatis动态SQL语句主要有以下几类:  ⭐ if语句(简单的条件判断)。  ⭐ choose(when,otherwize),相当于Java语言中的switch,与JSTL中的choose很类似。  ⭐ trim(对包含的内容加上prefix,或者suffix等,前缀,后缀)。  ⭐ where(主要是用来简化SQL语句中where条件判断的,能智能的处理and or,不必担心多余导致语法错误)。  ⭐ set(主要用于更新时)。 6、foreach(在实现MyBatis in语句查询时特别有用)。  下面用介绍几种方式:  依据数据库创建class类,student类  ClassInfo  package cn.yyj1.entity;  import java.util.List;  public class ClassInfo {  private int classid;  private String className;  private List studentInfoList;  public List getStudentInfoList() {  return studentInfoList;  }  public void setStudentInfoList(List studentInfoList) {  this.studentInfoList = studentInfoList;  }  public int getClassid() {  return classid;  }  public void setClassid(int classid) {  this.classid = classid;  }  public String getClassName() {  return className;  }  public void setClassName(String className) {  this.className = className;  }  public ClassInfo(int classid, String className) {  this.classid = classid;  this.className = className;  }  public ClassInfo() {  }  }  StudentInfo类  package cn.yyj1.entity;  public class StudentInfo {  private String studentid;  private String studentName;  private String studentSex;  private String studentPhone;  private String studentAddress;  private int studentAge;  private int stuclassid;  //私有的 类型 名字  //只有空的构造方法 才能查到className 的信息  private ClassInfo classInfo;  public String getStudentid() {  return studentid;  }  public void setStudentid(String studentid) {  this.studentid = studentid;  }  public String getStudentName() {  return studentName;  }  public void setStudentName(String studentName) {  this.studentName = studentName;  }  public String getStudentSex() {  return studentSex;  }  public void setStudentSex(String studentSex) {  this.studentSex = studentSex;  }  public String getStudentPhone() {  return studentPhone;  }  public void setStudentPhone(String studentPhone) {  this.studentPhone = studentPhone;  }  public String getStudentAddress() {  return studentAddress;  }  public void setStudentAddress(String studentAddress) {  this.studentAddress = studentAddress;  }  public int getStudentAge() {  return studentAge;  }  public void setStudentAge(int studentAge) {  this.studentAge = studentAge;  }  public int getStuclassid() {  return stuclassid;  }  public void setStuclassid(int stuclassid) {  this.stuclassid = stuclassid;  }  public ClassInfo getClassInfo() {  return classInfo;  }  public void setClassInfo(ClassInfo classInfo) {  this.classInfo = classInfo;  }  public StudentInfo(String studentid, String studentName, String studentSex, String studentPhone, String studentAddress, int studentAge, int stuclassid, ClassInfo classInfo) {  this.studentid = studentid;  this.studentName = studentName;  this.studentSex = studentSex;  this.studentPhone = studentPhone;  this.studentAddress = studentAddress;  this.studentAge = studentAge;  this.stuclassid = stuclassid;  this.classInfo = classInfo;  }  public StudentInfo(String studentName, String studentSex, String studentPhone, String studentAddress, int studentAge, int stuclassid, ClassInfo classInfo) {  this.studentName = studentName;  this.studentSex = studentSex;  this.studentPhone = studentPhone;  this.studentAddress = studentAddress;  this.studentAge = studentAge;  this.stuclassid = stuclassid;  this.classInfo = classInfo;  }  public StudentInfo() {  }  }  创建mapper类 和mapper.xml  package cn.yyj1.mapper;  import cn.yyj1.entity.ClassInfo;  import cn.yyj1.entity.StudentInfo;  import org.apache.ibatis.annotations.Param;  import java.util.List;  import java.util.Map;  public interface StudentInfoMapper {  //根据班级编号查询所属班级的所有学生信息 id 班级编号 所属这个班级的学生  public List findStuByClassId(int id);  //根据班级编号查询班级信息 id 班级信息 班级信息  public ClassInfo findClassByClassId(int id);  //根据班级编号查询所属姓名的学生  public List findStudNameByClassId(@Param("stuclassid") int stuclassid, @Param("studentName") String studentName);  //根据ID修改学生信息  public int update (StudentInfo si);  public StudentInfo findStudentById(String id);  //根据数组查询所有学生信息 定义数组 int [] array  public List findStudentByArray(int [] array);  //根据集合查学生信息  public List findStudentByList(List list);  //根据Map查询  public List findStudentByMap(Map map);  //Choose  public List findStudentByChoose(@Param("studentName")String studentName,@Param("studentAge")int studentAge,@Param("stuclassid")int stuclassid);  //分页  public List findStudentByPage(@Param("pageSize")int pageSize,@Param("pageCode")int pageCode);  }  mapper.xml  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  select s.*,c.className from student s,classinfo c where s.stuclassid=c.classid and s.stuclassid=#{stuclassid}  select s.*,c.className from student s,classinfo c where s.stuclassid=c.classid and c.classid=#{classid}  SELECT * FROM student            stuclassid=#{stuclassid}        and studentName LIKE concat(concat('%',#{studentName}),'%')  SELECT * FROM student WHERE studentid=#{studentid}  UPDATE student  /**/  studentName=#{studentName},  studentSex=#{studentSex},  studentPhone=#{studentPhone},  studentAddress=#{studentAddress},  studentAge=#{studentAge},  stuclassid=#{stuclassid},  SELECT * from student WHERE stuclassid IN      #{stuclassid}  SELECT * from student WHERE stuclassid IN      #{stuclassid}  SELECT * FROM student where studentName LIKE concat(concat('%',#{studentName}),'%') and stuclassid in      #{map}  SELECT * FROM student where 1=1         AND studentName LIKE concat(concat('%',#{studentName}),'%')        AND studentAge>#{studentAge}        and stuclassid=#{stuclassid}  SELECT * FROM student      limit #{pageSize},#{pageCode}  创建工具类:  package cn.yyj1.util;  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;  public class MybatisUtil {  //加载mybatis配置文件  //创建sqlsessionfactory对象  //创建sqlsession连接对象  //创建关闭sqlsession连接对象  //mybatis 数据库查询  private static SqlSessionFactory sessionFactory;  static{  String resource="mybatis1.xml";  try {  InputStream is= Resources.getResourceAsStream(resource);  sessionFactory=new SqlSessionFactoryBuilder().build(is);  } catch (IOException e) {  // TODO Auto-generated catch block  e.printStackTrace();  }  }  public static SqlSession getSession(){  return sessionFactory.openSession();  }  public static void closeSession(SqlSession session){  if(session!=null){  session.close();  }  }  }  连接数据库的xml  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd">  测试类:  package cn.yyj1.test;  import cn.yyj1.entity.ClassInfo;  import cn.yyj1.entity.StudentInfo;  import cn.yyj1.mapper.StudentInfoMapper;  import cn.yyj1.util.MybatisUtil;  import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;  import org.apache.ibatis.session.SqlSession;  import java.io.ObjectStreamClass;  import java.util.ArrayList;  import java.util.HashMap;  import java.util.List;  import java.util.Map;  public class Test {  public static void main(String[] args) {  // test1();  // test2();  // test3();  // test4();  // test5();  // test6();  // test7();  // test8();  test9();  }  private static void test9() {  SqlSession session = MybatisUtil.getSession();  int pageSize=2;int pageCode=2;  int before=(pageCode-1)*pageSize;  int after=pageSize;  List LIST=session.getMapper(StudentInfoMapper.class).findStudentByPage(before,after);  System.out.println(LIST);  for (StudentInfo s:LIST){  System.out.println(s.getStudentName()+"\t"+s.getStuclassid());  }  }  private static void test8() {  //Choose 等于java中的 Switch 语句 第一次直接跳入名字中含有 “赵” 的  // SqlSession session = MybatisUtil.getSession();  // List list=session.getMapper(StudentInfoMapper.class).findStudentByChoose("赵",20,1);  // for (StudentInfo l:list){  // System.out.println(l.getStudentName()+"\t"+l.getStuclassid()+"\t"+l.getStudentAge());  // }  //第二次跳入年龄大于20岁的  SqlSession session = MybatisUtil.getSession();  List list=session.getMapper(StudentInfoMapper.class).findStudentByChoose(null,20,1);  System.out.println(list);  for (StudentInfo l:list){  System.out.println(l.getStudentName()+"\t"+l.getStuclassid()+"\t"+l.getStudentAge());  }  //第三次进入 班级 id 为 1 的  // SqlSession session = MybatisUtil.getSession();  // List list=session.getMapper(StudentInfoMapper.class).findStudentByChoose(null,0,1);  // System.out.println(list);  // for (StudentInfo l:list){ 大连人流医院价格 http://www.120wtrlyy.com/  // System.out.println(l.getStudentName()+"\t"+l.getStuclassid()+"\t"+l.getStudentAge());  // }  }  private static void test7() {  SqlSession session = MybatisUtil.getSession();  Map map = new HashMap();  List list1 = new ArrayList();  list1.add(1);  list1.add(2);  map.put("studentName","赵");  map.put("list",list1);  List li=session.getMapper(StudentInfoMapper.class).findStudentByMap(map);  for (StudentInfo a:li){  System.out.println(a.getStudentName()+"\t"+a.getStuclassid());  }  }  private static void test6() {  SqlSession session = MybatisUtil.getSession();  //新建一个list集合 命名为list1  ArrayList list1 = new ArrayList();  //向list1 集合中添加数据  list1.add(2);  list1.add(3);  //遍历获取 打印输出  List list=session.getMapper(StudentInfoMapper.class).findStudentByList(list1);  for (StudentInfo i:list){  System.out.println(i.getStudentName()+"\t"+i.getStuclassid());  }  }  private static void test5() {  SqlSession session = MybatisUtil.getSession();  int[] array={1,2};  List list=session.getMapper(StudentInfoMapper.class).findStudentByArray(array);  for (StudentInfo i:list){  System.out.println(i.getStudentName()+"\t"+i.getStuclassid());  }  }  private static void test4() {  SqlSession session = MybatisUtil.getSession();  //先查找ID 再给Id更改  StudentInfo a=session.getMapper(StudentInfoMapper.class).findStudentById("s123452");  a.setStudentName("张大东");  int b=session.getMapper(StudentInfoMapper.class).update(a);  if (b>0){  System.out.println("ok");  }  session.commit();  }  private static void test3() {  SqlSession session = MybatisUtil.getSession();  List list=session.getMapper(StudentInfoMapper.class).findStudNameByClassId(1,"赵");  for (StudentInfo i:list){  System.out.println(i.getStudentName());  }  }  private static void test2() {  SqlSession session = MybatisUtil.getSession();  ClassInfo list=session.getMapper(StudentInfoMapper.class).findClassByClassId(2);  System.out.println(list.getClassName());  List lists=list.getStudentInfoList();  for (StudentInfo u:lists){  System.out.println(u.getStudentName());  }  }  private static void test1() {  SqlSession session = MybatisUtil.getSession();  //遍历集合 输出  List list=session.getMapper(StudentInfoMapper.class).findStuByClassId(1);  System.out.println(list.size());  for (StudentInfo u:list){  System.out.println(u.getStudentName()+"\t"+u.getClassInfo().getClassName());  }  }  }  其中:  when  when元素表示当when中的条件满足的时候就输出其中的内容,跟JAVA中的switch效果差不多的是按照条件的顺序,当when中有条件满足的时候,就会跳出choose,即所有的when和otherwise条件中,只有一个会输出,当所有的条件都不满足的时候就输出otherwise中的内容  set  set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素就可以动态的更新那些修改了的字段。  foreach  foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:  1、如果传入的是单参数且参数类型是一个List的时候,collection属性值为list  2、如果传入的是单参数且参数类型是一个Array数组的时候,collection的属性值为array  3、如果传入的参数是多个的时候,就需要把它们封装成一个Map,当然单参数也可以封装成Map,实际上如果在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,Map的key就是参数名,所以这个时候collection属性值就是传入的List或Array对象在自己封装的Map里面的key  trim  trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以也可以非常简单的利用trim来代替where元素的功能。

相关推荐