美文网首页大数据-技能
mysql&mybatis,在开发中遇到的坑

mysql&mybatis,在开发中遇到的坑

作者: 别停下思考 | 来源:发表于2019-07-06 14:52 被阅读0次

    Mybatis
    动态拼接
    数据更新,replace/insert
    mybatis批量插入
    插入的内容含英文单引号
    Mysql
    常见错误
    分区表

    mysql作为开源的数据库软件,好用免费,是关系型数据库的首选。我在使用的过程中,遇到的一些问题,进行汇总,不定期更新。作为记录,下次也有一个查询的地方。

    Mybatis

    动态拼接,实现有条件的数据更新或者插入
    <?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.datacenter.manage.rmdbrecord.dao.OperaDataLoadMapper">
    
        <select id="list" parameterType="***Dto" resultType="***Dto">
            select
                  id
                  ***
                 ,jdbc_name AS  jdbcName
            from operational_data_source_mysql
            where 1=1 and table_schema not in ('mysql','performance_schema','sys')
            <trim>
                <if test="jdbcName != null">
                    and jdbc_name like '%${jdbcName}%'
                </if>
                <if test="tableSchema != null">
                    and table_schema like '%${tableSchema}%'
                </if>
            </trim>
        </select>
    
    

    ​ 通过if判断,来检查test条件是否满足。如果满足则执行,不满足则跳过。而trim另外的三个参数。prefix为拼接sql的前缀,suffix这个是动态sql的后缀,suffixOverrides去掉最后多出来的符号。如:insert数据时,在对象没有数据时实现不插入的动态拼接。

    数据更新(insert into...on duplicate key update 与replace into)

    insert into ... on duplicate key update在primary key或者unique key冲突的时候才会执行update之后的语句(一个有意义的index是否重要)。如:

    <insert id="insert" param.....>
    insert into tb1 (id,name,age) select id,name,age from tb2 
    on duplicate key update name=#{name},age={age}
    </insert>
    

    replace into在唯一性冲突时(同上,primary key/unique key),将覆盖原有的数据(先删除,再插入)。这样的代价就是: 历史数据无保存、无痕迹,新数据插入(部分字段无内容,则以默认值取代。以及create_time/modify_time都是最新的。)

    <insert id="insert" param...>
        replace into tb1 (id,name,age)
        select id,name,age 
        from tb2
    </insert>
    
    mybatis批量插入

    对于List类型来说,我们需要批量的进行数据插入。在mysql中也类似于动态拼接sql的过程。mybatis提供了for-each方法,如:

    <insert id="insertMap" parameterType="java.util.List">
            <foreach collection="list" item="item" index="index" separator=";">
                insert into param_map ( file_path,type, `key`, content_line, parse_result)
                values
                (
                substring(#{item.filePath},1,1000)
                ,substring((#{item.key},1,1000)
                ,substring(#{item.contentLine},1,1000)
                ,substring(#{item.parseResult},1,1000)
                ) on duplicate key update content_line=substring(#{item.contentLine},1,1000) ,parse_result=substring(replace(replace(#{item.parseResult},1,1000) ,mtime=now()
            </foreach>
        </insert>
    
    mybatis中插入的内容中带有英文单引号

    mybatis对于参数的传递有两种模式。一种是#{},一种{}。#{}会自动添加'',而{}则为直接传递数据。

    我在遇到这个问题的时候,我是将原始的数据中''给替换掉。

    mysql上的操作

    脚本执行报错
    • Exception: Data too long for column

      字段长度问题,可以通过将长度设置的更长,如varchar(1000),如果字段内容更长,则可以考虑设置为: mediumtext

    • Exception: Row ** was cut by GROUP_CONCAT()

      处理行转列的数据处理时需呀用到group_concat函数,如果需要合并的行太多,就会报这样的错误。可以设置相关参数

      //会话级
      SET SESSION group_concat_max_len = 102400;
      //全局
      SET GLOBAL group_concat_max_len=102400;
      
    分区表
    • 分区类型

      序号 分区类型 说明 使用频率
      1 RANGE分区 给定一个连续区间的列值(非离散),将多行数据分配给对应分区 较多
      2 HASH分区 对给定的列/值算出对应的hash值,作为对应行的分区 较多
      3 LIST分区 对行记录,匹配List(离散列表)值,放入指定分区 一般
      4 KEY分区 类似于分桶,指定分桶数和分桶字段。有mysql内部分区 一般
    • 创建

    create table test.user_test(
      id int comment '自增id',
      phone varchar(255) comment '送检的手机号',
      p_dt DATE comment '分区字段(yyyy-mm-dd)',
      PRIMARY key(id,p_dt)
    ) ENGINE=InnoDB  COMMENT='用户风险等级 - 依赖于腾讯天御接口'
    PARTITION by range(TO_DAYS(p_dt))
    (
    PARTITION p1 VALUES LESS THAN (to_days('2019-08-12')) ENGINE = InnoDB,
    PARTITION p2 VALUES LESS THAN (to_days('2019-08-13')) ENGINE = InnoDB,
    PARTITION p3 VALUES LESS THAN (to_days('2019-08-14')) ENGINE = InnoDB,
    PARTITION p4 VALUES LESS THAN (to_days('2019-08-15')) ENGINE = InnoDB
    )
    ;
    
    • 查询分区
    select table_catalog,table_schema,table_name,partition_name,partition_ordinal_position,partition_method,partition_expression,table_rows,create_time,nodegroup
    from information_schema.partitions  
    where table_schema = schema()  
    and table_name='user_test';
    
    • 操作分区
    -- 新增分区
    alter table xqlm_base.user_test add partition (partition p4 values less than (to_days('2019-08-16')))
    -- 修改分区
    alter table xqlm_base.user_test PARTITION by range(TO_DAYS(p_dt)) (partition p4 values less than (to_days('2019-08-16')))
    -- 重建分区
    ALTER TABLE xqlm_base.user_test rebuild partitionp1,p2; 
    -- 优化分区
    ALTER TABLE xqlm_base.user_test optimize partition p1,p2;
    
    • 分区问题
    -- 需求场景1:创建分区,类似实现create ... if exists 功能
    储存过程,调度,判断
    

    相关文章

      网友评论

        本文标题:mysql&mybatis,在开发中遇到的坑

        本文链接:https://www.haomeiwen.com/subject/ycvphctx.html