欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis高级映射、动态SQL及获得自增主键的解析

程序员文章站 2024-03-12 16:16:26
mybatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache software foundation 迁移到了google code,并且...

mybatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为mybatis 。下文给大家介绍mybatis高级映射、动态sql及获得自增主键的内容,具体详情请参考本文。

一、动态sql

相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorlist,需要根据authorlist里已有的作者信息在数据库中查询相应作者的博客信息。那么最容易想到的做法就是遍历authorlist,获取相应的信息查询数据库。

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:

先上代码:

<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:

<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配置:

<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实体类

public class bolg {
private integer authorid;
private string authorname;
private list<post> postslist;
//setter getter
}

post实体类

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

<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

user usernew = usermapper.insert(user);

usernew.getid //即为插入后的自增id

其实,mysql的自增主键可以用select last_insert_id();来得到,

所以,还有一种写法:

<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

<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及获得自增主键,希望对大家有所帮助