java生成db文件


工作中遇到一個需求,就是需要把mysql里的一些表數據生成db文件,給客戶端使用,客戶端使用sqlite數據庫;

首先我們需要在項目中添加Sqlite JDBC 依賴

<dependency>
  <groupId>org.xerial</groupId>
  <artifactId>sqlite-jdbc</artifactId>
  <version>3.23.1</version>
</dependency>

生成DB文件工具類

 

package cn.kayun.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Created by root on 2018/7/2 0002.
 */
public class DBUtil {

    private static final Logger logger = LoggerFactory.getLogger(DBUtil.class);
    private static Connection connection = null;
    private static Statement statement = null; 
    private static String username = "kanyun";
    private static String password = "kanyun";

    /**
     * @describe: 設置連接 * @params: * @Author: Kanyun * @Date: 2018/7/12 9:54
     */
    public static void setConnection() {
        try {
//            聲明驅動類型
            Class.forName("org.sqlite.JDBC");
//            設置sqlite db文件存放基本目錄
            String path = DBUtil.class.getClassLoader().getResource("").getPath();
//            設置 sqlite文件路徑,等同於mysql連接地址(jdbc:mysql://127.0.0.1:3306/test)
            String url = "jdbc:sqlite:" + path + "data.db";
//            獲取連接
            connection = DriverManager.getConnection(url, username, password);
//            聲明
            statement = connection.createStatement();
        } catch (Exception e) {
            throw new RuntimeException("建立Sqlite連接失敗");
        }


    }

    /**
     * @describe: 創建表
     * @params: tableName: 要創建的表的名稱 className:項目中Pojo的類名(需要注意的是該類名需要加上包名 如 com.xxx.xxx.pojo.xxx)
     * @Author: Kanyun
     * @Date: 2018/7/12 9:56
     */
    public synchronized static void create(String tableName, String className) {
        try {
            statement.executeUpdate("DROP TABLE IF EXISTS " + tableName + ";");
//            通過反射,獲取傳入類名的字段信息
            Field[] fields = Class.forName(className).getDeclaredFields();
            StringBuffer sb = new StringBuffer();
            String reg = " ";
            sb.append("create table " + tableName + " (");
            for (Field field : fields) {
//                設置使用反射時,可以訪問私有變量,當pojo的變量設置為private修飾時,isAccessible()得到的值是false,必須要改成true才可以訪問
                field.setAccessible(true);
//                通過獲得的字段,獲取字段類型,和字段名,來定義創建表的字段名和字段類型
                if (field.getType().getName().equals(java.lang.Long.class.getName())) {
                    sb.append(reg + field.getName() + " bigint(20) ");
                } else if (field.getType().getName().equals(java.lang.String.class.getName())) {
                    sb.append(reg + field.getName() + " varchar(255) ");
                } else if (field.getType().getName().equals(java.util.Date.class.getName())) {
                    sb.append(reg + field.getName() + " datetime ");
                } else {
                    sb.append(reg + field.getName() + " int(11) ");
                }
                reg = ",";
            }
            sb.append(") ;");
            statement.executeUpdate(sb.toString());
        } catch (Exception e) {
            logger.error("建表失敗:" + e);
            throw new RuntimeException("建表失敗,表名稱:" + tableName);
        }
    }

    /**
     * @describe: 表中插入數據
     * @params: tableName:表名 list:待插入的對象集合 需要注意的是插入的對象要跟表名對應
     * @Author: Kanyun
     * @Date: 2018/7/12 10:03
     */
    public synchronized static <T> int insert(String tableName, List<T> list) {
        StringBuffer declaration = new StringBuffer();
        List<String> dataSqlArray = new ArrayList<>();
        int count = 0;
        try {
            list.stream().map(t -> {
                if (dataSqlArray.size() < 1) {
                    logger.info("定義語句");
                    Field[] fields = t.getClass().getDeclaredFields();
                    declaration.append(" (");
                    String reg = "";
                    for (Field field : fields) {
                        field.setAccessible(true);
                        declaration.append(reg + field.getName());
                        reg = ",";
                    }
                    declaration.append(")");
                }
                return t;
            }).forEach((t) -> {
                Field[] fields = t.getClass().getDeclaredFields();
                StringBuffer oneData = new StringBuffer();
                String reg = "";
                oneData.append(" (");

                for (Field field : fields) {
                    try {
                        field.setAccessible(true);
                        if (null == field.get(t) || "".equals(field.get(t))) {
                            oneData.append(reg + null);
                        } else if (field.getType().getName().equals(java.lang.String.class.getName())) {
//                            傳入的對象中字段是字符串時,插入數據庫需要轉義單引號
                            oneData.append(reg + "\'" + field.get(t) + "\'");
//                            傳入的對象中字段是日期類型時,先將日期轉換為 yyyy-MM-dd 的形式(我這里,傳入對象的日期對象格式為:Wed Jul 11 14:34:07 CST 2018),在將其轉換成字符串,注意轉義單引號
                        } else if (field.getType().getName().equals(java.util.Date.class.getName())) {
                            String dd = field.get(t).toString();
                            SimpleDateFormat sdf1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
                            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            String date = sdf2.format(sdf1.parse(dd));
                            oneData.append(reg + "\'" + date + "\'");
                        } else {
                            oneData.append(reg + field.get(t));
                        }
                        reg = ",";
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                oneData.append(")");
                dataSqlArray.add(oneData.toString());
            });
            String dataSql = StringUtils.join(dataSqlArray, ",");
            String retSQL = "INSERT INTO " + tableName + declaration.toString()
                    + " VALUES " + dataSql + ";";
            System.out.println(retSQL);
            PreparedStatement prep = connection.prepareStatement(retSQL);
//            設置自動提交
            connection.setAutoCommit(true);
            count = prep.executeUpdate();
        } catch (Exception e) {
            logger.error("插入失敗:" + e);
            e.printStackTrace();
        }
        return count;
    }

    /**
     * @describe: 關閉鏈接
     * @params:
     * @Author: Kanyun
     * @Date: 2018/7/12 10:11
     */
    public static void endConnection() {
        try {

            connection.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

 

生成的DB文件在classess目錄下.

需要注意的是,在創建鏈接的過程中,雖然可以傳入用戶名,密碼,但是使用一些工具(比如Navicat)還是可以查看db文件的內容的,因為免費版的SQLite有一個致命缺點:不支持加密

如果需要使用sqlite加密,一是數據本身進行加密,也就是往表中插入的數據進行加密,二是可以加密db文件本身

更多加密方式,參考:https://www.cnblogs.com/ligun123/p/5206942.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM