Mybatis映射文件Mapper

前提说明

  1. 使用Dao接口+映射文件的方式创建Dao对象
  2. 在接口方法参数中可以使用@Param(“别名”)来指定当前参数的名称,在映射文件中使用#{别名}来获取对应的参数值
  3. 当只有一个参数时,会自动将参数值作为PreparedStatement的参数
  4. 当具有多个参数时且不使用@param注解时,可以使用#{arg0}来指定参数下标获得,0表示第一个参数

1.insert标签

·····属性
1. id:唯一的映射名(需要与对应的方法名一致)
2. parameterType:参数类型(可以不写,接口中加入注解@Param)
3. kepProperties:主键属性
4. useGeneratedKeys:是否使用数据库生成的主键true、false

  • 当数据库不支持自动生成主键时,可以使用子标签<selectKey keyProperty="" order="BEFORE" resultType=""></selectKey>;keyProperty表示查询出主键之后赋值给某个属性,order有BEFORE和AFTER可选,表示在执行插入语句之前或者之后执行selectKey中的sql语句,resultType设置查询返回的结果类型

示例:

    <!-- 插入操作 -->
    <insert id="save" parameterType="com.oracle.vo.Book">
        <selectKey keyProperty="isbn" order="BEFORE" resultType="int">
            select max(isbn)+1 from book
        </selectKey>
        insert into
        book(isbn,bookname,price)
        values(#{isbn},#{bookName},#{price})
    </insert>

2.delete标签

常用属性

  1. id:唯一映射名称
  2. parameterType:参数类型

示例:

    <!-- 单个删除 -->
    <delete id="delete" parameterType="int" >
        delete from book where isbn=#{isbn}
    </delete>

3.update标签

常用属性:

  1. id:唯一映射名称
  2. parameterType:参数类型

示例:

    <update id="update" >
        update book set bookname=#{name} where isbn=#{isbn}
    </update>

4.select标签

常用属性:

  1. id:唯一映射名称
  2. resultType:查询返回的结果的数据类型(多条记录为每一条记录对应的类型);当查询结果来自多个表格时,可以使用Map来存储数据
  3. resultMap:高级映射
  4. useCache:是否使用缓存,默认为true

示例:

    <select id="getByParameters" resultType="com.oracle.vo.Book" useCache="true">
        <include refid="selectSql"/> where
        isbn=#{isbn} or bookname=#{name}
        <!--  isbn=#{arg0} or bookname=#{arg1} -->
    </select>

5.高级映射(<resultMap>

使用高级映射的优点
可以将多个表格中的数据映射到相互关联的vo属性上,也可以映射到list上,而不需要重新创建一个vo包含所有的查询返回字段属性
常用属性:
1. type:每条结果对应的数据类型
2. id:该高级映射的唯一标识
子标签
1. <id column="" property=""/>:主键对应的列名及对应vo的属性名
2. <result column="" property=""/>:一般数据结果对应的列名和属性名
3. <collection property="" ofType="">:一对多或者多对多映射,对应集合的类型以及集合里面元素的类型
4. <association property="" javaType="">:一对一映射,对应的属性名和属性的类型
一对多关系:
一个类关联另一个类;使用<association property="" javaType="">
一对多关系:
查询的数据中,某个表中一条数据对应其他表中的多条记录,表现在类之间的关系即为关联;
例如:某员工具有多条教育经历数据(该员工的id为教育经历表的外键),对应的vo即为:

对应员工的vo:

package com.oracle.vo;

import java.sql.Date;
import java.util.List;

public class Emp {
    private Integer empId;
    private String empName;
    private String password;
    private Date birth;
    private String email;
    private List<Education> list;//一个员工具有多条教育经历数据
    //此处省略了get和set方法
    @Override
    public String toString() {
        return "\nEmp [empId=" + empId + ", empName=" + empName + ", password=" + password + ", birth=" + birth
                + ", email=" + email + "\n教育经历:" + list + "]";
    }
}

对应教育经历的vo

package com.oracle.vo;

import java.sql.Date;

public class Education {
    private Integer educationId;
    private Integer empId;
    private String education;
    private String school;
    private String major;
    private Date beginDate;
    private Date endDate;
    //此处省略get和set方法
    @Override
    public String toString() {
        return "Education [educationId=" + educationId + ", empId=" + empId + ", education=" + education + ", school="
                + school + ", major=" + major + ", beginDate=" + beginDate + ", endDate=" + endDate + "]\n";
    }


}

则对应的resultMap为:

    <!-- 高级映射:一对多关系 -->
    <resultMap type="emp" id="myEmps">
        <id column="empId" property="empId"/>
        <result column="empName" property="empName"/>
        <result column="password" property="password"/>
        <result column="birth" property="birth"/>
        <result column="email" property="email"/>
        <!-- 映射一个集合 -->
        <collection property="list" ofType="education">
            <id column="educationId" property="educationId"/>
            <result column="education" property="education"/>
            <result column="school" property="school"/>
            <result column="major" property="major"/>
            <result column="beginDate" property="beginDate"/>
            <result column="endDate" property="endDate"/>
        </collection>

对应查询sql为:

    <select id="selectEmpById" resultMap="myEmps">
        SELECT 
        e.empId,empName,password,birth,email,educationId,education,school,major,beginDate,endDate
        FROM emp e INNER JOIN education d ON e.empId = d.empId 
        where e.empId=#{empId}
    </select>

多对多关系
例子:一个用户查询自己的订单记录,同时每条订单可能包含多个商品信息;使用<collection property="" ofType="">嵌套即可实现多对多。

6.sql片段<sql>

使用<sql id=""></sql>可以将大量重复的sql语句片段提取出来,在需要使用该sql片段的使用<include refid=""/>来引用id对应的sql片段。

示例:

    <!-- sql片段 -->
    <sql id="selectSql">
        select * from book
    </sql>
    <select id="getByParameters" resultType="com.oracle.vo.Book" >
        <!--引用sql片段-->
        <include refid="selectSql"/> where
        isbn=#{isbn} or bookname=#{name}
        <!--  isbn=#{arg0} or bookname=#{arg1} -->
    </select>

7.#{}与${}的区别

说明:

无论使用#还是$,Mybatis都时使用PreparedStatement来预编译sql语句,然后设置参数

#{}是将获取的参数使用PreparedStatement来设置对应的参数(需要模糊查询的时候可以先将参数转成需要的参数格式,比如添加%等);

当作参数获取:
    <select id="getByParameters" resultType="com.oracle.vo.Book" >
        <include refid="selectSql"/> where
        isbn=#{isbn} or bookname=#{name}
        <!--  isbn=#{arg0} or bookname=#{arg1} -->
    </select>

输出日志信息:

DEBUG - ==>  Preparing: select * from book where isbn=? or bookname=? 
DEBUG - ==> Parameters: 2(Integer), 时间简史(String)
DEBUG - <==      Total: 2
Book [isbn=2, bookName=神奇的太阳, price=98]
Book [isbn=6, bookName=时间简史, price=108]

说明:先对sql语句中#{}位置作为”?”进行预编译,然后将设置参数,共查询到两条记录

${}是将获取到的参数作为sql片段插入到sql语句中,而不是当作参数。比如查询需要按照用户选定的类型进行排序:

    <select id="selectByOrder" parameterType="String" resultType="com.oracle.vo.Book">
        select * from book order by ${arg}
    </select>

对应接口中的方法:public List<Book> selectByOrder(@Param("arg") String arg);
执行该方法,使用LOG4J输出日志信息:

。。。。
DEBUG - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6121c9d6]
DEBUG - ==>  Preparing: select * from book order by price 
DEBUG - ==> Parameters: 
DEBUG - <==      Total: 6
Book [isbn=1, bookName=活着, price=66]
Book [isbn=5, bookName=你好未来, price=88]
Book [isbn=3, bookName=C语言入门, price=96]
Book [isbn=4, bookName=深入了解java虚拟机, price=96]
Book [isbn=2, bookName=神奇的太阳, price=98]
Book [isbn=6, bookName=时间简史, price=108]

可以看出,使用${}时,仍然使用的是PreparedStatement,且没有参数,说明并没有当作参数,而是当作了sql片段,将完整的sql合成之后进行的预编译。

猜你喜欢

转载自blog.csdn.net/dingse/article/details/79666821