Mybatis批量Insert及水平分表

工作中需要读取很多大数据量(1000w条)的文件并写入到mysql表里,涉及到的技术点主要是数据库的addbatch及水平分表。

数据库的写入场景包括:一条一条的写入和批量写入,这里数据库的批量增加使用mybatis框架完成。

水平分表的意思是本来我们要将1000w的数据写入到一张表里,但为了考虑未来表容量的扩展,及表的性能要求,将本来写入一张表转换成写入多张表。

我在这里没有使用一些框架(Cobar ClientShardbatismybatis-shards),而是采用Hash分表来实现的。

首先是Mybatis批量insert

说一下核心部分,整个工程参考我的github,运行的main方法在org/xiongmaotailang/mybatis/batchinsert/DbUtil.java中,涉及到的脚本是sql.txt

需要的数据表示例,包括4个字段。

CREATE TABLE `newspvuv` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `pv` bigint(11) DEFAULT NULL,
  `uv` bigint(11) DEFAULT NULL,
  `time` varchar(15) NOT NULL,
  PRIMARY KEY (`id`)
)

接下来看看批处理的mapper.xml文件(工程中org\xiongmaotailang\mybatis\batchinsert\mappers\DataMapper.xml),批量插入方法的定义

<mapper namespace="org.xiongmaotailang.mybatis.batchinsert.mappers.DataMapper">    
    <insert id="insertPVUV">
        insert into  ${table}(pv,uv,time) values(#{pv},#{uv},#{time})
    </insert>
    <insert id="batchInsertPVUV" parameterType="java.util.List">  
        insert into  ${table}(pv,uv,time) values  
        <foreach collection="list" item="item" index="index"  
            separator=",">  
            (#{item.pv,jdbcType=INTEGER},#{item.uv,jdbcType=INTEGER},#{item.time,jdbcType=CHAR}  
            )  
        </foreach>  
    </insert>  
</mapper>

id="insertPVUV"是一条一条的写入的配置、id="batchInsertPVUV"是批量写入的配置。

对上边二个配置的main方法在DbUtil中。

    public static void main(String[] args) throws InterruptedException {
        testInsert();
        testBatchInsert();
    }
    private static void testInsert() {
        long start=System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            addPvUv(12,i,"123");
        }
        System.out.println("insert 1000 row :"+(System.currentTimeMillis()-start)+"ms");
    }
    private static void testBatchInsert() {
        long start=System.currentTimeMillis();
        List<NewsPvUv> list=new ArrayList<NewsPvUv>();
        for (int i = 0; i < 1000; i++) {
            NewsPvUv n = new NewsPvUv(12, i, "123");
            list.add(n);
        }
        addPvUv(list);
        System.out.println("batch insert 1000 row :"+(System.currentTimeMillis()-start)+"ms");
    }

上边对比了对1000条数据的二种写入方式,在我笔记本的测试结果如下图,可见批量写入的性能高效。

image

 

水平分表

整个工程参考我的github

方法一:使用MD5哈希

// 使用md5做hash水平分表
    public static String getTable(String mark, String prefix, int num) {
        if (num == 0)
            return prefix;
        String temp = md5(mark).substring(0, 2);
        int hexdec = Integer.parseInt(temp, 16);// 16转成10进制
        int index = hexdec % num + 1;
        return prefix + "_" + index;
    }

    // 提供和php->md5一样的功能
    private static String md5(String txt) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(txt.getBytes("GBK")); // 问题主要出在这里,Java的字符串是unicode编码,不受源码文件的编码影响;而PHP的编码是和源码文件的编码一致,受源码编码影响。
            StringBuffer buf = new StringBuffer();
            for (byte b : md.digest()) {
                buf.append(String.format("%02x", b & 0xff));
            }
            return buf.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

方法二:使用移位

// 使用移位分表
    /*
     * 如果我们预估我们系统的用户是100亿,单张表的最优数据量是100万,
     * 那么我们就需要将UID移动20来确保每个表是100万的数据,保留用户表(user_xxxx)四位来扩展1万张表
     */
    public static String getTable1(int uid, String prefix) {
        
        return prefix + "_" + String.format("%04d",(uid>>20));
    }

转载于:https://www.cnblogs.com/xiongmaotailang/p/5294795.html

MyBatis提供了多种方法来实现批量插入操作。根据引用中的描述,可以使用MyBatis的拼接原生SQL一次性插入的方法或者使用MyBatis Plus框架的批量插入功能。其中,使用MyBatis Plus框架的批量插入功能相对更为推荐。引用中提到,很多人对于MyBatis Plus的批量插入功能存在误解,认为它也是使用循环单次插入数据的,所以性能没有提升。但事实上,MyBatis Plus的批量插入功能可以有效地提高性能。 在使用MyBatis Plus进行批量插入时,需要确保你的项目中已经引入了正确版本的MyBatis Plus框架。你可以通过访问https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter查询最新版本号,并将其替换到你的项目中。然后,你可以使用MyBatis Plus提供的批量插入方法来实现批量插入操作。 总结起来,如果你需要实现mybatis批量插入操作,可以考虑使用MyBatis Plus框架并使用其提供的批量插入功能。记得将正确的MyBatis Plus版本号引入你的项目中,然后按照MyBatis Plus的官方文档来使用批量插入方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MyBatis 批量插入数据的 3 种方法](https://blog.csdn.net/uuuyy_/article/details/121756068)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值