Mybatis映射文件Mapper
前提说明
- 使用Dao接口+映射文件的方式创建Dao对象
- 在接口方法参数中可以使用@Param(“别名”)来指定当前参数的名称,在映射文件中使用#{别名}来获取对应的参数值
- 当只有一个参数时,会自动将参数值作为PreparedStatement的参数
- 当具有多个参数时且不使用@param注解时,可以使用#{arg0}来指定参数下标获得,0表示第一个参数
1.insert标签
·····属性
- id:唯一的映射名(需要与对应的方法名一致)
- parameterType:参数类型(可以不写,接口中加入注解@Param)
- kepProperties:主键属性
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标签
常用属性
- id:唯一映射名称
- parameterType:参数类型
示例:
<!-- 单个删除 -->
<delete id="delete" parameterType="int" >
delete from book where isbn=#{isbn}
</delete>
3.update标签
常用属性:
- id:唯一映射名称
- parameterType:参数类型
示例:
<update id="update" >
update book set bookname=#{
name} where isbn=#{
isbn}
</update>
4.select标签
常用属性:
- id:唯一映射名称
- resultType:查询返回的结果的数据类型(多条记录为每一条记录对应的类型);当查询结果来自多个表格时,可以使用Map来存储数据
- resultMap:高级映射
- 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包含所有的查询返回字段属性
常用属性:
- type:每条结果对应的数据类型
- id:该高级映射的唯一标识
子标签 <id column="" property=""/>
:主键对应的列名及对应vo的属性名<result column="" property=""/>
:一般数据结果对应的列名和属性名<collection property="" ofType="">
:一对多或者多对多映射,对应集合的类型以及集合里面元素的类型<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合成之后进行的预编译。
还没有评论,来说两句吧...