zoukankan      html  css  js  c++  java
  • JDBC 数据处理 总结

           以下是JDBC批处理的例子,还有处理数据的一些总结。(在公司把MySql数据库几千万的数据导入搜索Elasticsearch里面)

    一、功能描述

     

    二、细节考虑

    2.1 为什么使用PreparedStatement进行处理?

      1、PreparedStatement接口继承Statement,PreparedStatement实例包含已编译的SQL语句,所以其执行速度要快于Statement 对象。

      2、PreparedStatement支持占位符,提高了安全性,它防止了sql语句的注入(实际处理数据时候,如果商品名称有单引号,不使用PreparedSatement会报错!)

      3、PreparedStatement代码的可读性和可维护性较好.

    2.2 分页查询和Result游标进行查询有什么区别?

           分页查询是每次去数据库查询一批结果回来,进行处理,如此循环,每次循环都要建立数据库连接;Result游标也是每次去数据库取一部分结果回来(Oracle默认是10条,MySql也支持),但是只需要打开一个连接,持续使用;如果数据量很大,通信速度很快,使用游标进行数据查询。

    2.3 MySql JDBC怎么实现Result游标?

      1、当statement设置以下属性时,采用的是流数据接收方式,每次只从服务器接收部份数据,直到所有数据处理完毕,不会发生JVM OOM。

              setResultSetType(ResultSet.TYPE_FORWARD_ONLY);

              setFetchSize(Integer.MIN_VALUE); 

      2、调用statement的enableStreamingResults方法,实际上enableStreamingResults方法内部封装的就是第1种方式。

      3、设置连接属性useCursorFetch=true (5.0版驱动开始支持),statement以TYPE_FORWARD_ONLY打开,再设置fetch size参数,表示采用服务器端游标,每次从服务器取fetch_size条数据。

    三、代码

    地址:https://github.com/huangchanghuan/CouponsUtil

      3.1  JDBC批处理MySql数据

        public static long importData( ){
            String url = "jdbc:mysql://192.168.0.183:3306/couponsdb?user=root&password=" +
                    "Sunstar123!&useUnicode=true&characterEncoding=UTF-8";
            String sql = "SELECT a.classid,a.spname,a.sppic,0,0,1,b.value_id,a.id FROM " +
                    "ss_hj_search_result a LEFT JOIN ss_hj_value b ON (a.brand_name = b.value_name " +
                    "AND b.quantity_id = 1) WHERE a.id not in (select autoid from ss_hj_product_relation)";
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e1) {
                e1.printStackTrace();
            }
            long allStart = System.currentTimeMillis();
            long count =0;
            Connection con = null;
            Connection con1 = null;
            PreparedStatement psHJSearchResult = null;
            PreparedStatement psHJProduct = null;
            PreparedStatement psHJProductPicture = null;
            PreparedStatement psHJProductRelation = null;
            ResultSet rs = null;
            int productId=572457;
            int pictureId=1711669;
            int relationId=252381;
            try {
                //查询操作创建连接(这个连接单独用来查询,游标需要保持连接不断开)
                con = DriverManager.getConnection(url);
                con.setAutoCommit(false);
                psHJSearchResult = con.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY,
                        ResultSet.CONCUR_READ_ONLY);
                psHJSearchResult.setFetchSize(1);
                psHJSearchResult.setFetchDirection(ResultSet.FETCH_REVERSE);
                rs = psHJSearchResult.executeQuery();
                // 写入操作创建连接
                con1 = DriverManager.getConnection(url);
                con1.setAutoCommit(false);
                //插入ss_hj_product
                psHJProduct = con1.prepareStatement("insert into ss_hj_product" +
                        "(PRODUCT_ID,CLS_ID,PRODUCT_NAME,MAIN_PICTURE,SALES_VOLUME," +
                        "COMMENTS_NUMBER,STS,PRIORITY,BRAND_ID) values(?,?,?,?,?,?,?,?,?)");
                //插入ss_hj_product_picture
                psHJProductPicture = con1.prepareStatement("insert into ss_hj_product_picture" +
                        "(PRODUCT_ID,PRODUCT_URL,PRODUCT_VIEW_URL,PICTURE_ID) values(?,?,?,?)");
                //插入ss_hj_product_relation
                psHJProductRelation = con1.prepareStatement("insert into ss_hj_product_relation" +
                        "(PRODUCT_ID,AUTOID,RELATION_ID) values(?,?,?)");
                while (rs.next()) {
                        //聚合商品表
                        psHJProduct.setInt(1,productId);
                        psHJProduct.setInt(2,rs.getInt("classid"));
                        psHJProduct.setString(3,rs.getString("spname"));
                        psHJProduct.setString(4,rs.getString("sppic"));
                        psHJProduct.setInt(5,0);
                        psHJProduct.setInt(6,0);
                        psHJProduct.setInt(7,1);
                        psHJProduct.setInt(8,productId);
                        psHJProduct.setInt(9,rs.getInt("value_id"));
                        psHJProduct.addBatch();
                        //图片表
                        psHJProductPicture.setInt(1,productId);
                        psHJProductPicture.setString(2,rs.getString("sppic"));
                        psHJProductPicture.setString(3,rs.getString("sppic"));
                        psHJProductPicture.setInt(4,pictureId);
                        psHJProductPicture.addBatch();
                        //关系表
                        psHJProductRelation.setInt(1,productId);
                        psHJProductRelation.setInt(2,rs.getInt("id"));
                        psHJProductRelation.setInt(3,relationId);
                        psHJProductRelation.addBatch();
                        //id增加
                        productId++;
                        pictureId++;
                        relationId++;
                    count++;
                    if(count%100000==0) {//提交
                        psHJProduct.executeBatch();
                        psHJProductPicture.executeBatch();
                        psHJProductRelation.executeBatch();
                        con1.commit();
                    }
                }
                //最后一批没有提交处理
                psHJProduct.executeBatch();
                psHJProductPicture.executeBatch();
                psHJProductRelation.executeBatch();
                con1.commit();
            } catch (Exception e) {
                logger.error("异常");
                e.printStackTrace();
            } finally {
                logger.error("=productId:"+productId);
                logger.error("=pictureId:"+pictureId);
                logger.error("=relationId:"+relationId);
                try {
                    if(rs!=null){
                        rs.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(psHJSearchResult!=null){
                        psHJSearchResult.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(con!=null){
                        con.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            return count;
        }

      3.2 JDBC批处理和ES Java Client批处理数据

    四、总结

      1.JDBC要配置编码格式,不然可能出现乱码;

      2.因为数大数据量处理,编码时候注意JVM的GC回收;

      3.使用PreparedStatement处理数据;

  • 相关阅读:
    Vue插件之导出EXCEl
    vue.js--加载JSON文件的两种方式
    vue项目中axios的封装
    雪碧图布局
    开始学习算法
    Java中有关Null的9件事
    一个抓取知乎页面图片的简单爬虫
    浅析Java中的final关键字
    Java中String、StringBuilder以及StringBuffer
    把一个数组向右循环移动k位要求时间复杂度为O(n)
  • 原文地址:https://www.cnblogs.com/huangchanghuan/p/8034489.html
Copyright © 2011-2022 走看看