mybatis入门看这一篇就够了
Mybatis 介绍
MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。
2013 年 11 月迁移到 Github。MyBatis 是一个优秀的持久层框架,它对 jdbc 的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建 connection、创建 statement、手动设置参数、结果集检索等 jdbc 繁杂的过程代码。Mybatis 通过 xml 或注解的方式将要执行的各种 statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过 java 对象和 statement 中的 sql 进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射成 java 对象并返回。
Mybatis 框架
框架介绍
1、 mybatis 配置
SqlMapConfig.xml,此文件作为 mybatis 的全局配置文件,配置了 mybatis 的运行环境等信息。
mapper.xml 文件即 sql 映射文件,文件中配置了操作数据库的 sql 语句。此文件需要在 SqlMapConfig.xml 中加载。
2、 通过 mybatis 环境等配置信息构造 SqlSessionFactory 即会话工厂
3、 由会话工厂创建 sqlSession 即会话,操作数据库需要通过 sqlSession 进行。
4、 mybatis 底层自定义了 Executor 执行器接口操作数据库,Executor 接口有两个实现,一个是基本执行器、一个是缓存执行器。
5、 Mapped Statement 也是 mybatis 一个底层封装对象,它包装了 mybatis 配置信息及 sql 映射信息等。mapper.xml 文件中一个 sql 对应一个 Mapped Statement 对象,sql 的 id 即是 Mapped statement 的 id。
6、 Mapped Statement 对 sql 执行输入参数进行定义,包括 HashMap、基本类型、pojo,Executor 通过 Mapped Statement 在执行 sql 前将输入的 java 对象映射至 sql 中,输入参数映射就是 jdbc 编程中对 preparedStatement 设置参数。
7、 Mapped Statement 对 sql 执行输出结果进行定义,包括 HashMap、基本类型、pojo,Executor 通过 Mapped Statement 在执行 sql 后将输出结果映射至 java 对象中,输出结果映射过程相当于 jdbc 编程中对结果的解析处理过程。
利用 IDEA 创建 Mybatis 的入门案例
8 个步骤
- 创建 maven 工程,什么都不选就 ok, 并导入坐标;
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<span class="hljs-tag"><<span class="hljs-name">dependency</span>></span>
<span class="hljs-tag"><<span class="hljs-name">groupId</span>></span>junit<span class="hljs-tag"></<span class="hljs-name">groupId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">artifactId</span>></span>junit<span class="hljs-tag"></<span class="hljs-name">artifactId</span>></span>
<span class="hljs-tag"><<span class="hljs-name">version</span>></span>4.10<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dependency</span>></span>
</dependencies>
- 编写 User 实体类
public class User implements Serializable {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
<span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">getId</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> id;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setId</span><span class="hljs-params">(<span class="hljs-type">int</span> id)</span> {
<span class="hljs-built_in">this</span>.id = id;
}
<span class="hljs-keyword">public</span> String <span class="hljs-title function_">getUsername</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> username;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setUsername</span><span class="hljs-params">(String username)</span> {
<span class="hljs-built_in">this</span>.username = username;
}
<span class="hljs-keyword">public</span> String <span class="hljs-title function_">getSex</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> sex;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setSex</span><span class="hljs-params">(String sex)</span> {
<span class="hljs-built_in">this</span>.sex = sex;
}
<span class="hljs-keyword">public</span> Date <span class="hljs-title function_">getBirthday</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> birthday;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setBirthday</span><span class="hljs-params">(Date birthday)</span> {
<span class="hljs-built_in">this</span>.birthday = birthday;
}
<span class="hljs-keyword">public</span> String <span class="hljs-title function_">getAddress</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> address;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setAddress</span><span class="hljs-params">(String address)</span> {
<span class="hljs-built_in">this</span>.address = address;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-keyword">public</span> String <span class="hljs-title function_">toString</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> <span class="hljs-string">"User [id="</span> + id + <span class="hljs-string">", username="</span> + username + <span class="hljs-string">", sex="</span> + sex
+ <span class="hljs-string">", birthday="</span> + birthday + <span class="hljs-string">", address="</span> + address + <span class="hljs-string">"]"</span>;
}
}
-
在 resources 文件夹中,创建 Mybatis 的主配置文件 SqlMapConfig.xml。它是 mybatis 核
心配置文件,配置文件内容为数据源、事务管理。
配置环境:
- 配置 mysql 的环境:
- 配置事务的类型;
- 配置连接池:配置连接数据库的 4 个基本信息;
- 指定映射配置文件的位置:
代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置 mysql 的环境 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接池 -->
<dataSource type="POOLED">
<!-- 配置连接数据库的 4 个基本信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.214.128:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="ben123"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置,映射配置文件指的是每个 dao 独立的配置文件 -->
<mappers>
<mapper resource="com/ben/dao/IUserDao.xml"/>
</mappers>
</configuration>
- 在 resources 文件夹中导入 log4j.properties 文件
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
- 编写映射文件 IUserDao.xml ,位置在目录 resource->sqlmap->User.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空间,用于隔离 sql,还有一个很重要的作用,后面会讲 -->
<mapper namespace="test">
</mapper>
- 加载映射文件,将 User.xml 添加在 SqlMapConfig.xml 下
<!-- 指定映射配置文件的位置 -->
<mappers>
<mapper resource="sqlmao/User.xml"/>
</mappers>
- 编写测试类:在 test->java 目录下创建测试类 com.ben.test.MybatisTest。实现业务需求,共 7 步,其中 2,3 步可以合在一起。
1. 加载核心配置文件SqlMapConfig.xml
2. 创建SqlSessionFactoryBuilder对象
3. 创建SqlSessionFactory对象(2,3可以写一起)
4. 创建SqlSession对象
5. 执行SqlSession对象执行查询,获取结果User
6. 打印结果
7. 释放资源
代码如下:
package com.ben.test;
import com.ben.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
- @ClassName: MybatisTest
- @author: benjamin
- @version: 1.0
- @description: TODO
- @createTime: 2019/07/13/11:50
*/
public class MybatisTest {
public static void main(String[] args) {
}
<span class="hljs-comment">//通过Id查询一个用户</span>
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testSearchById</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException {
<span class="hljs-comment">//1.读取配置文件</span>
<span class="hljs-type">InputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> Resources.getResourceAsStream(<span class="hljs-string">"SqlMapConfig.xml"</span>);
<span class="hljs-comment">//2.创建SqlSessionFactory工厂</span>
<span class="hljs-type">SqlSessionFactory</span> <span class="hljs-variable">sqlSessionFactory</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SqlSessionFactoryBuilder</span>().build(in);
<span class="hljs-comment">//3.使用工厂生产SqlSession对象</span>
<span class="hljs-type">SqlSession</span> <span class="hljs-variable">session</span> <span class="hljs-operator">=</span> sqlSessionFactory.openSession();
<span class="hljs-comment">//4.执行Sql语句</span>
<span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> session.selectOne(<span class="hljs-string">"test.findUserById"</span>, <span class="hljs-number">10</span>);
<span class="hljs-comment">//5. 打印结果</span>
System.out.println(user);
<span class="hljs-comment">//6.释放资源</span>
session.close();
in.close();
}
<span class="hljs-comment">//根据用户名模糊查询用户列表</span>
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testFindUserByUsername</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException {
<span class="hljs-comment">//1.读取配置文件</span>
<span class="hljs-type">InputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> Resources.getResourceAsStream(<span class="hljs-string">"SqlMapConfig.xml"</span>);
<span class="hljs-comment">//2.创建SqlSessionFactory工厂</span>
<span class="hljs-type">SqlSessionFactory</span> <span class="hljs-variable">sqlSessionFactory</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SqlSessionFactoryBuilder</span>().build(in);
<span class="hljs-comment">//3.使用工厂生产SqlSession对象</span>
<span class="hljs-type">SqlSession</span> <span class="hljs-variable">session</span> <span class="hljs-operator">=</span> sqlSessionFactory.openSession();
<span class="hljs-comment">//4.执行Sql语句</span>
List<User> list = session.selectList(<span class="hljs-string">"test.findUserByUsername"</span>, <span class="hljs-string">"王"</span>);
<span class="hljs-comment">//5. 打印结果</span>
<span class="hljs-keyword">for</span> (User user:list) {
System.out.println(user);
}
<span class="hljs-comment">//6.释放资源</span>
session.close();
in.close();
}
<span class="hljs-comment">//添加用户</span>
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testInsertUser</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException {
<span class="hljs-comment">//1.读取配置文件</span>
<span class="hljs-type">InputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> Resources.getResourceAsStream(<span class="hljs-string">"SqlMapConfig.xml"</span>);
<span class="hljs-comment">//2.创建SqlSessionFactory工厂</span>
<span class="hljs-type">SqlSessionFactory</span> <span class="hljs-variable">sqlSessionFactory</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SqlSessionFactoryBuilder</span>().build(in);
<span class="hljs-comment">//3.使用工厂生产SqlSession对象</span>
<span class="hljs-type">SqlSession</span> <span class="hljs-variable">sqlSession</span> <span class="hljs-operator">=</span> sqlSessionFactory.openSession();
<span class="hljs-comment">//4.执行Sql语句</span>
<span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">User</span>();
user.setUsername(<span class="hljs-string">"小强"</span>);
user.setBirthday(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());
user.setAddress(<span class="hljs-string">"sadfsafsafs"</span>);
user.setSex(<span class="hljs-string">"2"</span>);
<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> sqlSession.insert(<span class="hljs-string">"test.insertUser"</span>, user);
sqlSession.commit();
<span class="hljs-comment">//5. 打印结果</span>
<span class="hljs-comment">// 刚保存用户,此时用户ID需要返回。执行完上面insert程序后,此时就能知道用户的ID是多少</span>
<span class="hljs-comment">// 需要在User.xml文件中配置</span>
System.out.println(<span class="hljs-string">"插入id:"</span>+user.getId());<span class="hljs-comment">//插入id:30</span>
<span class="hljs-comment">//6.释放资源</span>
sqlSession.close();
in.close();
}
<span class="hljs-comment">//更新用户</span>
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testUpdateUserById</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException {
<span class="hljs-comment">//1.读取配置文件</span>
<span class="hljs-type">InputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> Resources.getResourceAsStream(<span class="hljs-string">"SqlMapConfig.xml"</span>);
<span class="hljs-comment">//2.创建SqlSessionFactory工厂</span>
<span class="hljs-type">SqlSessionFactory</span> <span class="hljs-variable">sqlSessionFactory</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SqlSessionFactoryBuilder</span>().build(in);
<span class="hljs-comment">//3.使用工厂生产SqlSession对象</span>
<span class="hljs-type">SqlSession</span> <span class="hljs-variable">sqlSession</span> <span class="hljs-operator">=</span> sqlSessionFactory.openSession();
<span class="hljs-comment">//4.执行Sql语句</span>
<span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">User</span>();
user.setId(<span class="hljs-number">27</span>);
user.setUsername(<span class="hljs-string">"小小"</span>);
user.setBirthday(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());
user.setAddress(<span class="hljs-string">"西安市"</span>);
user.setSex(<span class="hljs-string">"1"</span>);
<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> sqlSession.insert(<span class="hljs-string">"test.updateUserById"</span>, user);
sqlSession.commit();
<span class="hljs-comment">//5. 打印结果</span>
System.out.println(user.getId());
<span class="hljs-comment">//6.释放资源</span>
sqlSession.close();
in.close();
}
<span class="hljs-comment">//删除用户</span>
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testDeleteUserById</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException {
<span class="hljs-comment">//1.读取配置文件</span>
<span class="hljs-type">InputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> Resources.getResourceAsStream(<span class="hljs-string">"SqlMapConfig.xml"</span>);
<span class="hljs-comment">//2.创建SqlSessionFactory工厂</span>
<span class="hljs-type">SqlSessionFactory</span> <span class="hljs-variable">sqlSessionFactory</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SqlSessionFactoryBuilder</span>().build(in);
<span class="hljs-comment">//3.使用工厂生产SqlSession对象</span>
<span class="hljs-type">SqlSession</span> <span class="hljs-variable">sqlSession</span> <span class="hljs-operator">=</span> sqlSessionFactory.openSession();
<span class="hljs-comment">//4.执行Sql语句</span>
<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> sqlSession.insert(<span class="hljs-string">"test.deleteUserById"</span>, <span class="hljs-number">32</span>);
sqlSession.commit();
<span class="hljs-comment">//5. 打印结果</span>
System.out.println(i);
<span class="hljs-comment">//6.释放资源</span>
sqlSession.close();
in.close();
}
}
- 配置映射配置文件 User.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:用来区别不同的类的名字 -->
<mapper namespace="test">
<span class="hljs-comment"><!-- 通过Id查询一个用户 --></span>
<span class="hljs-tag"><<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"findUserById"</span> <span class="hljs-attr">parameterType</span>=<span class="hljs-string">"Integer"</span> <span class="hljs-attr">resultType</span>=<span class="hljs-string">"com.ben.domain.User"</span>></span>
select * from user where id = #{v}
<span class="hljs-tag"></<span class="hljs-name">select</span>></span>
<span class="hljs-comment"><!-- 根据用户名模糊查询用户列表 --></span>
<span class="hljs-comment"><!-- select * from user where username like '%${value}%'--></span>
<!-- select * from user where username like "%"#{value}"%"-->
<select id="findUserByUsername" parameterType="String" resultType="com.ben.domain.User">
select * from user where username like #{username}
</select>
<!-- 添加用户 -->
<insert id="insertUser" parameterType="com.ben.domain.User">
<selectKey keyProperty="id" resultType="Integer" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,address,sex) values(#{username},#{birthday},#{address},#{sex})
</insert>
<!-- 更新用户 -->
<update id="updateUserById" parameterType="com.ben.domain.User">
update user
set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
where id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteUserById" parameterType="Integer">
delete from user
where id = #{vvvvv}
</delete>
</mapper>
注意事项
详解参数
namespace:用来区别不同的类的名字
id:标识映射文件中的sql,称为statement的id将sql语句封装到mappedStatement对象中,所以将id称为statement的id
parameterType:指定输入参数的类型.
resultType:指定输出结果类型。mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
#{}:一个占位符。preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}:表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
解释 select 语句
这一部分参考 mybatis 官网。详情点击http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
<select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User">
select * from user where id = #{v}
</select>
这个语句被称作 findUserById, 接受一个 Integer 类型的参数,返回一个 User 对象。#{V} 告诉 mybatis 创建一个预处理语句参数,在 JDBC 中,这个的一个参数在 Sql 中会由一个“ ?”表示,并被传递到新的预处理语句中,如:
// 近似的 JDBC 代码,并非 Mybatis 代码
String findUserById = "select * from user where id = ?";
PreparedStatement ps = conn.prepareStatement(findUserById);
ps.setInt(1,id);
使用 JDBC 意味着需要更多的代码来提取结果并将它们映射到对象实例中,而这就是 MyBatis 节省你时间的地方.
注意
- 在根据用户名模糊查询中注意:有两种写法。
1.测试类中这样写:
List<User> list = session.selectList("test.findUserByUsername", "王");
在User.xml中写:
select * from user where username like '%${value}%'
其对应的实际sql操作语句:select * from user where username like'% 五 %'
也可以这样写:
select * from user where username like "%"#{value}"%" # value 可以换成haha
其对应的sql查询语句是:select * from user where username like"%"'五'"%"
2.如果测试类中这样写:
List<User> list = session.selectList("test.findUserByUsername", "%王%");
User.xml这样写
select * from user where username like #{username}
其中username可以换成haha等其他名称。
- 执行插入操作时,保存成功,但是 id=0,需要解决 id 返回不正常的问题。如果刚保存用户,此时用户 ID 需要返回。执行完上面 insert 程序后,此时就能知道用户的 ID 是多少,需要在插入之前补充语句:
<selectKey keyProperty="id" resultType="Integer" order="AFTER">
select LAST_INSERT_ID()
</selectKey>