• mybatis大数据提交和更新,数据SQL语句批量提交数据库


    我们在做数据插入和数据更新的时候,业务产生的日志数据有好几万百万,那么正常的插入语句已性能弱,mybatis提供了实现大数据插入数据表的方法,下面我们就来实现一个例子。

    1.引入mybatis的依赖jar

    <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.1</version>
            </dependency>

    2.配置mybatis

    mybatis:
      typeAliasesPackage: com.xdd.entity
      mapperLocations: classpath:mapper/*.xml,classpath*:com/cloud/dataplatformbronto/dao/*Mapper.xml

    3.创建 BrontoDataDao

    import org.apache.ibatis.annotations.*;
    import java.util.List;
    @Mapper
    public interface BrontoDataDao {
    int insertBatchUserChannelInfo(List<BrontoChannelActiveBean> list);
    int batchUpdate(Map<?,?> map);
    }

    4.创建BrontoDataMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.sengled.cloud.dataplatformbronto.dao.BrontoDataDao" >
    <insert id="insertBatchUserChannelInfo" parameterType="java.util.List" useGeneratedKeys="false">
        INSERT INTO dp_bronto_channel_active
        (customer_id,channel_name,active_status,channel_type,area_info)
        values
        <foreach collection="list" item="item" index="index" separator=",">
            (
            #{item.customerId},
            #{item.channelName},
            #{item.activeStatus},
            #{item.channelType},
            #{item.areaInfo}
            )
        </foreach>
    </insert>
    
    <!-- 批量更新第一种方法,通过接收传进来的参数list进行循环着组装sql -->
    <update id="batchUpdate" parameterType="java.util.Map">
        <!-- 接收list参数,循环着组装sql语句,注意for循环的写法
             separator=";" 代表着每次循环完,在sql后面放一个分号
             item="cus" 循环List的每条的结果集
             collection="list" list 即为 map传过来的参数key -->
        <foreach collection="list" separator=";" item="cus">
            update t_customer set
            c_name = #{cus.name},
            c_age = #{cus.age},
            c_sex = #{cus.sex},
            c_ceroNo = #{cus.ceroNo},
            c_ceroType = #{cus.ceroType}
            where id = #{cus.id}
        </foreach>
        <!--<foreach collection="attendingUsrList" item="model"  separator=";">-->
            <!--UPDATE parties SET attending_user_count = #{model.attending_count}-->
            <!--WHERE  fb_party_id = #{model.eid}-->
        <!--</foreach>-->
    </update>
    
    </mapper>

    5.编写业务方法

    @Service("brontoDataService")
    @Transactional
    public class BrontoDataServiceImp implements IBrontoDataService{
    
        private static final int BATCH_SIZE = 5000;
    
        private Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Autowired
        private BrontoDataDao brontoDataDao;
        @Autowired
        SqlSessionFactory sqlSessionFactory;
    /**
         * 用户渠道信息大批量数据插入
         *@param: [brontoDeviceModelList]
         **/
        @Transactional
        public void saveUserChannelInfo(List<BrontoChannelActiveBean> brontoDeviceModelList) {
            int groupNo = brontoDeviceModelList.size() / BATCH_SIZE;
            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
            BrontoDataDao mapper = sqlSession.getMapper(BrontoDataDao.class);
            if (brontoDeviceModelList.size() <= BATCH_SIZE) {
                mapper.insertBatchUserChannelInfo(brontoDeviceModelList);
            } else {
                List<BrontoChannelActiveBean> subList = null;
                for (int i = 0; i < groupNo; i++) {
                    subList = brontoDeviceModelList.subList(0, BATCH_SIZE);
                    mapper.insertBatchUserChannelInfo(subList);
                    brontoDeviceModelList.subList(0, BATCH_SIZE).clear();
                }
                if (brontoDeviceModelList.size() > 0) {
                    mapper.insertBatchUserChannelInfo(brontoDeviceModelList);
                }
            }
            sqlSession.flushStatements();
        }
    }

    需要测试功能再写一个测试类或测试接口来测试!

    附录XML CDATA(Mybatis mapper and XML)

    Tip:must be followed by either attribute specifications, ">" or "/>".

    所有 XML 文档中的文本均会被解析器解析。

    只有 CDATA 区段(CDATA section)中的文本会被解析器忽略。

    PCDATA

    PCDATA 指的是被解析的字符数据(Parsed Character Data)。

    XML 解析器通常会解析 XML 文档中所有的文本。

    当某个 XML 元素被解析时,其标签之间的文本也会被解析:

    <message>此文本也会被解析</message>

    解析器之所以这么做是因为 XML 元素可包含其他元素,就像这个例子中,其中的 <name> 元素包含着另外的两个元素(first 和 last):

    <name><first>Bill</first><last>Gates</last></name>

    而解析器会把它分解为像这样的子元素:

    <name>
       <first>Bill</first>
       <last>Gates</last>
    </name>

    转义字符

    非法的 XML 字符必须被替换为实体引用(entity reference)。

    假如您在 XML 文档中放置了一个类似 "<" 字符,那么这个文档会产生一个错误,这是因为解析器会把它解释为新元素的开始。因此你不能这样写:

    <message>if salary < 1000 then</message>

    为了避免此类错误,需要把字符 "<" 替换为实体引用,就像这样:

    <message>if salary &lt; 1000 then</message>

    在 XML 中有 5 个预定义的实体引用:

    &lt; < 小于
    &gt; > 大于
    &amp; & 和号
    &apos; ' 省略号
    &quot; " 引号

    注释:严格地讲,在 XML 中仅有字符 "<"和"&" 是非法的。省略号、引号和大于号是合法的,但是把它们替换为实体引用是个好的习惯。

    CDATA

    术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data)。

    在 XML 元素中,"<" 和 "&" 是非法的。

    "<" 会产生错误,因为解析器会把该字符解释为新元素的开始。

    "&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。

    某些文本,比如 JavaScript 代码,包含大量 "<" 或 "&" 字符。为了避免错误,可以将脚本代码定义为 CDATA。

    CDATA 部分中的所有内容都会被解析器忽略。

    CDATA 部分由 "<![CDATA[" 开始,由 "]]>" 结束:

    <script>
    <![CDATA[
    function matchwo(a,b)
    {
    if (a < b && a < 0) then
      {
      return 1;
      }
    else
      {
      return 0;
      }
    }
    ]]>
    </script>
    

    在上面的例子中,解析器会忽略 CDATA 部分中的所有内容。

    关于 CDATA 部分的注释:

    CDATA 部分不能包含字符串 "]]>"。也不允许嵌套的 CDATA 部分。

    标记 CDATA 部分结尾的 "]]>" 不能包含空格或折行。

     附录部分摘自:http://www.w3school.com.cn/xml/xml_cdata.asp

  • 相关阅读:
    图灵测试
    百度面试题
    【javascript每日一练】- 插入排序
    各种排序讲解
    【javascript每日一练】- 多维数组
    不用JQuery,原生Javascript实现Ajax功能及相关知识点
    【javascript每日一练】- 无序数组排序
    前端面试题
    前端重构面试题
    面试题
  • 原文地址:https://www.cnblogs.com/zengsong-restService/p/3398965.html
Copyright © 2020-2023  润新知