一、数据库mysql 批量插入 时遇到的问题:
数据表的字段 一定不要是关键字(key,value等),否则你执行sql的时候一直报错,告诉你糟糕的sql语法,错误靠近###等
但是出于常理,我们肯定不会去想 是数据表的字段名出了问题,而是想sql语法,或者是值传的有问题。
但最后我还是发现了关键字的问题,因为我用排除法排除所有结果,剩下的那个就是真相。
因为首先我们确保sql的语法是正确的,那么错误就在数据上,首先将数据表字段的数据分为几类,比如字符串,int,和时间 ,然后逐个排除。
1、先将sql中只留字符串类型,然后执行,看是否报错,有错说明在这几个字符串中某些出了问题,在细分找;没问题的话就下一步
2、sql的插入条件只留int类型,然后执行,。。。。
3、sql 中只留时间data类型,
最后你就会发现,关键字的列会报错,然后把名字改成普通的,就运行通过了!
2、这是修改后我批量查询的sql:
<!-- 批量保存数据 -->
<insert id="saveEnvConfig" parameterType="arrayList">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT @@IDENTITY AS id
</selectKey>
insert into envconfig(version,createTime,editTime,createUser,editUser,resourceID,envResourceID,envKey,envValue)values
<foreach collection="list" item="item" index="index" separator=",">
(0,#{item.createTime},#{item.editTime},#{item.createUser},#{item.editUser},#{item.resourceID},#{item.envResourceID},#{item.envKey},#{item.envValue})
</foreach>
</insert>
3、批量查询出错了,不要惊慌,先试试插入单条数据,如果单条插入数据也出错,那么原因很有可能就是数据的问题。
之后就是排除法一一知道找错错误的那一列。
4、报错的sql:
insert into envconfig(version,createTime,editTime,createUser,editUser,resourceID,envResourceID,key,value) values
(0,#{createTime},#{editTime},#{createUser},#{editUser},#{resourceID},#{envResourceID},#{key},#{value})
5、报错内容:
最后附上,调错一定要细心,粗心大意会浪费你很多时间,写到这里,着重感谢刘**对我热心的帮助。希望以后编程路上能永远充满激情,克服粗心,着急,手忙脚乱的坏习惯。
特别注意的情况:(批量更新不起作用)
二、mybatis实现批量更新,一直报错,说我的sql语句不对,然后我仔细检查了语句没问题,还是执行不了,运行报错。
原来,在连接数据库的url中要加入 ?allowMultiQueries=true 这段,而且要放在第一行。
url: jdbc:mysql://localhost:3306/crm?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
三、mybatis 拼接sql:
1、概念:
mybatis 标签的一些关键字:
eg: <select id="selectPersionByID" parameterType="java.lang.String"
resultMap="PersonResultMap">
select * from person where id=#{id}
</select>
1.id:sql 的唯一标识,
2.parameterType:传递给sql参数的数据类型,
3.resultMap:返回数据结果的类型,
4.#{id} :用于接收参数的语法,{}中的内容,如果是接收一个参数内容任意,可以使用
select * from person where id=? 但#{} 使用预编译的方式生成sql,防止sql的注入。
5.结果集 :resultMap 是可以直接写javabena类名的,只要bean属性和数据库字段名一一对应,
但实际上是因为属性名使用驼峰命名法,mysql是不区分大小写的,(只有在数据库字段名
都是单个字母的时候才成立,但是实际开发是要求字段见名知意的,所以一个单词情况很少)因此多数情况
就需要构建结果集,
在mapper.xml的上面定义结果集,让javabena 和数据库字段一一对应,这样数据库就认识java字段了。
例如:
<resultMap id="PersonResultMap" type="com.feilong.person.model.Person" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="createTime" property="createTime" jdbcType="TIMESTAMP" />
<result column="createUser" property="createUser" jdbcType="VARCHAR" />
<result column="editTime" property="editTime" jdbcType="TIMESTAMP" />
<result column="editUser" property="editUser" jdbcType="VARCHAR" />
<result column="resourceID" property="resourceID" jdbcType="VARCHAR" />
<result column="version" property="version" jdbcType="INTEGER" />
</resultMap>
6.批量 增加 ,删除 ,修改
批量主要是foreach 标签 就是循环遍历的意思:
foreach一共有List,array,Map三种类型的使用场景。foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
item表示集合中每一个元素进行迭代时的别名,
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔 符,
close表示以什么结束。
1.List类型插入:
<insert id="addPersons" parameterType="java.util.List" >
INSERT INTO person (order_no,mac_id,client_code,status,order_time)
<foreach collection="list" item="item" index="index" separator="union all">
select #{item.orderNo, jdbcType=VARCHAR},#{item.macId, jdbcType=VARCHAR}
from dual
</foreach>
</insert>
2.1List类型查询:
<select id="getPersonsList" parameterType="java.util.List" resultType="personResultMap">
select * from person where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
3.参数array类型查询:
<select id="getPersonsById" parameterType="java.util.ArrayList" resultType="personResultMap">
select * from person where id in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
4.参数Map类型查询:
map中存放了一个元素key为ids,value为List<String>用于id in的条件
<select id="getPersonsList" parameterType="java.util.HashMap" resultType="personResultMap">
select * from person where mac like "%"#{mac}"%" and id in
<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
5、 resultType: 的接收
1、基本类型 :resultType=基本类型
2、List类型: resultType=List中元素的类型
3、Map类型 单条记录:resultType =map
多条记录:resultType =Map中value的类型
6、dao.java 与 mapper.xml 的参数接收问题;
通常我查询的方法接收返回数据喜欢用对象接,方便get 和set, 比如多表联合查询结果,我会在model层单独为这个查询语句建立javabean,设置属性和查询结果字段 一一对应,之后用dao层用 List<对象名> 作为方法的返回参数,而 mapper 文件里返回结果集就用我加的对象的全路径类名。但是这样查询多的情况下需要建立很多的bean,对代码维护不友好,于是可以用一下方法,用通用的list,map接参数。
注意:使用对象的时候是resultType (返回不需要映射的查询结果使用),使用结果集的是resultMap
例如:mybatis 的写法: (返回值是map ,方法接的是list<map<,>>)
对应 mapper 。java 里:
public List<Map<String, String>> findIpByVersionManagementAndEnvironment(String versionManagementRid,String enResourceID){
return versionManagementEnMapper.findIpByVersionManagementAndEnvironment(versionManagementRid,enResourceID);
}
对应 mapper。xml 里 :
<select id="findIpByVersionManagementAndEnvironment" resultType = "java.util.Map">
SELECT DISTINCT
i.resourceID,
i.innerIP
FROM
EnIp i
INNER JOIN EnPort p ON i.resourceID = p.enIpResourceID
AND p.resourceID NOT IN ( SELECT DISTINCT t.enPortResourceID FROM ProjectTypeEn t INNER JOIN ProjectType y ON t.projectTypeResourceID = y.resourceID AND y.versionManagementRid = #{versionManagementRid}
AND t.enPortResourceID IS NOT NULL AND t.enPortResourceID != "" )
WHERE
i.enEnvironmentResourceID = #{enResourceID}
</select>