MyBatis魔法堂:Insert操作详解(返回主键、批量插入

合集下载

mysql注解批量添加mybatis_Mybatis注解方式实现批量插入数据库

mysql注解批量添加mybatis_Mybatis注解方式实现批量插入数据库

mysql注解批量添加mybatis_Mybatis注解方式实现批量插入数据库MyBatis是一个开源的持久化框架,它提供了一种简单而灵活的方式来访问关系数据库。

在MyBatis中,可以使用注解方式来实现批量插入数据库的操作。

本文将介绍如何使用MyBatis注解来实现批量插入数据。

首先,需要在Maven或Gradle中添加MyBatis依赖。

以下是使用Maven的示例配置:```xml<dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency></dependencies>```接下来,需要创建一个数据模型类,用于表示数据库中的表结构。

假设我们有一个名为User的表,包含id、name和age字段,那么对应的数据模型类可以如下所示:```javapublic class Userprivate Long id;private String name;private Integer age;// 省略getter和setter方法```然后,需要创建一个Mapper接口,用于定义数据库操作的方法。

在该接口中,我们将使用注解方式来实现批量插入数据的方法。

假设我们的Mapper接口为UserMapper,那么可以如下所示:```javapublic interface UserMapper"<script>","INSERT INTO user (name, age) VALUES ","<foreach collection='list' item='user' separator=','>","(#{}, #{user.age})","</foreach>","</script>"})```接下来,需要在MyBatis的配置文件中配置Mapper接口的扫描路径,并且使用注解配置的方式来启用Mapper接口。

mybatis里insert返回的主键id的原理

mybatis里insert返回的主键id的原理

mybatis里insert返回的主键id的原理全文共四篇示例,供读者参考第一篇示例:MyBatis是一个流行的Java持久层框架,它提供了一种优雅的方式来管理数据库访问。

在MyBatis中,当我们执行一个插入操作时,有时会需要获取插入数据后生成的主键ID,这个主键ID是数据库自动生成的,并且在插入完成后需要返回给应用程序使用。

今天我们就来深入探讨一下MyBatis里insert返回的主键ID的原理。

在MyBatis中,插入操作通常通过使用Mapper接口中的insert 方法来实现。

在执行插入操作时,我们通常会使用GeneratedKeys返回主键ID。

GeneratedKeys是MyBatis提供的一种特殊类型的Statement,它可以获取到插入数据后生成的主键ID。

GeneratedKeys还有一个重要的特性是可以通过keyColumn指定主键字段的名称,这样可以灵活地指定获取主键ID的方式。

在实际使用中,我们可以通过以下两种方法来获取插入数据后生成的主键ID:1. 通过Mapper接口的insert方法返回主键ID在Mapper接口中定义一个返回主键ID的方法,并在insert操作中通过GeneratedKeys返回主键ID。

这样我们就可以在插入数据后直接获取到生成的主键ID。

代码示例如下:```java@Insert("INSERT INTO user(username, password) VALUES(#{username}, #{password})")@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")int insertUser(User user);第二篇示例:在MyBatis中,当我们执行插入操作时,有时需要获取插入记录的主键ID。

MyBatisinsert操作插入数据之后返回插入记录的id

MyBatisinsert操作插入数据之后返回插入记录的id

MyBatisinsert操作插⼊数据之后返回插⼊记录的idMyBatis插⼊数据的时候,返回该记录的id<insert id="insert"keyProperty="id"useGeneratedKeys="true" parameterType="com.demo.domain.CountRateConfig">insert into query_rate_config (code,partner_type,search_count, booking_count, ticket_count,rate_type)values (#{code,jdbcType=VARCHAR},#{partnerType,jdbcType=TINYINT}, #{searchCount,jdbcType=INTEGER}, #{bookingCount,jdbcType=INTEGER}, #{ticketCount,jdbcType=INTEGER},#{rateType,jdbcType=TINYINT}) </insert>⾸先我们应该保证数据库的主键Id是⾃增的,另外需要设置的两个属性为:keyProperty="id"useGeneratedKeys="true"这样的话,我们在插⼊数据之后,就可以得到插⼊数据之后的对象,然后通过该对象获取该对象的id。

useGeneratedKeys=”true” 可以获取⾃增长的ID 只⽀持具有⾃增长⽅式的那种数据库(mysql, mssql 等但 oracle 就不⽀持了 )案例如下:1、MyBatis的配置⽂件如上遍所⽰的⼀段代码;2、使⽤的Java代码如下:@Overridepublic int insert(CountRateConfig countRateConfig) {int insertNum = Integer.parseInt(countRateConfigMapper.insert(countRateConfig) + "");Long id = countRateConfig.getId();return insertNum;}3、上述代码,如果插⼊数据成功的话,则可以找到数据库中对应的key;结果是正确的,即可以读取正确的id。

Mybatis笔记–insert语句中主键的返回

Mybatis笔记–insert语句中主键的返回

Mybatis笔记–insert语句中主键的返回在DBMS中可以使⽤insert语句显⽰指定⾃增主键值,但Mybatis中不可,即使指定了也⽆效,可以使⽤特殊的⽅式返回主键。

⼀、⾃增主键返回mysql⾃增主键执⾏insert提交之前,会⾃动⽣成⼀个⾃增主键值;insert语句在提交之后可以调⽤mysql函数LAST_INSERT_ID(),返回auto_increment⾃增列新记录id值;最后再将⾃增主键值返回到pojo对象中指定的属性中即可。

这个函数只适⽤于⾃增主键。

1、标签属性标签对应的属性含义如下:keyProperty:返回的主键存储在pojo类中的哪个属性order:相对于insert语句,select LAST_INSERT_ID() 的执⾏顺序resultType:指定select LAST_INSERT_ID() 的结果类型2、详细代码1 <insert id="insertEmp" parameterType="po.Emp">2 <selectKey keyProperty="empno" order="AFTER" resultType="ng.Integer">3 select LAST_INSERT_ID()4 </selectKey>5 insert into emp(ename,job) values(#{ename},#{job})6 </insert>可以通过po类的get()⽅法获取⾃增主键值,代码如下:1//返回⾃增主键2 System.out.println(emp.getEmpno());3、运⾏结果⼆、⾮⾃增主键(UUID)返回使⽤mysql的uuid()函数⽣成主键,需要修改表中id字段类型为string,长度设置成36位(设置成35位会出错)。

mybatis批量插入并返回主键(序列)-oracle

mybatis批量插入并返回主键(序列)-oracle

mybatis批量插⼊并返回主键(序列)-oracle需求:批量插⼊数据,并返回每条数据的主键(序列),因为这⾥是采⽤序列⽣成唯⼀的主键的,其实oracle批量插⼊操作有⼏种,⽹上百度都是有相关资源的。

但是笔者现在的需求是,不仅批量插⼊数据后,并返回每条数据的主键,⽹上查阅了⼀番始终没有找到,相应办法,倒是针对mysql貌似mybatsi是⽀持批量返回主键的,因为笔者没有测试,所有不敢妄下⾔论。

好了,说了这么多,直接进⼊正题:1、参照⽹上的相关资源,如图所⽰<insert id="saveEPDetail" useGeneratedKeys="true" parameterType="java.util.List"><selectKey keyProperty="code" resultType="String" order="BEFORE">select SEQ_DIS_DRUG_PRESC_DETAIL.NEXTVAL as code from dual</selectKey>INSERT INTO DIS_DRUG_PRESC_DETAIL(code,antibac_purpose,ref_price,)SELECT SEQ_DIS_DRUG_PRESC_DETAIL.NEXTVAL,t.*FROM (<foreach collection="list" item="item" separator="UNION ALL">select#{item.antibacPurpose,jdbcType=VARCHAR},#{item.skintObserver2,jdbcType=VARCHAR}from dual</foreach>) t</insert>结果批量插⼊式成功了,单主键code打死都没有返回,如是⼀条条插⼊⼜要加锁最后的解决⽅式:因为笔者这⾥是采⽤序列⽣成的主键,于是在插⼊数据的时候,先调⽤⼀下序列获取到序列值,再赋值给主键code,最后进⾏批量插⼊操作。

MyBatisinsert语句返回主键和selectKey标签方式

MyBatisinsert语句返回主键和selectKey标签方式

MyBatisinsert语句返回主键和selectKey标签⽅式⽬录insert语句返回主键和selectKey标签1.主键⾃增的情况2.Oracle中⽤Sequence获取主键MyBatis insert语句key的⽣成和返回1.使⽤数据库⾃带的⽣成器2.使⽤selectKeyinsert语句返回主键和selectKey标签往数据库中插⼊⼀条记录后,有时候我们需要这条记录的主键,⽤于后续的操作。

如果在插⼊后再去查⼀次数据库,显然不够优雅和效率,MyBatis中已经有了insert后返回主键的功能,下⾯就主要讲⼏种不同情况的具体做法。

1.主键⾃增的情况对于MySQL和Sql Server这种⽀持主键⾃增的数据库,可以设置useGeneratedKeys="true"和keyProperty。

例如现在有⼀个表tbl_employee,表有id,name,age,create_time四个字段,MyBatis映射⽂件中可以写成如下:<insert id="insertRecord" parameterType="com.lzumetal.mybatis.entity.Employee"useGeneratedKeys="true" keyProperty="id">INSERT INTO tbl_employee(name, age, create_time)VALUES(#{name}, #{age}, #{createTime})</insert>useGeneratedKeys="true":使⽤⾃动⽣成的主键keyProperty:指定主键是(javaBean的)哪个属性。

useGeneratedKeys:(insert and update only) This tells MyBatis to use the JDBC getGeneratedKeys method to retrieve keys generated internally by the database (e.g.auto increment fields in RDBMS like MySQL or SQL Server). Default: falsekeyProperty:(insert and update only) Identifies a property into which MyBatis will set the key value returned bygetGeneratedKeys , or by a selectKey child element of the insert statement. Default: unset .Can be a comma separated list of property names if multiple generated columns are expected.2.Oracle中⽤Sequence获取主键对于Oracle数据库,当要⽤到⾃增字段时,需要⽤到Sequence,假设我们现在已经创建了⼀个名字为SEQ_ADMIN的Sequence,在MyBatis中的映射⽂件中可以结合selectKey标签使⽤。

mybatis批量insert的写法

mybatis批量insert的写法

在MyBatis 中,你可以使用以下两种方式来进行批量插入:方法一:使用<foreach>标签MyBatis 提供了<foreach>标签,你可以使用它来遍历集合,并对集合中的每个元素执行SQL 语句。

以下是使用<foreach>标签进行批量插入的示例:xml复制代码<insert id="batchInsert" parameterType="java.util.List">INSERT INTO your_table (column1, column2, ...)VALUES<foreach collection="list" item="item" separator=",">(#{item.column1}, #{item.column2}, ...)</foreach></insert>在上面的示例中,你需要将your_table替换为你要插入数据的表名,column1, column2, ...替换为表中的列名。

list是传递给SQL 语句的参数名称,item是每次遍历的元素名称。

方法二:使用ExecutorType.BATCH执行器MyBatis 还提供了ExecutorType.BATCH执行器,它专门用于批量操作。

以下是使用ExecutorType.BATCH执行器进行批量插入的示例:java复制代码try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { YourMapper mapper = sqlSession.getMapper(YourMapper.class);for (YourObject obj : yourList) {mapper.insert(obj);}mit();} catch (Exception e) {// 处理异常}在上面的示例中,你需要将YourMapper替换为你的Mapper 接口,YourObject替换为你要插入的对象类型,yourList替换为包含要插入对象的列表。

Mybatis批量增加insert

Mybatis批量增加insert

Mybatis批量增加insert⽅法⼀:foreach容易出现的错误:出现SQL语句错误解决⽅式:在数据库的连接url后添加allowMultiQueries=true(允许批量更新)jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true例⼦:xml⽂件<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.center.manager.mapper.FundMapper"><insert id="insertForeach" parameterType="java.util.List" useGeneratedKeys="false">insert into fund( id,fund_name,fund_code,date_x,data_y,create_by,create_date,update_by,update_date,remarks,del_flag)<foreach collection="list" item="item" index="index" separator=","> values(#{item.id}, #{item.fundName},#{item.fundCode},#{item.dateX},#{item.dataY},#{item.createBy},#{item.createDate},#{item.updateBy},#{item.updateDate},#{item.remarks},#{item.delFlag})</foreach></insert></mapper>mapper层package com.center.manager.mapper;import java.util.List;import org.apache.ibatis.annotations.Mapper;import com.center.manager.entity.Fund;@Mapperpublic interface FundMapper {int insertForeach(List<Fund> list);}Fun类package com.center.manager.entity;import java.util.Date;@datapublic class Fund {private String id;private String fundName;private String fundCode;private String dateX;private String dataY;private String remarks;private String createBy;private Date createDate;private String updateBy;private Date updateDate;private String delFlag;}⽅法⼆:Mybatis内置的ExecutorType有3种,默认的是simple,该模式下它为每个语句的执⾏创建⼀个新的预处理语句,单条提交sql;⽽batch模式重复使⽤已经预处理的语句,并且批量执⾏所有更新语句,显然batch性能将更优;service层@Autowiredprivate SqlSessionTemplate sqlSessionTemplate;public void add(List<ApplyInfo> list) {SqlSession sessionn = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);AddInfoDap mapper = session.getMapper(AddInfo.class);for(int i = 0; i < list.seize ; i++) {mapper.addApplicationDetail(lisr.get(i));if(i == list.size()-1) {mit();session.close();}}}xml层<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.center.manager.mapper.FundMapper"><insert id="addApplicationDetail" parameterType="com.dao.entity.ApplyInfo">insert into fund( id,fund_name,fund_code,date_x,data_y,create_by,create_date,update_by,update_date,remarks,del_flag) values(#{item.id}, #{item.fundName},#{item.fundCode},#{item.dateX},#{item.dataY},#{item.createBy},#{item.createDate},#{item.updateBy},#{item.updateDate},#{item.remarks},#{item.delFlag})</foreach></insert></mapper>mapper层void addApplicationDetail(ApplyInfo infos)。

mybatis注解方式批量添加对象,批量返回主键ID

mybatis注解方式批量添加对象,批量返回主键ID

mybatis注解⽅式批量添加对象,批量返回主键ID @Insert("<script> insert into USER(xxx,xxx,xxx) values"<foreach collection='users' item='user' index = 'index' separator=','>" +"(#{user.xxx},#{user.xxx},#{user.xxx}) " +"</foreach> </script>")@Options(useGeneratedKeys = true,keyColumn = "ID", keyProperty = "users.id")int batchInsert(@Param("users")List<User> users);注解⽅式 - 注意点:keyColumn 表⽰数据库表主键字段,适⽤mysql的⾃增主键keyProperty 表⽰实体主键字段,必须要加users,不然mybatis 不知道把主键赋值给哪个参数@Param("users") 必须加上批量插⼊后,返回的主键都赋值给了users列表,通过users既可获取所有的主键Id,进⾏下⼀步操作XML ⽅式:void batchInsert(List<User> list);<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">insert into USER(XXX,XXX,XXX)values<foreach collection="list" item="user" separator=",">(#{userxxx},#{userxxx},#{user.xxx})</foreach></insert>dao层不需要@Param注解,使⽤集合⽤ list命名。

mybatis+mysqlinsert添加数据后返回数据主键id

mybatis+mysqlinsert添加数据后返回数据主键id

mybatis+mysqlinsert添加数据后返回数据主键id1.根据useGeneratedKeys获取返回值,部分数据库不⽀持修改mybatis xml<insert id="insertUser" useGeneratedKeys="true" keyProperty="id" parameterType="er">insert into test (name) values (#{name})</insert>useGeneratedKeys="true" :设置是否使⽤JDBC的getGenereatedKeys⽅法获取主键并赋值到keyProperty设置的领域模型属性中。

(适⽤于mysql、sqlserver数据库,oracle不能使⽤,使⽤selectkey⼦节点做)keyProperty:赋值的对象的属性名称。

添加完成后,直接根据对象属性取值。

user u=new user();u.setName("测试");System.out.println(u.getId()+"取值前");int num = this.dao.getSqlSession().insert("insertUser",u);System.out.println(u.getId()+"取值后");2.根据selectkey获取<insert id="insertUser" parameterType="er">insert into test (name) values (#{name})<selectKey keyProperty="id" resultType="ng.Integer">select LAST_INSERT_ID() as id</selectKey></insert>后台代码不变。

MyBatis在insert插入操作时返回主键ID的配置

MyBatis在insert插入操作时返回主键ID的配置

MyBatis在insert插⼊操作时返回主键ID的配置很多时候,在向数据库插⼊数据时,需要保留插⼊数据的id,以便进⾏后续的update操作或者将id存⼊其他表作为外键。

但是,在默认情况下,insert操作返回的是⼀个int值,并且不是表⽰主键id,⽽是表⽰当前SQL语句影响的⾏数。

接下来,我们看看MyBatis如何在使⽤MySQL和Oracle做insert插⼊操作时将返回的id绑定到对象中。

MySQL⽤法:<insert id="insert" parameterType="er" keyProperty="userId" useGeneratedKeys="true">上⾯配置中,“keyProperty”表⽰返回的id要保存到对象的那个属性中,“useGeneratedKeys”表⽰主键id为⾃增长模式。

MySQL中做以上配置就OK了,较为简单,不再赘述。

Oracle⽤法:<insert id="insert" parameterType="er"><selectKey resultType="INTEGER" order="BEFORE" keyProperty="userId">SELECT SEQ_USER.NEXTVAL as userId from DUAL</selectKey>insert into user (user_id, user_name, modified, state)values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{modified,jdbcType=TIMESTAMP}, #{state,jdbcType=INTEGER})</insert>Oracle⽤法中,需要注意的是:由于Oracle没有⾃增长⼀说法,只有序列这种模仿⾃增的形式,所以不能再使⽤“useGeneratedKeys”属性。

mybatismysql批量insert返回主键

mybatismysql批量insert返回主键

mybatismysql批量insert返回主键Mybatis在插⼊单条数据的时候有两种⽅式返回⾃增主键: mybatis3.3.1⽀持批量插⼊后返回主键ID,⾸先对于⽀持⾃增主键的数据库:useGenerateKeys和keyProperty。

不⽀持⽣成⾃增主键的数据库:<selectKey>。

这⾥主要说下批量插⼊数据时如何返回主键ID(注意要将mybatis升到3.3.1)public class UserInfo{private int userId;private String userName;private StringuserPwd;public long getUserId() {return userId;}public void setUserId(long userId) {erId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {erName = userName;}public String getUserPwd() {return userPwd;}public void setUserPwd(String userPwd) {erPwd = userPwd;}}Daopublic interface UserDao{ int insertTest(List<UserInfo> userInfo);}mapper<insert id="insertTest" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="userId">insert into t_sys_course (user_name,user_pwd)values<foreach collection="list" item="item" index="index"separator=",">(#{erName,jdbcType=VARCHAR},#{erPwd,jdbcType=VARCHAR})</foreach></insert>serviceImplpublic List<UserInfo> saveCheckin(List<UserInfo> userInfo) {userDao.insertCheckin(userInfo);return userInfo;}//返回的对象List⾥⾯已经包含主键ID。

MyBatis中insert操作返回主键的实现方法

MyBatis中insert操作返回主键的实现方法

MyBatis中insert操作返回主键的实现⽅法在使⽤MyBatis做持久层时,insert语句默认是不返回记录的主键值,⽽是返回插⼊的记录条数;如果业务层需要得到记录的主键时,可以通过配置的⽅式来完成这个功能针对Sequence主键⽽⾔,在执⾏insert sql前必须指定⼀个主键值给要插⼊的记录,如Oracle、DB2,可以采⽤如下配置⽅式:<insert id="add" parameterType="vo.Category"><selectKey resultType="ng.Short" order="BEFORE" keyProperty="id">SELECT SEQ_TEST.NEXTVAL FROM DUAL</selectKey>insert into category (name_zh, parent_id,show_order, delete_status, description)values (#{nameZh,jdbcType=VARCHAR},#{parentId,jdbcType=SMALLINT},#{showOrder,jdbcType=SMALLINT},#{deleteStatus,jdbcType=BIT},#{description,jdbcType=VARCHAR})</insert>针对⾃增主键的表,在插⼊时不需要主键,⽽是在插⼊过程⾃动获取⼀个⾃增的主键,⽐如MySQL,可以采⽤如下两种配置⽅式:<insert id="add" parameterType="vo.Category" useGeneratedKeys="true" keyProperty="id">insert into category (name_zh, parent_id,show_order, delete_status, description)values (#{nameZh,jdbcType=VARCHAR},#{parentId,jdbcType=SMALLINT},#{showOrder,jdbcType=SMALLINT},#{deleteStatus,jdbcType=BIT},#{description,jdbcType=VARCHAR})</insert>或<insert id="add" parameterType="vo.Category"><selectKey resultType="ng.Short" order="AFTER" keyProperty="id">SELECT LAST_INSERT_ID() AS id</selectKey>insert into category (name_zh, parent_id,show_order, delete_status, description)values (#{nameZh,jdbcType=VARCHAR},#{parentId,jdbcType=SMALLINT},#{showOrder,jdbcType=SMALLINT},#{deleteStatus,jdbcType=BIT},#{description,jdbcType=VARCHAR})</insert>在插⼊操作完成之后,参数category的id属性就已经被赋值了如果数据库表的主键不是⾃增的类型,那么就需要应⽤层⽣成主键的⽅式··········这个就不多说了,需要的朋友,可以留⾔交流··下⾯是针对Oracle的写法,Oracle没有autoincrement,⽽是⽤触发器实现的 CURRVAL是在触发器中定义的.<insert id="insert" parameterClass="ProFeeKindObject"><![CDATA[INSERT INTO t_pro_feeKind (KINDID,kindName,kindType,enable)VALUES (seq_t_pro_feekind_id.nextval,#kindName#,#kindType#,#enable#)]]><selectKey resultClass="ng.Integer" keyProperty="kindId" >SELECT seq_t_pro_feekind_id.CURRVAL AS kindId FROM DUAL</selectKey></insert><!-- 下⾯是针对MySQL的写法 --><!--<selectKey resultClass="int" keyProperty="id" >SELECT @@IDENTITY AS id</selectKey>-->其他参考代码:持久化某个实体对象(如保存⼀个对象)时,如果我们不⽤selectKey,那么我们不会⽴刻得到实体对象的Id属性的,也就是数据表主键Java代码Permission permission = new Permission();permission.set...permmisonDao.createPermission(permission);assertNull(permission);Permission permission = new Permission();permission.set...permmisonDao.createPermission(permission);assertNull(permission);selectKey元素与其在⽗元素中的位置有关<insert id="addPermission" parameterClass="Permission"><selectKey resultClass="int" keyProperty="permissionId">SELECT SEQ_P_PERMISSION.NEXTVAL FROM DUAL</selectKey>INSERT INTO P_PERMISSION (PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL) VALUES (#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#)</insert><insert id="addPermission" parameterClass="Permission"><selectKey resultClass="int" keyProperty="permissionId">SELECT SEQ_P_PERMISSION.NEXTVAL FROM DUAL</selectKey>INSERT INTO P_PERMISSION (PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL) VALUES (#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#)</insert>Mysql、SQLServer在后Xml代码<insert id="addPermission" parameterClass="Permission">INSERT INTO P_PERMISSION (PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL) VALUES (#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#)<selectKey resultClass="int" keyProperty="permissionId">SELECT LAST_INSERT_ID()</selectKey></insert><insert id="addPermission" parameterClass="Permission">INSERT INTO P_PERMISSION (PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL) VALUES (#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#)<selectKey resultClass="int" keyProperty="permissionId">SELECT LAST_INSERT_ID()</selectKey></insert>像上⾯这样书写,与selectKey的位置联系得太紧密了,iBatis的sqlMap配置⽂件的selectKey元素有个type属性,可以指定pre 或者post表⽰前⽣成还是后⽣成。

Mybatis批量插入返回插入成功后的主键id操作

Mybatis批量插入返回插入成功后的主键id操作

Mybatis批量插⼊返回插⼊成功后的主键id操作我们都知道Mybatis在插⼊单条数据的时候有两种⽅式返回⾃增主键:1、对于⽀持⽣成⾃增主键的数据库:增加 useGenerateKeys和keyProperty ,<insert>标签属性。

2、不⽀持⽣成⾃增主键的数据库:使⽤<selectKey>。

但是怎么对批量插⼊数据返回⾃增主键的解决⽅式⽹上看到的还是⽐较少,⾄少百度的结果⽐较少。

Mybatis官⽹资料提供如下:First, if your database supports auto-generated key fields (e.g. MySQL and SQL Server), then you can simply set useGeneratedKeys="true" and set the keyProperty to the target property and you're done. For example, if the Authortable above had used an auto-generated column type for the id, the statement would be modified as follows:<insert id="insertAuthor" useGeneratedKeys="true"keyProperty="id">insert into Author (username,password,email,bio)values (#{username},#{password},#{email},#{bio})</insert>id="insertAuthor" useGeneratedKeys="true"keyProperty="id">insert into Author (username,password,email,bio)values (#{username},#{password},#{email},#{bio})</insert>If your database also supports multi-row insert, you can pass a list or an array of Authors and retrieve the auto-generated keys.<insert id="insertAuthor" useGeneratedKeys="true"keyProperty="id">insert into Author (username, password, email, bio) values<foreach item="item" collection="list" separator=",">(#{ername}, #{item.password}, #{item.email}, #{item.bio})</foreach></insert>id="insertAuthor" useGeneratedKeys="true"keyProperty="id">insert into Author (username, password, email, bio) values<foreach item="item" collection="list" separator=",">(#{ername}, #{item.password}, #{item.email}, #{item.bio})</foreach></insert>从官⽹资料可以看出Mybatis是⽀持批量插⼊时返回⾃增主键的。

MyBatis批量插入返回主键

MyBatis批量插入返回主键

MyBatis批量插⼊返回主键 ⽹上有很多⼈说MyBatis不⽀持批量插⼊并且返回主键,其实这种说法有⼀定的误解,如果你想让MyBatis直接返回⼀个包含主键的list,即mapper接⼝中批量插⼊⽅法的返回值为List<Integer>,这样的确是不⾏的 例如:录⼊学⽣成绩 数据库:mysql//错误的写法public List<Integer> batchInsert(List<Student> students); 这种想法是错误的,为了把这个错误解释得明⽩⼀点,我们还是先看看单条插⼊的时候是如何返回主键的吧,下⾯是MyBatis官⽅⽂档 也就是说只要在insert标签⾥加⼊useGeneratedKeys="true"和keyProperty="id"即可,mapper接⼝这样写public int insert(Student student); xml<insert id="insert" useGeneratedKeys="true" keyProperty="id">insert into student (name, score) values (#{name}, #{score})</insert> 运⾏之后会发现,返回值始终是1,也就是返回值是受影响的⾏数。

返回的主键实际上被映射到了参数student的id属性中,只需student.getId()即可得到Student student = new Student("⼩明", 77);int line = mapper.insert(student);System.out.println("受影响的⾏数:" + line);System.out.println("返回的主键:" + student.getId()); 运⾏结果: 接下来说批量插⼊,其实⼀样的原理,下⾯是官⽅⽂档,使⽤foreach批量插⼊,返回主键的⽅法还是那样 mapper接⼝public int batchInsert(List<Student> students); xml<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">insert into student (name, score) values<foreach collection="list" item="item" index="index" separator=",">(#{}, #{item.score})</foreach></insert> 测试插⼊List<Student> students = new ArrayList<Student>();Student tom = new Student("Tom", 88);Student jerry = new Student("Jerry", 99);students.add(tom);students.add(jerry);int line = mapper.batchInsert(students);System.out.println("受影响的⾏数:" + line);for (Student student : students) {System.out.println("返回的主键:" + student.getId());} 运⾏结果 综上,MyBatis是可以批量插⼊并返回主键的,不过返回的主键不是在mapper接⼝的返回值⾥⾯(有点绕,其实很简单),⽽是映射到了参数的id属性⾥⾯。

Mybatisinsert方法主键回填和自定义操作

Mybatisinsert方法主键回填和自定义操作

Mybatisinsert⽅法主键回填和⾃定义操作在数据库插⼊的时候,有很多属性需要我们⾃⼰处理,如主键⾃增字段。

MYSQL中主键根据⼀定规则⽣成后,需要我们在插⼊后去主动获取,以便后⾯的操作,Mybatis为我们提供了处理的⽅法。

主键回填keyProperty:指定哪个字段是主键useGeneratedKeys:这个主键是否使⽤数据库内置⽣成策略我们可以在XML⽂件中进⾏如下配置:<insert id="insertUser" parameterType="user" useGeneratedKeys="true" keProperty="id">insert into t_user(user_name,age) values (#${userName},#{age})</insert>这样我们传⼊的user对象⽆需设置id字段,Mybatis会⾃动进⾏设置处理,插⼊成功后id字段会回填到user对象中。

使⽤⾃定义规则⽣成主键实际⼯作上有时候主键的⽣成规则并不是这么简单,⽐如我们取消t_user的主键⾃增规则。

我们的要求是:如果t_user表没有数据,我们也要设置主键为1,否则就取主键最⼤值加2,来设置新的主键。

对此,Mybatis也提供了处理⽅法,使⽤SelectKey元素进⾏处理<insert id="insertUser" parameterType="user" useGeneratedKeys="true" keProperty="id"><SelectKey keProperty="id" resultType="int" order="BEFORE>select if(max(id) is null, 1, max(id) + 2) as newId from t_user</SelectKey>insert into t_user(user_name,age) values (#${userName},#{age})</insert>这样我们就可以根据⾃定义的规则来处理⽣成主键了。

Mybatis+Mysql插入数据库返回自增主键id值的三种方法

Mybatis+Mysql插入数据库返回自增主键id值的三种方法

Mybatis+Mysql插⼊数据库返回⾃增主键id值的三种⽅法⼀、场景:插⼊数据库的值需要⽴即得到返回的主键id进⾏下⼀步程序操作⼆、解决⽅法:第⼀种:使⽤通⽤mapper的插⼊⽅法Mapper.insertSelective(record);此⽅法:插⼊⼀条数据,只插⼊不为null的字段,不会影响有默认值的字段⽀持Oracle序列,UUID,类似Mysql的INDENTITY⾃动增长(⾃动回写)优先使⽤传⼊的参数值,参数值空时,才会使⽤序列、UUID,⾃动增长controller的实际应⽤:使⽤⽅法id会直接将映射到参数的实体上使⽤时直接使⽤参数的实体get获取值第⼆种:编写sql语句dao层⽅法:[java]1. /**2. * 插⼊数据库并返回主键id3. * @param batch4. * @return5. */6. Integer insertBatchReturnId(Batch batch);xml的sql语句写法记得加上useGeneratedKeys和keyProperty配置即可,前者是指设置是否使⽤jdbc的getGenereatedKeys⽅法获取主键并赋值到keyProperty 设置的属性中,后者即实体类主键字段(并且⼤⼩写要对应上)[html]1. <insert id="insertBatchReturnId" useGeneratedKeys="true" keyProperty="id" parameterType="org.uz.dxt.model.bankbase.Batch" >2.3. insert into t_batch (4. batchCode,5. bankCode,6. bizType,7. companyCode,8. wtEndDate,9. wtDate,10. contractId,11. totalCount,12. totalBase,13. handCode)14. values15. ( #{batchcode},16. #{bankcode},17. #{biztype},18. #{companycode},19. #{wtenddate},20. #{wtdate},21. #{contractid},22. #{totalcount},23. #{totalbase},24. #{handCode})25. </insert>controller的实际应⽤:使⽤⽅法id会直接将映射到参数的实体上使⽤时直接使⽤参数的实体get获取值[java]1. batchService.insertBatch(param);//实体2. idlist.add(param.getId());第三种:sql语句使⽤<selectKey>获取⾃增逐渐id[html]1. <insert id="add" parameterType="EStudent">2. // 下⾯是SQLServer获取最近⼀次插⼊记录的主键值的⽅式3. <selectKey resultType="_long" keyProperty="id" order="AFTER">4. select @@IDENTITY as id5. </selectKey>6. insert into TStudent(name, age) values(#{name}, #{age})7. </insert>使⽤⽤法同上这⾥推荐使⽤第⼀种和第⼆种中⽅法第三种⽅法对oracl额外的配置controller的实际应⽤:使⽤⽅法id会直接将映射到参数的实体上使⽤时直接使⽤参数的实体get获取值。

mybatis批量插入数据

mybatis批量插入数据

mybatis批量插⼊数据 1.先说插⼊数据到mysql中的mapper.xml写法: 参数都是list<model>类型<!--批量插⼊--><insert id="batchInsertStudent" parameterType="java.util.List">INSERT INTO STUDENT (id,name,sex,tel,address)VALUES<foreach collection="list" item="item" index="index" separator=",">(#{item.id},#{},#{item.sex},#{item.tel},#{item.address})</foreach></insert><!--批量删除--><delete id="batchDeleteStudent" parameterType="java.util.List">DELETE FROM STUDENT WHERE id IN<foreach collection="list" index="index" item="item" open="(" separator="," close=")">#{item}</foreach></delete><!--批量修改--><update id="batchUpdateStudentWithMap" parameterType="java.util.Map">UPDATE STUDENT SET name = #{name} WHERE id IN<foreach collection="idList" index="index" item="item" open="(" separator="," close=")">#{item}</foreach></update> 2.oracle这种做法会报”java.sql.SQLException: ORA-00933: SQL 命令未正确结束“ 错误 正确做法如下: 参数都是list<model>类型 第⼀种:使⽤ insert all into table(...) values(...) into table(...) values(...) select * from dual; 语句来解决 <insert id="addList" parameterType="java.util.List" useGeneratedKeys="false">INSERT ALL<foreach item="item" index="index" collection="list">INTO T_APPLAUD(ID,USER_ID,BUSINESS_TYPE,PRODUCT_ID,CREATE_TIME) VALUES(#{item.id, jdbcType=NUMERIC},#{erId, jdbcType=VARCHAR},#{item.businessType, jdbcType=VARCHAR},#{item.productId, jdbcType=VARCHAR},#{item.createdTime, jdbcType=NUMERIC})</foreach>SELECT 1 FROM DUAL</insert> 如果还报”java.sql.SQLException: ORA-00933: SQL 命令未正确结束“ 错误,原因可能是mybatis批量插⼊oracle时没有显式指定为 useGeneratedKeys="false" 不然报错~~~ 另外⼀种⽅法是 insert into table(...) (select ... from dual) union all (select ... from dual) <insert id="addList" parameterType="java.util.List" useGeneratedKeys="false">INSERT INTO T_APPLAUD(ID,USER_ID,BUSINESS_TYPE,PRODUCT_ID,CREATE_TIME)<foreach item="item" index="index" collection="list" separator="union all">(SELECT#{item.id},#{erId},#{item.businessType}, #{item.productId},#{item.createdTime} FROM DUAL)</foreach></insert>。

MyBatis批量操作

MyBatis批量操作

MyBatis批量操作前⾔:在项⽬中遇到了需要批量操作数据表的情况,笔者遇到的是更新操作。

但在mybatis中批量操作有多种,因此在此对mybatis中的批量操作以及其注意点进⾏总结。

1.批量插⼊操作批量插⼊,传⼊的是⼀个List对象的集合,因此在mapper⽂件中需要⽤循环的⽅式进⾏操作,具体格式如下:<insert id="insertBatch" parameterType="java.utils.List">insert into tablename (xxx,xxx,xxx)values/*collection的属性值为接⼝中对应的参数名称(#{item.xxx},#{item.xxx},#{item.xxx}通过属性的⽅式取得对应的值,注意⼩括号的使⽤*/<foreach collection="listxxx" item="item" separator=",">(#{item.xxx},#{item.xxx},#{item.xxx})</foreach></insert>mapper⽂件对应的接⼝形式如下:public void insertBatch(@Param("listxxx") List<xxx> listxxx);2.批量更新操作批量更新操作,笔者总结了下⾯两种⽅式:①使⽤循环update形式【这种⽅式需要特别注意,需要在数据库连接字符串中增加allowMultiQueries=true,不然会报异常】<update id="batchUpdate" parameterType="java.util.List"><foreach collection="list" index="index" item="item" separator=";">update t_demo_user set<if test="erName!=null">user_name=#{erName},</if><if test="item.gender!=null">gender=#{item.gender}</if>where user_id=#{erId}</foreach></update>②使⽤ case 形式<update id="batchUpdate" parameterType="java.util.List">UPDATE t_demo_user<trim prefix="set" suffixOverrides=","><trim prefix="user_name= case" suffix="end,"><foreach collection="list" item="item" index="index"><if test="erName !=null">when user_id=#{erId} then #{erName}</if></foreach></trim><trim prefix="gender= case" suffix="end,"><foreach collection="list" item="item" index="index"><if test="item.gender !=null">when user_id=#{erId} then #{item.gender}</if></foreach></trim></trim>where user_id in<foreach collection="list" item="item" index="index" separator="," open="(" close=")">#{erId}</foreach></update>通过以上⽅式可实现批量插⼊与批量更新,但是笔者并没有进⾏效率⽅⾯的测试,也可能直接批处理效率更⾼。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、前

数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅。

二、 insert元素属性详解
其属性如下:
parameterType ,入参的全限定类名或类型别名
keyColumn ,设置数据表自动生成的主键名。

对特定数据库(如PostgreSQL),若自动生成的主键不是第一个字段则必须设置
keyProperty ,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中
useGeneratedKeys ,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys 方法获取主键并赋值到keyProperty设置的领域模型属性中。

MySQL和SQLServer执行auto-generated key field,因此当数据库设置好自增长主键后,可通过JDBC的getGeneratedKeys方法获取。

但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了
statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLE
flushCache ,取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存
timeout ,默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常
databaseId ,取值范围oracle|mysql等,表示数据库厂家,元素内部可通过`<if test="_databaseId = ‘oracle‘">`来为特定数据库指定不同的sql语句
三、一般的INSERT操作——返回值为插入的记录数目mapper接口代码:
/**
* 添加学生信息
* @param student 学生实例
* @return 成功操作的记录数目
*/
int add(EStudent student);
mapper.xml:
<insert id="add" parameterType="EStudent">
insert into TStudent(name, age) values(#{name}, #{age})
</insert
四、执行INSERT操作后获取记录主键
mapper接口代码:
/**
* 添加学生信息
* @param student 学生实例
* @return 成功操作的记录数目
*/
int add(EStudent student);
至于mapper.xml则分为两种情况了,一种是数据库(如MySQL,SQLServer)支持auto-generated key field,另一种是数据库(如Oracle)不支持auto-generated key field的。

1. 数据库(如MySQL,SQLServer)支持auto-generated key field的情况
手段①(推荐做法):
<insert id="add" parameterType="EStudent" useGeneratedKeys="true" keyProperty="id">
insert into TStudent(name, age) values(#{name}, #{age})
</insert>
手段②:
<insert id="add" parameterType="EStudent">
// 下面是SQLServer获取最近一次插入记录的主键值的方式
<selectKey resultType="_long" keyProperty="id" order="AFTER">
select @@IDENTITY as id
</selectKey>
insert into TStudent(name, age) values(#{name}, #{age})
</insert>
由于手段②获取主键的方式依赖数据库本身,因此推荐使用手段①。

2. 数据库(如Oracle)不支持auto-generated key field的情况
<insert id="add" parameterType="EStudent">
<selectKey keyProperty="id" resultType="_long" order="BEFORE">
select CAST(RANDOM * 100000as INTEGER) a FROM
SYSTEM.SYSDUMMY1
</selectKey>
insert into TStudent(id, name, age) values(#{id}, #{name}, #{age})
</insert
注意:mapper接口返回值依然是成功插入的记录数,但不同的是主键值已经赋值到领域模型实体的id中了。

五、 selectKey子元素详解
作用:在insert元素和update元素中插入查询语句。

其属性如下:
keyProperty ,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中
resultType ,keyPropety所指向的属性类全限定类名或类型别名
order属性,取值范围BEFORE|AFTER,指定是在insert语句前还是后执行selectKey操作
statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLE
注意:selectKey操作会将操作查询结果赋值到insert元素的parameterType的入参实例下对应的属性中。

并提供给insert语句使用
六、批量插入
方式1:
<insert id="add" parameterType="EStudent">
<foreach collection="list" item="item" index="index" separator=";">
INSERT INTO TStudent(name,age) VALUES(#{}, #{item.age})
</foreach>
</insert>
上述方式相当语句逐条INSERT语句执行,将出现如下问题:
1. mapper接口的add方法返回值将是最一条INSERT语句的操作成功的记录数目(就是0或1),而不是所有INSERT语句的操作成功的总记录数目
2. 当其中一条不成功时,不会进行整体回滚。

方式2(仅限于MSSQL):
<insert id="add" parameterType="EStudent">
WITH R AS
<foreach collection="list" item="item" index="index" open="(" close=")" separator="union all">
SELECT #{} as a, #{item.age} as b
</foreach>
INSERT INTO TStudent(name,age) SELECT a, b FROM R
</insert>
上述方式解决了方式1中的问题。

但该方式仅限于MSSQL
方式3(通用解决方法):
INSERT INTO TStudent(name,age)
<foreach collection="list" item="item" index="index" open="(" close=")" separator="union all">
SELECT #{} as a, #{item.age} as b
</foreach>
该方式与方式2效果一样,而且不仅限于MSSQL。

相关文档
最新文档