技术标签: mybatis insert 【MyBatis】
和 MyBatis-03 MyBatis XML方式之select元素比起来,insert要简单的多。 只有让它返回主键值时,由于不同的数据库的主键生成方式不同,这种情况会复杂一点。
/**
*
*
* @Title: insertSysUser
*
* @Description: 增加SysUser
*
* @param sysUser
* @return
*
* @return: int 受影响的行数
*/
int insertSysUser(SysUser sysUser);
<!-- 添加SysUser -->
<insert id="insertSysUser" >
insert into sys_user(
id,user_name, user_password, user_email,
user_info, head_img, create_time)
values(
#{
id},#{
userName}, #{
userPassword}, #{
userEmail},
#{
userInfo}, #{
headImg, jdbcType=BLOB}, #{
createTime, jdbcType=TIMESTAMP})
</insert>
先看下insert元素标签包含的属性
id:命名空间中的唯一标示符
parameterType:传入的语句参数的全限定类名或者别名,因为 MyBatis可以推断传入语句的具体参数,因此不建议配置该属性
flushCache :默认true,任何时候只要语句被调用,都会清空一级缓存和二级缓存
timeout:设置在抛出异常之前,驱动程序等待数据库返回请求结果的秒数
statementType : 默认PREPARED
useGenerateKeys: 默认false. 如果设置为true , MyBatis会使用JDBC的getGeneratedKeys方法取出由数据库内部生成的主键
keyProperty: MyBatis通过getGeneratedKeys获取组建后要将辅助的属性名。
keyColumn:仅对UPDATE和INSERT又有,通过生成的键值设置表中的列名。
databaseId:如果配置了databaseIdProvider, MyBatis会加载所有的不带databaseId或者匹配当前databaseId的语句。 如果同时存在带databaseId和不带databaseId的语句,后者将被忽略。
此外,insert中的sql语句就是一个简单的insert语句,将所有的列都列举出来,在value中通过#{property}方式从参数中取出属性的值。
为了防止类型错误,对于一些特殊的数据类型,建议指定具体的jdbcType值#{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP}
@Test
public void insertSysUserTest() {
logger.info("insertSysUserTest");
// 获取SqlSession
SqlSession sqlSession = getSqlSession();
try {
// 获取UserMapper接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
SysUser sysUser = new SysUser();
sysUser.setUserName("artisanTest");
sysUser.setUserPassword("123456");
sysUser.setUserEmail("[email protected]");
sysUser.setUserInfo("测试用户");
// 模拟头像
sysUser.setHeadImg(new byte[] { 1, 2, 3 });
sysUser.setCreateTime(new Date());
// 新增用户 ,返回受影响的行数
int result = userMapper.insertSysUser(sysUser);
// 只插入一条数据 ,期望是1
Assert.assertEquals(1, result);
// id 为null , 因为没有给ID赋值,也没有配置回写id的值 ,期望是null
Assert.assertNull(sysUser.getId());
logger.info("受影响的行数:" + result);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 为了保持测试数据的干净,这里选择回滚
// 由于默认的sqlSessionFactory.openSession()是不自动提交的
// 除非显式的commit,否则不会提交到数据库
sqlSession.rollback();
logger.info("为了保持测试数据的干净,这里选择回滚,不写入mysql,请观察日志,回滚完成");
sqlSession.close();
logger.info("sqlSession close successfully ");
}
}
日志
2018-04-15 18:32:49,378 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully
2018-04-15 18:32:49,383 INFO [main] (BaseMapperTest.java:29) - reader close successfully
2018-04-15 18:32:49,386 INFO [main] (UserMapperTest.java:152) - insertSysUserTest
2018-04-15 18:32:49,970 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Preparing: insert into sys_user( id,user_name, user_password, user_email, user_info, head_img, create_time) values( ?,?, ?, ?, ?, ?, ?)
2018-04-15 18:32:50,060 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Parameters: null, artisanTest(String), 123456(String), test@artisan.com(String), 测试用户(String), java.io.ByteArrayInputStream@50a14c18(ByteArrayInputStream), 2018-04-15 18:32:49.403(Timestamp)
2018-04-15 18:32:50,066 DEBUG [main] (BaseJdbcLogger.java:142) - <== Updates: 1
2018-04-15 18:32:50,067 INFO [main] (UserMapperTest.java:174) - 受影响的行数:1
2018-04-15 18:32:50,078 INFO [main] (UserMapperTest.java:182) - 为了保持测试数据的干净,这里选择回滚,不写入mysql,请观察日志,回滚完成
2018-04-15 18:32:50,080 INFO [main] (UserMapperTest.java:185) - sqlSession close successfully
在使用主键自增(比如MySql 、SQLServer数据库)时,插入数据库后可以需要得到自增的主键值,然后使用这个值进行一些其他的操作。
// 演示使用JDBC方式返回主键的自增长值
int insertSysUser2(SysUser sysUser);
<!-- 添加SysUser 使用JDBC的方式返回自增长的主键的值-->
<insert id="insertSysUser2" useGeneratedKeys="true" keyProperty="id">
insert into sys_user(
user_name, user_password, user_email,
user_info, head_img, create_time)
values(
#{userName}, #{userPassword}, #{userEmail},
#{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP})
</insert>
和insertSysUser比较, insertSysUser2主要的变化是在insert 标签上配置了两个属性
useGeneratedKeys="true" keyProperty="id"
useGeneratedKeys设置为true后, MyBatis会使用JDBC的getGeneratedKeys方法来取由数据库内部生成的主键。 获取主键值后将其赋值给keyProperty配置的id属性。
当需要设置多个属性时,使用逗号分开,这种情况下通常还需要设置keyColunm属性,按顺序指定数据库的列,这里的列的值会和keyProperty配置的属性一一对应。
由于使用数据库返回的主键值,所以SQL上线两部分中的列去掉了id列和对应的#{id}属性。
@Test
public void insertSysUser2Test() {
logger.info("insertSysUser2Test");
// 获取SqlSession
SqlSession sqlSession = getSqlSession();
try {
// 获取UserMapper接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
SysUser sysUser = new SysUser();
sysUser.setUserName("artisanTest");
sysUser.setUserPassword("123456");
sysUser.setUserEmail("[email protected]");
sysUser.setUserInfo("测试用户");
// 模拟头像
sysUser.setHeadImg(new byte[] { 1, 2, 3 });
sysUser.setCreateTime(new Date());
// 新增用户 ,返回受影响的行数
int result = userMapper.insertSysUser2(sysUser);
// 只插入一条数据 ,期望是1
Assert.assertEquals(1, result);
// id不为null ,因为使用了 useGeneratedKeys="true" keyProperty="id"
Assert.assertNotNull(sysUser.getId());
logger.info("受影响的行数:" + result);
logger.info("userId:" + sysUser.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 为了保持测试数据的干净,这里选择回滚
// 由于默认的sqlSessionFactory.openSession()是不自动提交的
// 除非显式的commit,否则不会提交到数据库
sqlSession.rollback();
logger.info("为了保持测试数据的干净,这里选择回滚,不写入mysql,请观察日志,回滚完成");
sqlSession.close();
logger.info("sqlSession close successfully ");
}
}
日志
2018-04-16 00:36:27,508 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully
2018-04-16 00:36:27,511 INFO [main] (BaseMapperTest.java:29) - reader close successfully
2018-04-16 00:36:27,514 INFO [main] (UserMapperTest.java:191) - insertSysUser2Test
2018-04-16 00:36:28,049 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Preparing: insert into sys_user( user_name, user_password, user_email, user_info, head_img, create_time) values( ?, ?, ?, ?, ?, ?)
2018-04-16 00:36:28,112 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Parameters: artisanTest(String), 123456(String), test@artisan.com(String), 测试用户(String), java.io.ByteArrayInputStream@4021065(ByteArrayInputStream), 2018-04-16 00:36:27.526(Timestamp)
2018-04-16 00:36:28,124 DEBUG [main] (BaseJdbcLogger.java:142) - <== Updates: 1
2018-04-16 00:36:28,125 INFO [main] (UserMapperTest.java:213) - 受影响的行数:1
2018-04-16 00:36:28,125 INFO [main] (UserMapperTest.java:214) - userId:1002
2018-04-16 00:36:28,127 INFO [main] (UserMapperTest.java:222) - 为了保持测试数据的干净,这里选择回滚,不写入mysql,请观察日志,回滚完成
2018-04-16 00:36:28,129 INFO [main] (UserMapperTest.java:225) - sqlSession close successfully
上面这种写法只适用于支持组件自增的数据库,有些数据库比如Oracle不提供主键自增的功能,而是使用序列得到一个值,然后将这个值赋给id ,然后再插入数据库。
对应这种情况,可以使用 selectKey标签来获取主键的值,这种方式不仅使用不提供主键自增功能的数据库,同时也适用于提供主键自增功能的数据库
// 演示使用selectKey的方式返回主键的自增长值
int insertSysUser3(SysUser sysUser);
<!-- 添加SysUser 使用selectKey的方式返回自增长的主键的值-->
<insert id="insertSysUser3">
insert into sys_user(
user_name, user_password, user_email,
user_info, head_img, create_time)
values(
#{userName}, #{userPassword}, #{userEmail},
#{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP})
<selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
select last_insert_id()
</selectKey>
</insert>
selectKey标签的keyColum、keyProperty
和上面useGeneratedKeys的用法含义相同。
resultType用于设置返回值的类型。
order属性的设置和数据库有关。
Mysql中,order属性设置为AFTER。因为当前记录的主键值是在insert语句执行成功后才获取到的。
Oracle数据库中,order的值设置为BEFORE,这是因为ORCLE数据库需要先从序列中获取中,然后将值作为主键插入数据库中
ORACLE的写法如下
<insert id="insertUser" >
<selectKey resultType="java.lang.Integer" order="BEFORE"
keyProperty="id">
SELECT 自定义序列.NEXTVAL FROM DUAL
</selectKey>
insert into *******
</insert>
注意这里使用的order是“BEFORE”
@Test
public void insertSysUser3Test() {
logger.info("insertSysUser3Test");
// 获取SqlSession
SqlSession sqlSession = getSqlSession();
try {
// 获取UserMapper接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
SysUser sysUser = new SysUser();
sysUser.setUserName("artisanTest");
sysUser.setUserPassword("123456");
sysUser.setUserEmail("[email protected]");
sysUser.setUserInfo("测试用户");
// 模拟头像
sysUser.setHeadImg(new byte[] { 1, 2, 3 });
sysUser.setCreateTime(new Date());
// 新增用户 ,返回受影响的行数
int result = userMapper.insertSysUser3(sysUser);
// 只插入一条数据 ,期望是1
Assert.assertEquals(1, result);
// id不为null ,因为使用了 useGeneratedKeys="true" keyProperty="id"
Assert.assertNotNull(sysUser.getId());
logger.info("受影响的行数:" + result);
logger.info("userId:" + sysUser.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 为了保持测试数据的干净,这里选择回滚
// 由于默认的sqlSessionFactory.openSession()是不自动提交的
// 除非显式的commit,否则不会提交到数据库
sqlSession.rollback();
logger.info("为了保持测试数据的干净,这里选择回滚,不写入mysql,请观察日志,回滚完成");
sqlSession.close();
logger.info("sqlSession close successfully ");
}
}
日志
2018-04-16 00:44:17,807 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully
2018-04-16 00:44:17,811 INFO [main] (BaseMapperTest.java:29) - reader close successfully
2018-04-16 00:44:17,814 INFO [main] (UserMapperTest.java:231) - insertSysUser3Test
2018-04-16 00:44:18,278 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Preparing: insert into sys_user( user_name, user_password, user_email, user_info, head_img, create_time) values( ?, ?, ?, ?, ?, ?)
2018-04-16 00:44:18,353 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Parameters: artisanTest(String), 123456(String), test@artisan.com(String), 测试用户(String), java.io.ByteArrayInputStream@18a52c57(ByteArrayInputStream), 2018-04-16 00:44:17.833(Timestamp)
2018-04-16 00:44:18,359 DEBUG [main] (BaseJdbcLogger.java:142) - <== Updates: 1
2018-04-16 00:44:18,361 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Preparing: select last_insert_id()
2018-04-16 00:44:18,362 DEBUG [main] (BaseJdbcLogger.java:142) - ==> Parameters:
2018-04-16 00:44:18,386 TRACE [main] (BaseJdbcLogger.java:148) - <== Columns: last_insert_id()
2018-04-16 00:44:18,386 TRACE [main] (BaseJdbcLogger.java:148) - <== Row: 1003
2018-04-16 00:44:18,389 DEBUG [main] (BaseJdbcLogger.java:142) - <== Total: 1
2018-04-16 00:44:18,391 INFO [main] (UserMapperTest.java:253) - 受影响的行数:1
2018-04-16 00:44:18,391 INFO [main] (UserMapperTest.java:254) - userId:1003
2018-04-16 00:44:18,396 INFO [main] (UserMapperTest.java:262) - 为了保持测试数据的干净,这里选择回滚,不写入mysql,请观察日志,回滚完成
2018-04-16 00:44:18,398 INFO [main] (UserMapperTest.java:265) - sqlSession close successfully
需要增加通过select uuid()得到uuid值
<insert id="insertUser">
<selectKey resultType="java.lang.String" order="BEFORE"
keyProperty="id">
select uuid()
</selectKey>
insert into sys_user(
user_name, user_password, user_email,
user_info, head_img, create_time)
values(
#{
userName}, #{
userPassword}, #{
userEmail},
#{
userInfo}, #{
headImg, jdbcType=BLOB}, #{
createTime, jdbcType=TIMESTAMP})
</insert>
注意这里使用的order是“BEFORE” , 比较简单就不再测试了。
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法