(转)Mybatis高级映射、动态SQL及获得自增主键
原文:http://www.cnblogs.com/edwinchen/p/4105278.html?utm_source=tuicool&utm_medium=referral
一、动态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一样,在获取自增主键时,最好使用实体接收。
作者<ahref="http: www.cnblogs.com="" edwinchen="" "="" target"_blank"="">瞪着太阳的乌鸦
(转)Mybatis高级映射、动态SQL及获得自增主键的更多相关文章
- Mybatis高级映射、动态SQL及获得自增主键
一.动态SQL 相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorList,需要根据authorList里已有的作者信息在数据库中查询相应作者 ...
- MyBatis 3.2.6插入时候获取自增主键方法
MyBatis 3.2.6插入时候获取自增主键方法有二 以MySQL5.5为例: 方法1: <insert id="insert" parameterType="P ...
- 关于mybatis用mysql时,插入返回自增主键的问题
公司决定新项目用mybatis,虽然这个以前学过但是一直没用过都忘得差不多了,而且项目比较紧,也没时间去系统点的学一学,只好很粗略的百度达到能用的程度就行了. 其中涉及到插入实体要求返回主键id的问题 ...
- mybatis执行insert后马上能获取自增主键的语句写法
<!--keyColumn keyProperty useGeneratedKeys 用于在插入数据后,能直接使用user.getId()获取主键--> <insert id=&qu ...
- Mybatis批量插入返回自增主键(转)
我们都知道Mybatis在插入单条数据的时候有两种方式返回自增主键: 1.对于支持生成自增主键的数据库:useGenerateKeys和keyProperty. 2.不支持生成自增主键的数据库:< ...
- 【Mybatis高级映射】一对一映射、一对多映射、多对多映射
前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...
- mybatis高级映射(一对一,一对多)
mybatis高级映射 一对一关联映射 需求:查询订单信息,关联查询用户信息(一个订单对应一个用户) (1)通过resultType实现 sql语句: select orders.* , USER.u ...
- 【mybatis深度历险系列】mybatis中的动态sql
最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...
- mybatis 高级映射和spring整合之逆向工程(7)
mybatis 高级映射和spring整合之逆向工程(7) 4.0 逆向工程 4.1 mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行 ...
随机推荐
- Linux系统下的程序开发之:命名规范
2016年12月13日16:19:53 ------------------------------- 不能使用类似驼峰法的命名文件:dingdanOrder.html 这样的命名,会让系统无法找到目 ...
- 第四章 电商云化,4.2 集团AliDocker化双11总结(作者: 林轩、白慕、潇谦)
4.2 集团AliDocker化双11总结 前言 在基础设施方面,今年双11最大的变化是支撑双11的所有交易核心应用都跑在了Docker容器中.几十万Docker容器撑起了双11交易17.5万笔每秒的 ...
- (转)CPU Cache与内存对齐
转自:http://blog.csdn.net/zhang_shuai_2011/article/details/38119657 原文如下: 一. CacheCache一般来说,需要关心以下几个方面 ...
- redis教程(整理中)
一.redis简介 1.Redis:键值对类型的内存数据库:应用于高并发和实时请求的场景: 2.Redis常用数据类型: (1) string(基本数据类型) (2)hash 注:hash中的 ...
- Android 四大组件之Service
---恢复内容开始--- 1,Service的生命周期
- 不要在控制台上使用 let/const
考虑下面的这三句代码和对应的报错信息: 假设写这个代码的人一开始不知道 ES6 里新增的构造函数不能省略 new,于是第一行写错了.然后第二行尝试重新声明一次,结果又报错说重复声明了.那干脆不声明,直 ...
- linux下实现在程序运行时的函数替换(热补丁)
声明:以下的代码成果,是参考了网上的injso技术,在本文的最后会给出地址,同时非常感谢injso技术原作者的分享. 但是injso文章中的代码存在一些问题,所以后面出现的代码是经过作者修改和检测的. ...
- 项目里面的某个资源文件(比如plist、音频等)无法使用
检查:Build Phases -> Copy Bundle Resources
- GDI+ 笔记
1.GDI+模板 #include<windows.h> #include<GdiPlus.h> #include <time.h> #include <ma ...
- SQL Server基础知识
1.SQL Server表名为什么要加方括号? 这个不是必须要加,但表名或字段名如果引用了sqlserver中的关键字,数据库会不识别这到底是关键字还是表名(或字段名)时就必须要加. 比如,一个表名叫 ...