sql语句批量
首先在数据库中写出批量插入的sql语句,然后查找重复的数据,再思考拼接过程。
在数据库中批量插入:
第一种通过别名实现表的同一,从而合并成一张表 插入数据
<!--第一种用select dual(空表) 再用集合 union all 合并-->
<!--dept表结构: deptno部门编号 dname部门名称 loc地址-->
insert into dept
select 60 deptno,'科创部' dname,'南昌' loc form dual
UNION
select 70 deptno,'文艺部' dname,'宜春' loc form dual
UNION
select 80 deptno,'新闻部' dname,'上饶' loc form dual
.....
<!--第二种方法 常规方法 mysql语法 Oracle不适用-->
INSERT INTO TABLE(col1, col2)
VALUES
(val11, val12),
(val21, val22),
(val31, val32);
<!--第三种 begin end-->
begin
insert into dept values (11,'aa','cc');
insert into dept values (12,'aa','cc');
insert into dept values (13,'aa','cc');
end;
在xml中拼接SQL语句:
<!--需要传入一个参数List<Dept> 对象。非空。-->
<!--接口方法:int insertSome(List<Dept> depts)-->
<insert id="insertSome" parameterType="list" >
insert into dept
<foreach collection="list" item="dept" separator="UNION">
select #{dept.deptno} deptno,#{dept.dname} dname,#{dept.loc} loc from dual
</foreach>
</insert>
<!--和上面要求一样 mysql语法 Oracle不适用-->
<insert id="insertSome" parameterType="list" >
insert into dept values
<foreach collection="list" item="dept" separator=",">
(#{dept.deptno},#{dept.dname},#{dept.loc})
</foreach>
</insert>
<!--和上面要求一样-->
<insert id="insertSome" parameterType="list" >
begin
<foreach collection="list" item="dept" separator=";">
insert into dept values(#{dept.deptno},#{dept.dname},#{dept.loc})
</foreach>
;end;
</insert>
在数据库中批量更新:
<!--使用begin end-->
begin
update 表名 set 字段1=值1,字段2=值2,字段3=值3.... where 字段n=值n;
update 表名 set 字段1=值1,字段2=值2,字段3=值3.... where 字段n=值n;
update 表名 set 字段1=值1,字段2=值2,字段3=值3.... where 字段n=值n;
end;
在xml中拼接SQL语句:
<update id="updateSome" parameterType="list">
begin
<foreach collection="list" item="dept" separator=";">
update emp set deptno=#{dept.deptno},dname=#{dept.dname} where empno=#{i.empno}
</foreach>
;end;
</update>
一级缓存 二级缓存
一级缓存
默认开启. 线程级别的缓存, SqlSession 的缓存;
在一个 SqlSession 生命周期中有效 SqlSession 关闭, 缓存清空;
在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map中获取数据;
不同的 SqlSession 之间的缓存是相互隔离的;
用一个 SqlSession, 可以通过配置使得在查询前清空缓存;flushCache=“true”
任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。
理解:同SqlSession 下,在只执行select语句时,会保存select存储的数据,通过方法签名,当该方法再次执行时,会自动使用已存储的数据。增删改查会默认清空缓存数据。
二级缓存
开启需要手动开启,调用标签。 在mapper.xml 文件中
<!-- 开启二级缓存, 要求实体类进行序列化 -->
<!--开启本mapper的namespace下的二级缓存-->
<!--
eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。
(1) LRU,最近最少使用的,一处最长时间不用的对象
(2) FIFO,先进先出,按对象进入缓存的顺序来移除他们
(3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
(4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU,
移除最长时间不用的对形象
flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那么当
SQL被执行的时候才会去刷新缓存。
size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。
这里配置的是1024个对象
readOnly:只读,意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,缺点是我们没有
办法修改缓存,他的默认值是false,不允许我们修改
-->
<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
进程级别的缓存, SqlSessionFactory 的缓存
在一个SqlSessionFactory生命周期中有效. 可以在多个SqlSession 生命中期中共享.
默认关闭, 需要使用的时候, 要为某个命名空间开启二级缓存(在 mapper.xml 中配置cache).
由于在更新时会刷新缓存, 因此需要注意使用场合:查询频率很高, 更新频率很低时使用, 即经常使用 select, 相对较少使用delete, insert, update。
缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。但刷新缓存是刷新整个 namespace的缓存, 也就是你 update 了一个, 则整个缓存都刷新了。
最好在 「只有单表操作」 的表的 namespace 使用缓存, 而且对该表的操作都在这个 namespace 中。 否则可能会出现数据不一致的情况。
理解:同一个命名空间namespace可以不同SqlSession,也是通过方法签名获取。但是多表查询的时候就很可能出现幻读。