Mybatis笔记(持续更新)

ORM框架–Mybatis—需要程序员自己写SQL语句,需要掌握Java,和sql语句
–Hibernate—纯面向对象的,不需要程序员自己写SQL语句,完全使用操作对象,需要掌握Java
1.什么是Mybatis?
Mybatis—>OEM框架—>对JDBC进行封装,是数据持久层的框架,数据持久层的技术,与JDBC操作步骤类似,所以为了减少繁琐,对JDBC进行了封装
框架:简单,好用,易上手,对一些东西进行封装
MyBatis是一个简化和实现了 Java 数据持久化层(persistence layer)的开源框架,它抽象了大量的JDBC冗余代码,并提供了一个简单易用的API和数据库交互。
MyBatis的前身是iBATIS,iBATIS于2002年由ClintonBegin创建。MyBatis3是iBATIS的全新设计,支持注解和Mapper。
MyBatis流行的主要原因在于它的简单性和易使用性。在Java应用程序中,数据持久化层涉及到的工作有:将从数据库查询到的数据生成所需要的Java对象;将Java对象中的数据通SQL持久化到数据库中。
MyBatis通过抽象底层的JDBC代码,自动化SQL结果集产生Java对象、Java对象的数据持久化数据库中的过程使得对SQL的使用变得容易。
2.基本流程总结
1.建立配置文件,实现映射文件的路径
2.建立mapper映射文件,在SQLMapper映射配置文件中配置SQL语句
3.建立一个接口,配置文件的方法要关联到接口中,实现在映射接口中的方法与关系映射文件的sql对应
4.建立实现类,编写java代码完成插入操作
3.以下是博主的教师给的一些mybatis配置的详细内容
mybatis的核心包只有一个mybatis-3.x.0.jar
mybatis的两种文件:
1)mybatis的配置文件:mybatis-config.xml,其中包括数据库连接信息,类型别名等等
特点:名字一般是固定的,位置是src下面
2)mybatis的映射文件:XxxxxMapper.xml,这个xml文件中包括Xxxx类所对应的数据库表的各种增删改查sql语句
特点:名字一般为XxxxMapper.xml,Xxxx是对应类的名字
位置不固定,一般放到一个专门的package里面
接下来是
mybatis中的映射接口XxxxMapper.java(和XxxxMapper.xml中的sql语句进行映射)
最终实现类通过XxxxMapper接口的实现类对象来调用xml中的SQL语句
其中还写了一个
mybatis中的SqlSession接口和sqlSessionFactory接口,专门用来产生SqlSession对象

以下是博主今天完成的作业,建立了一个书籍管理,仅供参考
Book.java :

import java.util.Date;

public class Book {
    //编号
    private Integer id;
    //书名
    private String bookName;
    //作者
    private String author;
    //发布日期
    private Date publishDate;
    //价格
    private Double price;

    public Book() {}
    public Book(Integer id, String bookName, String author, Date publishDate, Double price) {
        this.id = id;
        this.bookName = bookName;
        this.author = author;
        this.publishDate = publishDate;
        this.price = price;
    }
    public Book(String bookName, String author, Date publishDate, Double price) {
        this.bookName = bookName;
        this.author = author;
        this.publishDate = publishDate;
        this.price = price;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public Date getPublishDate() {
        return publishDate;
    }
    public void setPublishDate(Date publishDate) {
        this.publishDate = publishDate;
    }
    public Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Book [id=" + id + ", bookName=" + bookName + ", author=" + author + ", publishDate=" + publishDate
                + ", price=" + price + "]";
    }
}

BookMapper.xml :

<?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.briup.mappers.BookMapper">
    <resultMap type="Book" id="BookResult">
        <id property="id" column="id"/>
        <result property="bookName" column="bookName"/>
        <result property="author" column="author"/>
        <result property="publishDate" column="publishDate"/>
        <result property="price" column="price"/>
    </resultMap>

