### jdbc 向数据库插入特殊字符 失败。SQL报错的问题。【批量插入时手动解决特殊字符,根本不现实!!】

====

不禁感叹:框架就是框架!!!不需要再手动处理很多业务以外的 各种繁琐处理。

【这也是为什么 生产环境 基本只使用 框架的原因!】

===批量插入SQL如何写的【重点!】

版本1:

【old】

  <insert id="insertListSelective" parameterType="List">
    insert into category (category.name,category.type, pid,wid,status) VALUES
    <foreach collection="list" item="item" index="index" separator="," >

        /*批量插入【看看mybatis能不能处理插入特殊字符问题。】*/
      <!–<trim prefix="(" suffix=")" suffixOverrides=",">–>
      <trim prefix="(" suffix=")" >
        <if test="item.name != null">
          #{item.name,jdbcType=VARCHAR},
        </if>
        <if test="item.type != null">
          #{item.type,jdbcType=INTEGER},
        </if>
        <if test="item.pid != null">
          #{item.pid,jdbcType=BIGINT},
        </if>
        <if test="item.wid != null">
          #{item.wid,jdbcType=BIGINT},
        </if>
          /*if判断里面 也 必须加“item.”,否则报错:ibatis.binding.BindingException: Parameter 'status' not found. Available parameters are [collection, list]*/
        <if test="item.status != null">
          #{item.status,jdbcType=BIGINT}
        </if>
      </trim>


    </foreach>
  </insert>

各种报错:因为担心mybatis不能处理插入特殊字符,SQL报错。想着用trim标签,看能不能好一些。

结果【小看了mybatis,能够处理特殊字符插入,完全不需要 if标签。】

①用了trim标签反而报错:


总是提示:参数“Xxx”找不到。

错误信息:

 nested exception is org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [categoryDOList, param1]

②去掉if标签:最终版。【没有if,null数据也会插入,原样数据保留。mybatis 的sql并不是一定要用if标签的,要灵活应用】

 <!--new-->
  <insert id="insertListSelective" parameterType="List">
    insert into category (category.name,category.type, pid,wid,status) VALUES
    <foreach collection="list" item="item" index="index"  separator="," >

        /*批量插入【看看mybatis能不能处理插入特殊字符问题。】*/
      <!--<trim prefix="(" suffix=")" suffixOverrides=",">-->
      <trim prefix="(" suffix=")" >
          #{item.name,jdbcType=VARCHAR},
          #{item.type,jdbcType=INTEGER},
          #{item.pid,jdbcType=BIGINT},
          #{item.wid,jdbcType=BIGINT},
          #{item.status,jdbcType=BIGINT}
      </trim>


    </foreach>
  </insert>


====又遇到:

PacketTooBigException: Packet for query is too large (1,555,811 > 1,048,576)

解决:

在做查询数据库操作时,报了以上错误,原因是MySQL的max_allowed_packet设置过小引起的,我一开始设置的是1M,后来改为了20M

mysql根据配置文件会限制server接受的数据包大小。

有时候大的插入和更新会被max_allowed_packet 参数限制掉,导致失败。 
在mysql命令行中执行命令

1.查看当前配置

show VARIABLES like '%max_allowed_packet%';
1
2.修改配置

set global max_allowed_packet = 2*1024*1024*10;
1
把max_allowed_packet的值修改的大点、

修改完成后mysql不需要重新启动服务,但是项目可能要重新启动。

③基本难点都解决了。解决jdAPI拿到的数据量太大。

【照着上面设置了 mysql最大的SQL长度,还是容不下】

于是。在业务逻辑,处理,每1000个记录插入一次。

package com.ybl.jdAPI.kuaiChe.category.service.impl;

import com.jd.open.api.sdk.DefaultJdClient;
import com.jd.open.api.sdk.JdClient;
import com.jd.open.api.sdk.domain.jzt_kc.KuaicheUserTagJosService.DspResult;
import com.jd.open.api.sdk.domain.jzt_kc.KuaicheUserTagJosService.DspUserTagQuery;
import com.jd.open.api.sdk.request.jzt_kc.DspKcUsertagGetRequest;
import com.jd.open.api.sdk.response.jzt_kc.DspKcUsertagGetResponse;
import com.ybl.jdAPI.kuaiChe.category.bean.CategoryDO;
import com.ybl.jdAPI.kuaiChe.category.mapper.CategoryDOMapper;
import com.ybl.jdAPI.kuaiChe.category.service.CategoryService;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2018/4/24/024.
 */
@Service
public class CategoryServiceImpl implements CategoryService {


//    private  ObjectMapper MAPPER = new ObjectMapper();

    @Autowired
    ObjectMapper MAPPER;
    @Autowired
    CategoryDOMapper categoryDOMapper;//就这样的。不是错误。

  @Override
    public int insertListSelective() {

        //SDK 访问jd数据,保存数据库。=====》mybatis方式保存 【存特俗字符到数据库 ,会不会简单点?】

        String SERVER_URL = "https://api.jd.com/routerjson";//文档给出,入口地址。
        String accessToken = "fa6df891-88c0-4e71-8a80-573ff7276254" ;//只有这里会变。
        String appKey = "DCB16278B645135825F936D08D636F05";
        String appSecret = "f59d6d41cf4e4d549b157dba39c3d50f";

        //
        //示例代码
        //3.    获取类目结构树 【没有应用级参数。OK  】
        JdClient client=new DefaultJdClient(SERVER_URL,accessToken,appKey,appSecret);

        DspKcUsertagGetRequest request=new DspKcUsertagGetRequest();

        try {
            //client.xxx 没有其他方法。
            DspKcUsertagGetResponse response=client.execute(request);

            //代码拿数据。
            DspResult result = response.getQuerylistusertagResult();
            boolean success = result.getSuccess();
            if( success ){

                List<DspUserTagQuery> valueList = result.getValue();//ok
                //==========》jdbc 操作mysql。【拼接SQL】
                   /* Connection connection = JdbcUtil.getConnection();
                    Statement statement = connection.createStatement();
                    //statement.executeUpdate("INSERT INTO stu VALUES (22, 'demo', 22);");
                    statement.executeUpdate(sql);
                    //最后不要忘记释放资源哦
                    JdbcUtil.release(statement);*/
                //==========》mybatis 操作mysnewql。【封装beanList】
                ArrayList<CategoryDO> categoryDOList = new ArrayList<CategoryDO>();
                for(int i=0; i< valueList.size();i++){


                    DspUserTagQuery query = valueList.get(i);
                    String[] name = query.getName();//###测试发现 数组 属性只存 一个元素。
                    int[] type = query.getType();
                    Long[] pid = query.getPid();
                    Long[] wid = query.getWid();
                    Long[] status = query.getStatus();

                    CategoryDO categoryDO = new CategoryDO();
                    if(name!=null){
                        categoryDO.setName(name[0]);
                    }
                    if(type!=null) {
                        categoryDO.setType(type[0]);
                    }
                    if(pid!=null){
                        categoryDO.setPid(pid[0]);
                    }
                    if(wid!=null) {
                        categoryDO.setWid(wid[0]);
                    }
                    if(status!=null) {
                        categoryDO.setStatus(status[0]);
                    }
                    categoryDOList.add(categoryDO);

                    //解决SQL过长的问题【mysql SQL最大限制都装不下了。】
                    if( (i>0 && (i%1000==0)) ||  (  i==(valueList.size()-1) )  ) { //每1000个对象插入一次
                        categoryDOMapper.insertListSelective(categoryDOList);
                        categoryDOList = new ArrayList<CategoryDO>();
                    }

                }

//                categoryDOMapper.insertListSelective(List<CategoryDO> valueList)//行不通
//                categoryDOMapper.insertListSelective(categoryDOList);


                //Jackson  list转json  Str  ====测试用
                //=====》【###   MAPPER是第三方jar的Class,这里@Autowire成功,必须在xml配置bean才行!!】
                String jsonStr = MAPPER.writeValueAsString(valueList);
                System.out.println(jsonStr);//ok

            }else{
                System.out.println("查询失败。");
            }
        }catch (Exception e){
            e.printStackTrace();
        }


        return 0;
    }


    @Override
    public int insert(CategoryDO record) {
        return 0;
    }

    @Override
    public int insertSelective(CategoryDO record) {
        return 0;
    }



}

④====测试 数据完整性。逻辑。

====




====最后。框架就是框架。!!!

经验:【遇到 一些业务逻辑 无关的繁琐处理,尝试使用 相关框架。】


工欲善其事必先利其器!




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值