MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。下文给大家介绍Mybatis高级映射、动态SQL及获得自增主键的内容,具体详情请参考本文。
一、动态SQL
相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorList,需要根据authorList里已有的作者信息在数据库中查询相应作者的博客信息。那么最容易想到的做法就是遍历authorList,获取相应的信息查询数据库。
1
2
3
4
5
|
for ( int i=0;I < authorList. size ();i++) {
……
//查询数据库代码
// select * from blog where author=#{author,jdbcType= VARCHAR }
}
|
想一想,如果假设authorList的长度为N,那么我们就需要查询N次数据库,如果用这种方法,程序的开销不仅仅是查询,还有从数据库连接池中取出连接实例、建立数据库连接、将数据库实例返还给数据库连接池,假设这三个动作加起来总共用时0.001秒。那么采取遍历的办法查询,将会多耗时0.001N秒,如果需要查询1000次,那么将多1秒钟的时间,对于程序猿来说,这是不可忍受的,因为这只是一个循环查询,还不算其它的业务代码。
那么,有没有更好的办法呢,答案是肯定,其中之一是动态SQL:
先上代码:
1
2
3
4
5
6
|
< select id= "dynamicForeachTest" resultType= "com.blog.Blog" parameterType= "java.util.List" >
select * from blog where author in
<foreach collection= "list" index = "index" item= "item" open = "(" separator= "," close = ")" >
#{item}
</foreach>
</ select >
|
tem表示集合中每一个元素进行迭代时的别名,
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔符,
close表示以什么结束这样返回值就可以用List<Bolg>接受.
但是动态SQL中的foreach语句用的最多的实在insert语句中,并且通常在in子句中使用。
二、高级映射
在使用mybatis的时候,一般是使用resultType = com.blog.author 实体类来接受查询结果
或者是使用resultType = java.util.map将数据库列名作为key,记录值作为value返回。
但是这次需要使用resultMap,它可以允许*组合返回值的形式,用以处理更复杂的查询。
还是先上代码:
SQL:
1
2
3
4
5
6
7
|
< select id= "getBlogs" resultMap= " blogs " parameterType= "map" >
Select a.authorID,
a.uthorName,
b.blogID,
b.blogName
from author a left join blog b on a. authorID=b. authorID where a. authorID = #{authorID,jdbcType= INTEGER }
</ select >
|
mybatis配置:
1
2
3
4
5
6
7
8
|
<resultMap id= "blogs" type= "com.bloh.Blog" >
<id property= "authorID" column= " authorID" >
<result property= "authorName" column= " authorName" >
<collection property= "postsList" ofType= "com.bolg.Post" >
<id property= "blogID" column= " blogID" />
<result property= "blogName" column= "blogName" />
</collection>
</resultMap>
|
Blog实体类
1
2
3
4
5
6
|
Public class Bolg {
private Integer authorID;
private String authorName;
private List<Post> postsList;
//setter getter
}
|
Post实体类
1
2
3
4
5
|
Public class Post {
private Integer blogID;
private String blogName;
//setter getter
}
|
这样就可以用一个实体接受一个复杂查询了。
下面再介绍下各个属性的作用:
其它和普通mybatis查询的属性和配置就不细说了,
resultMap用来代替resultType,表示查询结果返回的格式
resultMap中的id主要有两个作用:
类似索引,提高查询性能
区分不同结果
所以id最好不要省略,如果没有主键,用能唯一区分记录的字段代替
result即实体类中定义的变量名,column是数据库的列名
collection 就是列表、map等集合
postsList就是在Blog实体类中定义的list变量名
ofType就是对象列表中对象的实体类。
三、获得自增ID:
如果有如下情况,在插入数据库记录后,想得到插入记录的主键,用以后面的业务代码
那么mybatis针对这种情况也提供了相应的支持(不支持批量插入):
MySQL是原声自增ID;假设自增主键的字段名就为ID
1
2
3
4
|
<insert id= "insert" useGeneratedKeys= "true" keyProperty= "id" parameterType= "User" >
insert into <include refid= "TABLE_NAME" /> ( NAME, AGE )
values ( #{name}, #{age} )
</insert>
|
比普通的插入就多了两个属性 useGeneratedKeys="true" 表示开启返回自增ID
keyProperty="id" 表示返回主键的名字。
那么在业务代码中就可以用下列语句接收:
假设实体类为User
1
|
User userNew = userMapper.insert(user);
|
userNew.getID //即为插入后的自增ID
其实,mysql的自增主键可以用select LAST_INSERT_ID();来得到,
所以,还有一种写法:
1
2
3
4
5
6
7
|
<insert id= "insert" parameterType= "User" >
<selectKey resultType= "int" order= "AFTER" keyProperty= "id" >
SELECT LAST_INSERT_ID() AS id
</selectKey>
insert into name,age
values ( #{name}, #{age} )
</insert>
|
和mysql的获取主键方式刚好相反,mysql是insert执行后由表分配自增长的值,而oracle是获取到自增长的值后再进行插入记录操作,在执行insert sql前必须指定一个主键值给要插入的记录所以要要在"BEFORE"的时候拿到自增的序列,然后用selectKey的方式注入到入参映射中即可。假设自增长还是id
1
2
3
4
5
6
7
8
|
<insert id= " insert " useGeneratedKeys= "true" keyProperty= "id" parameterType= "xxxx" >
<selectKey resultType= "int" order= "BEFORE" keyProperty= "id" >
SELECT SEQ_TABLE.NEXTVAL FROM dual
</selectKey>
INSERT INTO id,name,age
VALUES
(#{id} #{name}, #{age} )
</insert>
|
这里的id就是selectKey获得的自增id。
接收方式和mysql一样,在获取自增主键时,最好使用实体接收。
以上所述是小编给大家介绍的Mybatis高级映射、动态SQL及获得自增主键,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!