Mybatis Mapper XML 映射文件的一些标签引用
SQL映射文件有很少的几个顶级元素:
① cache - 给定命名空间的缓存配置
② cache-ref - 其他空间命名缓存配置的引用
③ resultMap - 是最复杂也是最强大的元素, 用来描述如何从数据库结果集中来加载对象。
④ sql - 可被其他语句引用的可重用语句块
⑤ insert - 映射插入语句
⑥ update - 映射更新语句
⑦ delete - 映射删除语句
⑧ select - 映射查询语句
下面来描述每个标签元素的细节
一、Select
查询语句是Mybatis 中最常用的元素之一,也是数据库操作中最常用的语句之一
简单的select元素是非常简单的, 比如:
<select id = "select" parameterType="int" resultType="hashmap">
select * from student where id = #{id}
</select>
这样的写法的意思是接受一个int(或Integer)类型的参数,并返回一个HashMap类型的对象,其中的键是列名,值便是结果行中的对应值,注意参数符号: #{id}
select 元素有很多属性可以允许你去配置,来决定每条语句的作用细节
<select
id="selectPerson"
parameterType="int"
parameterMap="deprecated"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
① id : 在命名空间中唯一的标识符, 可以被用来引用这条语句
② parameterType : 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为mybatis可以通过TypeHandler推断出具体传入语句的参数,默认为unset
③ resultType: 返回期望的类型的类的完全限定名或别名。 注意如果是集合情形,那应该是集合可以包含的类型,而不是集合本身。 使用resultType 或 resultMap, 但不能同时使用
④ resultMap : 返回的map集合类型, 使用resultType 或 resultMap, 但不能同时使用
⑤ flushCache: 将其设置为true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值为 false
⑥ useCache: 将其设置为true,将会导致本条语句的结果被二级缓存,默认值:对select标签元素设置为true
⑦ timeout: 这个设置是抛出异常之前,驱动程序等待数据库返回请求结果的秒数,默认值为unset(依赖驱动)
⑧ fetchSize:这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等
⑨ statementType: statement, prepared或callable的一个。
⑩ resultSetType:forward_only, scroll_sensitive或scroll_insensitive
二、 Insert、 update、 和 delete语句
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">
<update
id="updateAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
例子:
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
</update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
</delete>
三、 cache和cache-ref元素
1、 cache元素
Mybatis 包含一个强大的、可配置并可定制的查询缓存机制。Mybatis3 的缓存实现有了许多的改进,使其更强大更容易配置。 默认情况下, 缓存是没有开启的,出了会话缓存以外。 会话缓存可以提高性能,且能解决循环依赖。 开启二级缓存,只需要在SQL映射文件中加入简单的一行。
<cache /> 这句简单的语句作用如下:
① 所有映射文件里的select语句的结果都会被缓存
② 所有映射文件里的insert、update和delete语句执行都会清空缓存
③ 缓存使用最近最少使用算法(LRU)来回收
④ 缓存不会被设定的时间所清空
⑤ 每个缓存可以存储1024个列表或对象的引用
⑥ 缓存作为“读/写”缓存,意味着检索的对象不是共享的且可以被调用者安全地修改,而不会被其他调用者或线程干扰
所有这些特性都可以通过cache元素进行修改
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
2、cache-ref元素
除了在某一个命名空间里使用cache元素配置或者刷新缓存。但有可能在不同的命名空间里共享同一个缓存配置或者实例。在这种情况下,则可以使用cache-ref元素来引用另一个缓存:
<cache-ref namespace="" />
四、 Result Map
resultMap 元素的作用是将数据集的列映射到Map结果集,例 :
比如有一个实体类User:
public class User {
private int id;
private String username;
private String hashedPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getHashedPassword() {
return hashedPassword;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
}
Mapper文件中查询user的数据:
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
注意返回的类型是一个Map : userResultMap, 下面我们来定义一个resultMap
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
正常地,mybatis在查询语句中返回数据集时,在映射javaBean时,mybatis只会映射与数据库表中的列名一致的属性,有一些情况下,数据库表中字段名和javaBean中实体类的属性名不一致时候,可以借用resultMap的作用来匹配javaBean的属性名和数据库表中的字段名
ResultMap 元素内置标签
1、 constructor - 用于在实例化类时,注入结果到构造方法中
① idArg - ID 参数标记出作为ID 的结果可以帮助提高整体性能
② arg - 将被注入到构造方法的一个普通结果
2、 id - 一个ID结果,标记出作为ID的结果可以帮助提高整体性能
3、 result - 注入到字段或javaBean属性的普通结果
4、 association - 一个复杂类型的关联;许多结果将包装成这个类型
嵌套结果映射 - 集合可以指定为一个resultMap元素,或者引用一个
5、 collection - 一个复杂类型的集合
嵌套结果映射 - 集合可以指定一个resultMap元素,或者引用一个
6、 discriminator - 使用结果值来决定使用那个resultMap
case - 基于某些值的结果映射
嵌套结果映射 - 一个case 也是一个映射它本身的结果,因此可以包含很多相同的元素,或者它可以参照一个外部的resultMap
ResultMap 元素标签属性
1、 id - 当前命名空间的一个唯一的标识,用于表示一个result map
2、 type - 类的完全限定名,或者一个类型别名
3、 autoMapping - 如果设置这个属性,Mybatis将会为这个ResultMap开启或者关闭自动映射,这个覆盖全局的属性默认值:unset
resultMap 例子
1、查询书籍的信息
书本Book类:
public class Book {
private String isbn;
private String bookName;
private double price;
private Date publishDate;
private String publisher;
//mybatis是orm框架,设计实体类时需要把表关系转成对象关系 - 本例是多对一关系
//has-a ,is-a,use-a
private Category category;
public Book() {
super();
}
public Book(String isbn, String bookName, double price, Date publishDate, String publisher) {
super();
this.isbn = isbn;
this.bookName = bookName;
this.price = price;
this.publishDate = publishDate;
this.publisher = publisher;
}
public Book(String isbn, String bookName, double price, Date publishDate, String publisher, Category category) {
super();
this.isbn = isbn;
this.bookName = bookName;
this.price = price;
this.publishDate = publishDate;
this.publisher = publisher;
this.category = category;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Date getPublishDate() {
return publishDate;
}
public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
@Override
public String toString() {
return "Book [isbn=" + isbn + ", bookName=" + bookName + ", price=" + price + ", publishDate=" + publishDate
+ ", publisher=" + publisher + ", category=" + category + "]";
}
}
书本分类 Category类:
public class Category {
private int id;
private String name;
//把数据关系转换成对象关系,本例是一对多的关系
private List<Book> books;
public Category() {
super();
}
public Category(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Category(int id, String name, List<Book> books) {
super();
this.id = id;
this.name = name;
this.books = books;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Category [id=" + id + ", name=" + name + ", books=" + books + "]";
}
}
Mapper xml文件配置:查询书籍信息(带分类)
<select id="findAllWithCategory" resultMap="bookMap2">
select * from book b,category c where b.category_id=c.id
</select>
resultMap 配置
<!-- 多对一或一对一关联查询方法2 -->
<!-- mybatis不提供多对多映射,如果是多对多关系需要转换为一对多和多对一关系 -->
<resultMap type="Book" id="bookMap2">
<id column="isbn" property="isbn"/>
<result column="book_name" property="bookName"/>
<result column="price" property="price"/>
<result column="publish_date" property="publishDate"/>
<result column="publisher" property="publisher"/>
<association property="category" column="category_id" javaType="Category">
<id column="id" property="id"/>
<result column="name" property="name"/>
</association>
</resultMap>
2、 查询分类信息下的所有书本
<!-- 关联查询方法1 -->
<!-- 对于复杂数据关系,mybatis可以支持自定义数据的关系映射 -->
<resultMap id="categoryMap" type="Category" >
<!-- 在自定义的关系映射中,可以通过配置每个查询结果与java对象的映射关系 -->
<!-- id标签一般用于配置主键列或唯一键列 -->
<id column="id" property="id" />
<result column="name" property="name"/>
<!-- 一对多关系可以使用collection进行配置 -->
<!-- property是集合的名称,ofType是集合的元素类型 -->
<collection property="books" ofType="Book">
<id column="isbn" property="isbn"/>
<result column="book_name" property="bookName"/>
<result column="price" property="price"/>
<result column="publish_date" property="publishDate"/>
<result column="publisher" property="publisher"/>
<!-- 多对一 或 一对一 关系 -->
<result column="category_id" property="category.id"/>
</collection>
</resultMap>
<select id="findCategoryAndBooks" resultMap="categoryMap">
<!-- 查询语句如果数据库表的列名与类的属性名相同,直接用列名进行查询;如果不相同则需要使用别名,别名与属性名相同 -->
select c.id,c.name,b.isbn,b.book_name,b.price,b.publish_date,b.publisher,b.category_id
from category c left join book b on c.id=b.category_id
</select>