    <!-- 添加书籍 -->
    <insert id="insertBook" parameterType="Book">
        insert into books
        values (#{id},#{bookName},#{author},#{publishDate},#{price})
    </insert>

    <!-- 通过ID删除书籍 -->
    <delete id="deleteBook" parameterType="int">
        delete from books
        where id=#{id}
    </delete>

    <!-- 通过名称查找书籍 -->
    <select id="selectBookByname" parameterType="String" resultMap="BookResult">
        select *
        from books
        where bookName=#{bookName}
    </select>

    <!-- 通过ID查找书籍 -->
    <select id="selectBookByid" parameterType="int" resultMap="BookResult">
        select *
        from books
        where id=#{id}
    </select>

    <!-- 查找所有书籍 -->
    <select id="selectBook" resultMap="BookResult">
        select *
        from books
    </select>

    <!-- 查找所有书籍的名字 -->
    <select id="selectBookname" resultType="String">
        select bookName
        from books
    </select>

    <!-- 查找有多少本书籍 -->
    <select id="selectBookcount" resultType="int">
        select count(*)
        from books
    </select>

    <!-- 通过ID修改书籍 -->
    <update id="updateBookByid" parameterType="Book">
        update from books
        set bookName=#{bookName},author=#{author},publishDate#{publishDate},price=#{price}
        where id=#{id}
    </update>

    <!-- 查询所有书籍的名字和对应的作者 -->
    <select id="selectBookn" resultType="String">
        select bookName
        from books
    </select>
    <select id="selectBooka" resultType="Object">
        select author
        from books
    </select>
    <select id="selectBooknaa" resultType="Book">
        select bookName,author
        from books
    </select>
</mapper>
BookMapper.java  :
package com.briup.mappers;

import java.util.List;

import com.briup.pojo.Book;

public interface BookMapper {
    public void insertBook(Book book);
    public void deleteBook(int id);
    public Book selectBookByname(String name);
    public Book selectBookByid(int id);
    public List<Book> selectBook();
    public List<String> selectBookname();
    public int selectBookcount();
    public void updateBookByid(Book book);
    public List<Book> selectBooknaa();
}

BookService.java :

package com.briup.test;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.briup.common.MyBatisSqlSessionFactory;
import com.briup.mappers.BookMapper;
import com.briup.pojo.Book;

/**
 * 在BookMapper.java接口中定义方法
 * 在BookService中调用BookMapper.java接口中方法
 * 完成以下功能(注意参照笔记中的实例)
 */
//处理书籍相关信息的服务类
public class BookService {

    //添加书籍
    //书籍的名称不能重复
//  @Test
    public void addBook(Book book){
        try {
            SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
            BookMapper mapper = session.getMapper(BookMapper.class);
//          Book b = new Book(1, "罗密欧与朱丽叶", "莎士比亚", new Date(), 100.0);
            mapper.insertBook(book);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //删除书籍
    //id值不存在则不能删除
    public void removeBook(Integer id){
        try {
            SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
            BookMapper mapper = session.getMapper(BookMapper.class);
            mapper.deleteBook(id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //查找书籍
    //通过名字
    public Book findBookByName(String bookName){
        SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
        BookMapper mapper = session.getMapper(BookMapper.class);
        Book book = mapper.selectBookByname(bookName);
        return book;
    }

    //查找书籍
    //通过id
    public Book findBookByName(Integer id){
        SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
        BookMapper mapper = session.getMapper(BookMapper.class);
        Book book = mapper.selectBookByid(id);
        return book;
    }

    //查找所有书籍
//  @Test
    public List<Book> findAllBooks(){
//      try {
            SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
            BookMapper mapper = session.getMapper(BookMapper.class);
            List<Book> list = mapper.selectBook();
//          for(Book li:list){
//              System.out.println(li);
//          }
//      } catch (Exception e) {
//          e.printStackTrace();
//      }
        return list;
    }

    //查找所有书籍的名字
//  @Test
    public List<String> findAllBooksName(){
//      try {
            SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
            BookMapper mapper = session.getMapper(BookMapper.class);
            List<String> list = mapper.selectBookname();
//          for(String li:list){
//              System.out.println(li);
//          }
//      } catch (Exception e) {
//          e.printStackTrace();
//      }
        return list;
    }

    //查找一共有多少本书籍
    public int findCountOfBook(){
        SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
        BookMapper mapper = session.getMapper(BookMapper.class);
        int count = mapper.selectBookcount();
        return count;
    }

    //修改书籍
    //通过id确定修改的是那本书
    public void updateBook(Book book){
        SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
        BookMapper mapper = session.getMapper(BookMapper.class);
        mapper.updateBookByid(book);
    }

    //查询所有书籍的名字和对应的作者
//  @Test
    public List<Map<String,Object>> findBookNameAndAuthor(){
        List<Map<String,Object>> listmap = new ArrayList<Map<String,Object>>();
        try {
            SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();
            BookMapper mapper = session.getMapper(BookMapper.class);
            List<Book> list= mapper.selectBooknaa();
            Map<String, Object> map = new HashMap<String, Object>();
            for(Book l:list){
                map.put(l.getBookName(), l.getAuthor());
            }
            listmap.add(map);
//          for(Map<String,Object> l:listmap){
//              System.out.println(l);
//          }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return listmap;
    }

}

以下是工厂类的写法
MyBatisSqlSessionFactory.java

package com.briup.common;

import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisSqlSessionFactory {
    private static SqlSessionFactory sqlSessionFactory;
    public static SqlSessionFactory getSqlSessionFactory(){
        if(sqlSessionFactory == null){
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e.getCause());
            }
        }
        return sqlSessionFactory;
    }

    public static SqlSession openSession() { 
        return openSession(false); 
    }
    //boolean参数是否要自动提交
        //false设置手动提交
        //true设置为自动提交
    public static SqlSession openSession(boolean autoCommit) { 
        return getSqlSessionFactory().openSession(autoCommit); 
    }
}

以下是配置文件的写法
mybatis-config.xml :

<?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>
    <!-- 定义在配置文件可以使用变量
                        变量名=变量值 -->
    <properties resource="db.properties">
        <!-- <property name="driver" value="oracle.jdbc.driver.OracleDriver" /> 
        <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:XE" /> 
        <property name="name" value="briup" />
        <property name="pwd" value="oracle" /> -->
        <!-- 下面这句是测试,外部引入文件的优先级比内部property优先级高。如果name有两个,会使用外部引用文件的name -->
        <property name="name" value="test"/>
    </properties>
    <!-- 定义全局参数 -->
    <settings>
        <setting name="logPrefix" value="LOG4J:"/>
    </settings>
    <!-- 指定类型的别名 -->
    <typeAliases>
        <!-- <typeAlias type="com.briup.pojo.Student" alias="Student" />  alias:起别名 -->
        <!-- 自动扫描该包,先判断是否用注解的方式取别名,如果没有则将该包中的所有类取一个默认的别名 默认别名就是类名 -->
        <package name="com.briup.pojo"/>
    </typeAliases>

    <!-- 定义自定义类型处理器 -->
    <typeHandlers>
        <typeHandler handler="com.briup.handler.PhoneTypeHandler"/>
    </typeHandlers>

    <!-- 定义当前数据库的环境 可以定义多个环境 -->
    <environments default="development">
        <environment id="development">
            <!-- 定义事务的控制 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 定义数据源--> <!-- pooled代表连接池 是以连接池的方式来连接的 -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" /> 
                <property name="url" value="${url}" /> 
                <property name="username" value="${name}" />
                <property name="password" value="${pwd}" />
            </dataSource>
        </environment>
    </environments>
    <!-- 指定的映射文件的路径 -->
    <mappers>
        <!-- <mapper resource="com/briup/mappers/StudentMapper.xml"/> -->
        <mapper resource="com/briup/mappers/BookMapper.xml"/>
    </mappers>

</configuration>

总的来说配置文件中的指定文件路径一定要和映射文件的路径对应
映射文件中的指定文件路径一定要和接口的路径对应
XML文件里的SQL语句的id一定要和接口的方法和测试类里mapper调用的方法三者对应
接口中方法名和配置文件中id值一致;方法参数类型和parameterType属性值一种;方法返回值类型和returnType属性值一致。

需要注意的是
keyProperty—类当中的属性
column—表当中的列

映射文件是不提供方法的返回值类型
映射文件是不关心方法的返回值类型
resultType定义的不是方法的返回值类型,它定义的是查询出的每一行数据要封装的对象类型是什么

用到的映射语句
select insert update delete
mapper mapper.xml的根节点
namespace 接口全限定名
resultType和resultMap
MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap 的引用,是结果集映射,但是resultType跟resultMap不能同时存在。
resultType=”id”;l
parameterType 参数类型

自定义MyBatis日志
日志记录优先级由上到下顺序递减:
SLF4J
Apache Commons Logging
Log4j2
Log4j
JDK logging
org.apache.ibatis.logging.LogFactory.useSlf4jLogging();
org.apache.ibatis.logging.LogFactory.useLog4JLogging();
org.apache.ibatis.logging.LogFactory.useLog4J2Logging();
org.apache.ibatis.logging.LogFactory.useJdkLogging();
org.apache.ibatis.logging.LogFactory.useCommonsLogging();
org.apache.ibatis.logging.LogFactory.useStdOutLogging();

如果想自定义MyBatis日志记录,你应该在调用任何其它方法之前调用以上的其中一个方法

4.结果集映射 ResultMaps
简单的结果集映射

        <resultMap type="属性名" id="结果集映射名称"> 
          <id property="studId" column="stud_id" /> 
          <result property="name" column="name" /> 
          <result property="email" column="email" /> 
          <result property="phone" column="phone" /> 
        </resultMap>

对ResultMap进行拓展
可以进行继承

    <resultMap type="属性名" id="结果集映射名称" extends="被继承的结果集映射名称"> 
      <result property="address.addrId" column="addr_id" /> 
      <result property="address.street" column="street" /> 
      <result property="address.city" column="city" /> 
      <result property="address.state" column="state" /> 
      <result property="address.zip" column="zip" /> 
      <result property="address.country" column="country" /> 
    </resultMap> 

一对一映射
我把我的代码写到这供参考

<?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">
<!-- com.briup.mappers.StudentMapper是我们定义接口的全限定名字 这样就可以使用接口调用映射的SQL语句了 这个名字一定要和接口对应上-->
<mapper namespace="com.briup.mappers.One2oneMapper">

    <!-- 一对一最基本的映射方式  最繁琐 -->

<!--    <resultMap type="Student" id="StudentResult">
        <id property="stuId" column="stud_id"/>
        <result property="name" column="name"/>
        <result property="email" column="email"/>
        <result property="phone" column="phone"/>
        <result property="dob" column="dob"/>
        <result property="address.addrId" column="addr_id"/>
        <result property="address.country" column="country"/>
        <result property="address.city" column="city"/>
        <result property="address.zip" column="zip"/>
        <result property="address.street" column="street"/>
    </resultMap> -->

    <!-- 嵌套结果 -->

     <resultMap type="Address" id="AddressResult">
        <id property="addrId" column="addr_id"/>
        <result property="street" column="street"/>
        <result property="city" column="city"/>
        <result property="state" column="state"/>
        <result property="zip" column="zip"/>
        <result property="country" column="country"/>
    </resultMap>

    <resultMap type="Student" id="StudentResult">
        <id property="stuId" column="stud_id"/>
        <result property="name" column="name"/>
        <result property="email" column="email"/>
        <result property="phone" column="phone"/>
        <result property="dob" column="dob"/>
        <association property="address" resultMap="AddressResult"></association>
    </resultMap>

    <!-- 查询所有学生的信息包括地址信息 -->
    <select id="findAllStudents" resultMap="StudentResult">
        select *
        from students s,addresses a
        where s.addr_id=a.addr_id(+)
        <!-- from students s left outer join addresses a
        on s.addr_id=a.addr_id -->
    </select>

    <!-- 嵌套查询 -->

    <resultMap type="Student" id="StudentWithAddressResult">
        <id property="stuId" column="stud_id"/>
        <result property="name" column="name"/>
        <result property="email" column="email"/>
        <result property="phone" column="phone"/>
        <result property="dob" column="dob"/>
        <association property="address" column="addr_id" select="findAddressById"></association>
    </resultMap>

    <select id="findAddressById" parameterType="int" resultMap="AddressResult">
        select *
        from addresses
        where addr_id=#{id}
    </select>

    <select id="findStudentById" parameterType="int" resultMap="StudentWithAddressResult">
        select *
        from students
        where stud_id=#{id}
    </select>


    <!-- 添加一个地址 -->
    <insert id="insertAddress" parameterType="Address">
        <selectKey resultType="int" keyProperty="addrId" order="BEFORE">
            select my_seq.nextval from dual
        </selectKey>
        insert into addresses
        values(#{addrId},#{street},#{city},#{state},#{zip},#{country})
    </insert>

    <!-- 添加一个学生 -->
    <insert id="insertStudent" parameterType="Student">
        <selectKey resultType="int" keyProperty="stuId" order="BEFORE">
            select my_seq.nextval from dual
        </selectKey>
        insert into students
        values(#{stuId},#{name},#{email},#{phone},#{dob},#{address.addrId})
    </insert>
</mapper>

多对多映射

<?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">
<!-- com.briup.mappers.StudentMapper是我们定义接口的全限定名字 这样就可以使用接口调用映射的SQL语句了 这个名字一定要和接口对应上-->
<mapper namespace="com.briup.mappers.One2ManyMapper">

    <resultMap type="Course" id="CourseResult">
        <id property="courseId" column="course_Id"/>
        <result property="name" column="cname"/>
        <result property="description" column="description"/>
        <result property="startDate" column="start_date"/>
        <result property="endDate" column="end_date"/>
    </resultMap>

    <resultMap type="Tutor" id="TutorResult">
        <id property="tutorId" column="tutor_Id"/>
        <result property="name" column="name"/>
        <result property="email" column="email"/>
        <result property="phone" column="phone"/>
        <collection property="courses" resultMap="CourseResult"/>
    </resultMap>

    <select id="findTutors" resultMap="TutorResult">
        select c.course_id,c.name cname,c.description,c.start_date,c.end_date,t.tutor_id,t.name,t.email,t.phone
        from tutors t left outer join courses c
        on t.tutor_id=c.tutor_id
    </select>

</mapper>

5.书写动态的SQL语句样例

<?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.briup.mappers.DynamicSqlMapper">

先创建了一个映射关系resultMap,方便之后的使用:

    <resultMap type="Course" id="CourseResult">
        <id property="courseId" column="course_Id"/>
        <result property="name" column="name"/>
        <result property="description" column="description"/>
        <result property="startDate" column="start_date"/>
        <result property="endDate" column="end_date"/>
    </resultMap>

条件,map参数表示用户输入的信息(讲师id,课程名字,结束时间,开始时间),可以看到where语句放的第一个条件是tutor_id,也就是说需要先在map参数中输入一个id值,再判断下面的if语句,的意思是如果courseName不为空,也就是说在map参数中又输入了一个courseName,所以才不为空,则会根据前面输入的id和后面输入的name来查找所有信息,语句有and连接,所有可以清楚的拼接出某条sql语句供使用,输入的参数不同sql语句也不同,达到动态效果。下面的startDate和endDate类似。
例:我可以在测试类中只输入一个map.put(“tutorId”,1);就可以查询,多输入map.put(“courseName”, “%Java%”);就可以达到拼接sql语句的目的来精确查询。后面我会把我的测试例子写出来

    <select id="selectCourse_if" parameterType="map" resultMap="CourseResult">
        select *
        from courses
        where tutor_id=#{tutorId}
        <if test="courseName !=null">
            and name like #{courseName}
        </if>
        <if test="startDate !=null">
            and start_date >= #{startDate}
        </if>
        <if test="endDate !=null">
            and end_date <![CDATA[<=]]> #{endDate}
        </if>
    </select>

条件,功能强大,即使不写id后面的也能加上并且会自动去除第一位的and/or语句,即与上面的if语句类似,加上了where,就没有必要必须写id之后再加其他条件,可以直接通过courseName(课程名称)或者startDate,endDate来查询。

<select id="selectCourse_where" parameterType="map" resultMap="CourseResult">
        select * from courses
        <where>
            <if test="tutorId!=null">
                tutor_id=#{tutorId}
            </if>
            <if test="courseName !=null">
                and name like #{courseName}
            </if>
            <if test="startDate !=null">
                and start_date >= #{startDate}
            </if>
            <if test="endDate !=null">
                and end_date <![CDATA[<=]]> #{endDate}
            </if>
        </where>
    </select>

条件,这条语句作用字面意思,选择一种方式来完成查询,意味着只选一种而不是像上面一个可以多个条件一起。

    <select id="selectCourse_choose" parameterType="map" resultMap="CourseResult">
        select * from courses
        <choose>
            <when test="searchBy=='Tutor'">
                where tutor_id=#{tutorId}
            </when>
            <when test="searchBy=='cName'">
                where name like #{courseName}
            </when>
            <otherwise>
                where start_date >= sysdate
            </otherwise>
        </choose>
    </select>

条件,元素和元素类似,但是提供了在添加前缀/后缀或者移除前缀/后缀方面提供更大的灵活性。
prefix表示有一个if成立则插入where语句
suffix表示后缀,和prefix相反

suffixOverrides=”and”表示如果最后生成的sql语句多一个and,则自动去掉.
prefixOverrides的意思是处理前缀,和suffixOverrides相反

    <select id="searchCourses" parameterType="map" resultMap="CourseResult"> 
        select * from courses 
        <trim prefix="where" suffixOverrides="or | and"> 
            <if test=" tutorId != null ">
                tutor_id = #{tutorId} and
            </if> 
            <if test="courseName != null"> 
                name like #{courseName} and
            </if> 
        </trim> 
    </select>

foreach循环,例如想在只输入某个id的情况下,查询出所有信息,并且查询出所有其他id的信息,foreach循环的作用就非常强大了,item中代表要输入的value值,collection中代表要输入的一个整体。

    <select id="selectCourse_foreach" parameterType="map" resultMap="CourseResult">
        select * from courses
        <if test="tutorIds!=null">
            <where>
                <foreach item="values" collection="tutorIds">
                    or tutor_id=#{values}
                </foreach>
            </where>
        </if>
    </select>

这里提供了一个生成in字句的方式:

    <!-- foreach 生成in字句 -->
    <select id="searchCoursesByTutors" parameterType="map" resultMap="CourseResult"> 
        select * from courses 
        <if test="tutorIds!= null"> 
            <where> 
                tutor_id in 
                <foreach item="Value" collection="tutorIds" open="(" separator="," close=")"> 
                    #{Value} 
                </foreach> 
            </where> 
        </if> 
    </select> 

元素和元素类似,如果其内部条件判断有任何内容返回时,他会插入SET SQL 片段。

    <update id="updateCourse" parameterType="Course"> 
        update courses  
        <set> 
        <if test="name != null">name=#{name},</if> 
        <if test="description != null">description=#{description},</if> 
        <if test="startDate != null">start_date=#{startDate},</if> 
        <if test="endDate != null">end_date=#{endDate},</if> 
        </set> 
        where course_id=#{courseId} 
    </update>
</mapper>

博主的测试接口:

public interface DynamicSqlMapper {
    public List<Course> selectCourse_if(Map<String,Object> map);
    public List<Course> selectCourse_where(Map<String,Object> map);
    public List<Course> selectCourse_choose(Map<String,Object> map);
    public List<Course> selectCourse_foreach(Map<String,Object> map);
}

测试类:

public class DynamicSqlTest {
    @Test
    public void test_selectCourse_if(){
        SqlSession session = null;
        try {
            session = MyBatisSqlSessionFactory.openSession();
            DynamicSqlMapper mapper = session.getMapper(DynamicSqlMapper.class);
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("tutorId",1);
            map.put("courseName", "%Java%");
            List<Course> course = mapper.selectCourse_if(map);
            for(Course c:course){
                System.out.println(c);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    @Test
    public void selectCourse_where(){
        SqlSession session = null;
        try {
            session = MyBatisSqlSessionFactory.openSession();
            DynamicSqlMapper mapper = session.getMapper(DynamicSqlMapper.class);
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("tutorId",2);
            map.put("courseName", "%Java%");
            List<Course> course = mapper.selectCourse_where(map);
            for(Course c:course){
                System.out.println(c);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    @Test
    public void selectCourse_choose(){
        SqlSession session = null;
        try {
            session = MyBatisSqlSessionFactory.openSession();
            DynamicSqlMapper mapper = session.getMapper(DynamicSqlMapper.class);
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("searchBy", "Tutor");
            map.put("tutorId",1);
            //////如果有第二句key值为searchBy则会执行第二句的  因为map集合里key值相同会覆盖values值
            map.put("searchBy", 1);
            map.put("courseName", "%Java%");
            List<Course> course = mapper.selectCourse_choose(map);
            for(Course c:course){
                System.out.println(c);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    @Test
    public void selectCourse_foreach(){
        SqlSession session = null;
        try {
            session = MyBatisSqlSessionFactory.openSession();
            DynamicSqlMapper mapper = session.getMapper(DynamicSqlMapper.class);
            Map<String,Object> map = new HashMap<String, Object>();
            List<Integer> list = new ArrayList<Integer>();
            list.add(1);
            map.put("tutorIds", list);
            List<Course> course = mapper.selectCourse_foreach(map);
            for(Course c:course){
                System.out.println(c);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

猜你喜欢

转载自blog.csdn.net/wei_2017/article/details/78013628