mybatis insert新增语句

1.生成主键id并返回
	<insert id="saveProduct" parameterType="java.util.HashMap" useGeneratedKeys="true" keyProperty="goods_id" >
		INSERT INTO t_product(store_id,name,
				goods_code,is_poss,is_prod_presell,platform_classify,
				platform_prop,store_classify,store_prop,product_HTML,is_quick_end,
				customer_service_HTML,status,
				create_time,creater,product_sales,is_up,keywords,product_info)
		VALUES
			(#{store_id},#{name},#{goods_code},#{is_poss},
			#{is_prod_presell},#{platform_classify},
			#{platform_prop},#{store_classify},#{store_prop},
			#{product_html},#{is_quick_end},#{customer_service_HTML},1,now(),
			#{user_id},#{product_sales},0,#{key_words},#{product_info});
	</insert>


useGeneratedKeys="true" keyProperty="goods_id" 语句来实现,在传入的map中即可取到
mybatis api:



  平时会经常遇到多个表的插入操作,多个表之间的关系,另一个表中的一个字段要以第一个表的主键作为外键。

下面说两种方法,MyBatis+MySQL 返回插入记录的主键ID:

第一种:

<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId" parameterType="com.chenzhou.mybatis.User">
	insert into user(userName,password,comment)
	values(#{userName},#{password},#{comment})
</insert>
第二种:
<insert id="insert" parameterType="cn.***.beans.LogObject" >
	<selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="id">
		SELECT LOGS_SEQ.nextval AS ID FROM DUAL
	</selectKey>
	INSERT INTO S_T_LOGS (
		ID, 
		USER_ID, 
		USER_NAME, 
		USER_IP, 
		OPERATION_TIME,
 		DESCRIPTION, 
		RESOURCE_ID) 
	VALUES (
		#{id}, 
		#{userId}, 
		#{userName}, 
		#{userIp}, 
		#{operationTime},
 		#{description}, 
		#{resourceId})
</insert>
这两种写法都可以,但有两点一定要注意:

一: keyProperty="id" 这个id必须是实体的id,而不是数据表的主键id,否则,得不到正确的返回结果;

二:接收返回值时候,必须用实体的get属性,而不能定义变量,否则,接收不到正确的返回结果:即必须用user.getId()来接收。



 
useGeneratedKeys 要求数据库本身具备主键自动增长的功能,比如说,mysql,sqlserver可以使用useGeneratedKeys =true 这功能,不支持主键自动增长的数据库是不能使用useGeneratedKeys =true的
这个样做是不对的, 用selectKey子节点来做,oracle不支持useGeneratedKeys

 
 
 
 
 
 




### MyBatisInsert 语句被截断的原因及解决方案 #### 原因分析 在 MySQL 数据库中,当执行批量插入操作时,如果 SQL 语句过长,则可能触发 `max_allowed_packet` 的限制。该参数定义了服务器能够接收的最大数据包大小。一旦超出此限制,SQL 语句会被截断,从而引发错误[^1]。 此外,在 MyBatis 使用过程中,如果未正确配置事务管理机制,可能导致部分操作失败并回滚整个事务,进一步掩盖实际的 SQL 截断问题[^2]。 最后,某些情况下,MyBatis 动态 SQL 或者注解方式可能存在参数绑定异常,例如使用 `@Insert` 注解处理复杂场景下的 List 集合插入时,可能出现类似 `BindingException` 错误,这可能是由于参数名称映射不匹配引起的[^3]。 --- #### 解决方案 ##### 方法一:调整 MySQL 配置中的 max_allowed_packet 参数 可以通过修改 MySQL 配置文件来增大允许的数据包大小。具体方法如下: - **Windows 平台**: 编辑 `my.ini` 文件。 - **Linux/MacOS 平台**: 编辑 `my.cnf` 文件。 找到或新增以下配置项: ```ini [mysqld] max_allowed_packet=1073741824 # 设置为 1GB ``` 保存后重启 MySQL 服务即可生效。通过这种方式可以有效避免因为数据量过大而导致的 SQL 截断问题[^4]。 ##### 方法二:分批提交数据 对于超大数据集的操作,建议采用分批次的方式进行插入。这样不仅可以减少单次请求的压力,还能提高系统的稳定性和性能。以下是实现代码示例: ```java public void batchInsert(List<Student> studentList) { int batchSize = 100; // 每批次的数量 for (int i = 0; i < studentList.size(); i += batchSize) { int toIndex = Math.min(i + batchSize, studentList.size()); List<Student> subList = studentList.subList(i, toIndex); mapper.insertBatch(subList); // 调用 Mapper 层的方法完成插入 } } ``` 上述代码片段展示了如何将大列表分割成多个子列表,并逐一调用数据库接口完成插入动作。 ##### 方法三:优化动态 SQL 和参数绑定逻辑 针对 MyBatis 动态 SQL 场景,需仔细检查 `<foreach>` 标签以及对应的参数传递过程是否存在潜在隐患。例如,确保传入的集合对象与 XML 映射文件中的变量名一致;或者在 Java 注解开发模式下验证参数声明是否准确无误。 假设当前存在一个基于注解的批量插入需求,可参考下面的例子修正参数绑定问题: ```java @Insert("<script>" + "INSERT INTO student(name, age)" + "<trim prefix='VALUES' suffixOverrides=','>" + "<foreach collection='list' item='item' separator=','>" + "(#{item.name}, #{item.age})" + "</foreach>" + "</trim>" + "</script>") void insertStudentList(@Param("list") List<Student> students); ``` 此处特别注意的是,`collection` 属性应指定为 `"list"`,而 `item` 则对应每条记录的具体字段访问路径。这种写法有助于规避之前提到过的 `BindingException` 异常情况。 --- ### 总结 综上所述,解决 MyBatis 插入语句被截断的核心在于三个方面:一是适当扩展 MySQL 客户端和服务端之间的通信容量上限;二是合理规划业务流程设计,引入分页策略降低每次交互规模;三是严格把控框架内部语法结构及其依赖关系,杜绝低级失误的发生。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值