springboot+clickhouse批量插入数据

问题:在clickhouse-server中批量插入数据;我选择的表引擎是MergeTree引擎

  1. 解决方案:
    通过file引擎建表,同时指定数据文件;
    数据文件是存储在/var/lib/clickhouse/data/数据库名/表名/
  2. 数据文件一开始就上传到data目录下,通过file引擎建表;
  3. 通过执行sql语句 INSERT INTO anothertable select * from onetable把数据导入MergeTree引擎的表里边;
package com.shi.dataopen.utils;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;

@Component
public class FtpUtils {
    //ftp服务器ip地址
    private static final String FTP_ADDRESS = "192.168.248.128";
    //端口号
    private static final int FTP_PORT = 21;
    //用户名
    private static final String FTP_USERNAME = "root";
    //密码
    private static final String FTP_PASSWORD = "123456";
     private static final String FTP_BASEPATH = "/var/lib/clickhouse/data/default/";
    //参数传过来了文件和文件的输入流

    public String getPath(String tableName){
        return FTP_BASEPATH+tableName+"/";
    }
    public boolean uploadFile(String tableName,String originFileName, InputStream input) {
        boolean success = false;
        FTPClient ftp = new FTPClient();//这是最开始引入的依赖里的方法
        ftp.setControlEncoding("utf-8");
        try {
            int reply;
            ftp.connect(FTP_ADDRESS, FTP_PORT);// 连接FTP服务器
            ftp.login(FTP_USERNAME, FTP_PASSWORD);// 登录
            reply = ftp.getReplyCode();//连接成功会的到一个返回状态码
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);//设置文件类型
            ftp.changeWorkingDirectory(getPath(tableName));//修改操作空间
            ftp.storeFile(originFileName, input);//这里开始上传文件
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                System.out.println("连接失败");
                return success;
            }
            System.out.println("连接成功!");
            input.close();
            ftp.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }
}

使用了其他博主写好的工具类=。=

在clickhouse数据库,主要是操作数据集;

构建sql语句;

package com.shi.dataopen.utils;


import org.springframework.stereotype.Component;
import java.sql.*;


@Component
public class CHConnectUtils {
    /*    * 在静态池中创建CH连接
     * */
    private static Connection connection = null;
    static {
        try {
            Class.forName("ru.yandex.clickhouse.ClickHouseDriver");
            String url = "jdbc:clickhouse://192.168.248.128:8123/default";
            String user = "";
            String password = "";
            connection = DriverManager.getConnection(url,user,password);
        } catch (Exception e) {
            e.printStackTrace( );
        }
    }
    /*执行查询语句*/
    public void exeSelSql(String sql) throws Exception {
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(sql);
        ResultSetMetaData metaData = resultSet.getMetaData( );
        int columnCount = metaData.getColumnCount( );
        while (resultSet.next()){
            for (int i = 1; i <= columnCount; i++) {
                System.out.println(metaData.getColumnName(i)+":"+resultSet.getString(i));
            }
        }
    }
    /*执行插入,修改,删除语句*/
    public void exeInsertSql(String sql) throws SQLException {
        Statement statement = connection.createStatement();
        statement.executeUpdate(sql);
    }
    public void exeUseSql(String sql) throws SQLException {
        Statement statement = connection.createStatement();
        Boolean flag = statement.execute(sql);
        if (flag){
            System.out.println("执行成功");
        }else {
            System.out.println("执行失败");
        }
    }
    /*动态拼接建表语句*/
    public String CreateTablesql(String tablename,String dataName,String dataType,String partition,String OrderBy){
        String datanames[] = dataName.split(",");
        String dataTypes[] = dataType.split(",");
        System.out.println(datanames);
        System.out.println(dataTypes);
        String sql = "create table IF NOT EXISTS "+tablename+" (";
        if (datanames.length == dataTypes.length&&datanames!=null||dataTypes==null){
            for (int i = 0;i<datanames.length-1;i++){
                sql = sql+ datanames[i]+" "+dataTypes[i]+",";
            }
            sql = sql+datanames[datanames.length-1]+" "+dataTypes[datanames.length-1]+")engine=MergeTree() PARTITION BY "+partition+" ORDER BY "+OrderBy+";";
        }
        System.out.println(sql);
        return sql;
    }
    /*动态的插入语句*/
    public String InsertSql(String MergeTreeTableName,String tableName){
        String sql = "insert into "+MergeTreeTableName+" select * from "+tableName;
        return sql;
    }

    /*创建临时表语句*/
    public String InsertFileSql(String tableName,String dataName,String dataType){
        String datanames[] = dataName.split(",");
        String datatypes[] = dataType.split(",");
        String sql = "create table if not exists "+tableName+"(";
        if (datanames.length == datatypes.length){
            for (int i = 0;i<datanames.length-1;i++){
                sql = sql+ datanames[i]+" "+datatypes[i]+",";
            }
            sql = sql+datanames[datanames.length-1]+" "+datatypes[datanames.length-1]+") engine=File('CSV');";
        }
        return sql;
    }
}

控制器类:

    @PostMapping("/upload")
    public String upload(MultipartFile file,
                         @RequestParam("OrderBy") String OrderBy,
                         @RequestParam("dataName") String dataName,
                         @RequestParam("dataType")String dataType,
                         @RequestParam("partition") String partition,
                         HttpSession session,Model model) throws Exception {

        Date date = new Date();
        /*获取文件名称*/
        String fileName = file.getOriginalFilename();
        String type = file.getContentType();
        String ext ="."+ FilenameUtils.getExtension(fileName);
        opendatafile.setOldFileName(null);
        /*获取文件名后缀*/
        opendatafile.setExt(ext);
        /*获取文件大小*/
        Long size = file.getSize();
        opendatafile.setSize(size);
        /*文件类型*/
        opendatafile.setType(type);
        opendatafile.setUploadTime(new Date());
        /*数据表名*/
        String newFileName =  new SimpleDateFormat("yyyyMMddHHmmss").format(date)+"-"+fileName;
        System.out.println("------------------------"+newFileName);
        opendatafile.setFilename(newFileName);
        String filePath = "/home/ubuntu/Desktop/CHFiles/";
        opendatafile.setFilepath(filePath);
        User user = (User) session.getAttribute("user");
        opendatafile.setUid(user.getUid());
        fileService.insertFile(opendatafile);
        InputStream inputStream = file.getInputStream();

        /*建file引擎的表*/
        String tableName = newFileName.replace(".","_").replace("-","_");
        /*文件上传到ubuntu桌面文件夹上*/
        chConnectUtils.exeUseSql(chConnectUtils.InsertFileSql(tableName,dataName,dataType));
        Boolean flag = ftpUtils.uploadFile(tableName,"data.CSV",inputStream);//主要就是这里实现了ftp的文件上传

        /*建MergeTree引擎的表*/
        String MergeTreeTableName = tableName+"_CH";
        chConnectUtils.exeUseSql(chConnectUtils.CreateTablesql(MergeTreeTableName,dataName,dataType,partition,OrderBy));
        /*插入MergeTree引擎的表*/
        chConnectUtils.exeUseSql(chConnectUtils.InsertSql(MergeTreeTableName,tableName));
        return "redirect:/UserDetail";
    }

控制器就很乱…

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值