JDBC 动态创建数据表 及 SQL预处理

5 篇文章 0 订阅

        这两天由于公司的需求,客户需要自定义数据表的字段,导致每张表的字段都不是固定的而且很难有一个通用的模板去维护,所以就使用JDBC动态去创建数据表,然后通过表的字段动态添加数据,数据的来源主要是用户提供的Excel直接导入到数据库中。

       如果考虑到字段的类型,可以通过反射的机制去获取,现在主要用户需求就是将数据导入到数据库提供查询功能,不能修改,所以就直接都使用String类型来处理数据更加便捷。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;


public class DataBaseSql {
  //配置文件 读取jdbc的配置文件
  private static ResourceBundle bundle = PropertyResourceBundle.getBundle("db");
  private static Connection conn;
  private static PreparedStatement ps;    
  
    /**
     * 创建表
     * @param tabName 表名称
     * @param tab_fields  表字段
     */
    public static void createTable(String tabName,String[] tab_fields) {
        conn = getConnection();    // 首先要获取连接,即连接到数据库
        try {
            String sql = "create table "+tabName+"(id int auto_increment primary key not null"; 
            
            if(tab_fields!=null&&tab_fields.length>0){
                sql+=",";
                int length = tab_fields.length;
                for(int i =0 ;i<length;i++){
                    //添加字段
                    sql+=tab_fields[i].trim()+" varchar(50)";
                    //防止最后一个,
                    if(i<length-1){
                        sql+=",";
                    }
                }
            }
            //拼凑完 建表语句 设置默认字符集
            sql+=")DEFAULT CHARSET=utf8;";
            System.out.println("建表语句是:"+sql);
            ps = conn.prepareStatement(sql);
            ps.executeUpdate(sql);  
            ps.close();
            conn.close();    //关闭数据库连接
        } catch (SQLException e) {
            System.out.println("建表失败" + e.getMessage());
        }
    }
    
    /**
     * 添加数据
     * @param tabName 表名
     * @param fields 参数字段
     * @param data 参数字段数据
     */
    public static void insert(String tabName,String[] fields,String[] data) {
        conn = getConnection();    // 首先要获取连接,即连接到数据库
        try {
            String sql = "insert into "+tabName+"("; 
            int length = fields.length;
            for(int i=0;i<length;i++){
                sql+=fields[i];
                //防止最后一个,
                if(i<length-1){
                    sql+=",";
                }
            }
            sql+=") values(";
            for(int i=0;i<length;i++){
                sql+="?";
                //防止最后一个,
                if(i<length-1){
                    sql+=",";
                }
            }
            sql+=");";
            System.out.println("添加数据的sql:"+sql);
            //预处理SQL 防止注入
            excutePs(sql,length,data);
            //执行
            ps.executeUpdate();
            //关闭流
            ps.close();
            conn.close();    //关闭数据库连接
        } catch (SQLException e) {
            System.out.println("添加数据失败" + e.getMessage());
        }
    }
    
    /**
     * 查询表  【查询结果的顺序要和数据库字段的顺序一致】
     * @param tabName 表名
     * @param fields 参数字段 
     * @param data  参数字段数据
     * @param tab_fields 数据库的字段
     */
    public static  String[] query(String tabName,String[] fields,String[] data,String[] tab_fields){
        conn = getConnection();    // 首先要获取连接,即连接到数据库
        String[] result = null;
        try {
            String sql = "select * from  "+tabName+" where ";
             int length = fields.length;
             for(int i=0;i<length;i++){
                    sql+=fields[i]+" = ? ";
                    //防止最后一个,
                    if(i<length-1){
                        sql+=" and ";
                    }
             }
             sql+=";";
             System.out.println("查询sql:"+sql);
            //预处理SQL 防止注入
            excutePs(sql,length,data);
            //查询结果集
            ResultSet rs = ps.executeQuery();
            //存放结果集
            result = new String[tab_fields.length];
            while(rs.next()){
                    for (int i = 0; i < tab_fields.length; i++) {
                        result[i] = rs.getString(tab_fields[i]);
                    }
                }
            //关闭流
            rs.close();
            ps.close();
            conn.close();    //关闭数据库连接
        } catch (SQLException e) {
             System.out.println("查询失败" + e.getMessage());
        }
        return result;
    }
    
    /**
     * 获取某张表总数
     * @param tabName
     * @return
     */
    public static Integer getCount(String tabName){
        int count  = 0;
         conn = getConnection();    // 首先要获取连接,即连接到数据库
         try {
            String sql = "select count(*) from  "+tabName+" ;";
             ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery();
              while(rs.next()){
                  count = rs.getInt(1);
                }
             rs.close();
             ps.close();
             conn.close();    //关闭数据库连接
        } catch (SQLException e) {
             System.out.println("获取总数失败" + e.getMessage());
        }
        return count;
    }
    
    /**
     * 后台分页显示
     * @param tabName
     * @param pageNo
     * @param pageSize
     * @param tab_fields
     * @return
     */
    public static  List<String[]> queryForPage(String tabName,int pageNo,int pageSize ,String[] tab_fields){
        conn = getConnection();    // 首先要获取连接,即连接到数据库
        List<String[]> list = new ArrayList<String[]>();
        try {
            String sql = "select * from  "+tabName+" LIMIT ?,? ; ";
             System.out.println("查询sql:"+sql);
             //预处理SQL 防止注入
             ps = conn.prepareStatement(sql);
             //注入参数
              ps.setInt(1,pageNo);
              ps.setInt(2,pageSize);
             
            //查询结果集
            ResultSet rs = ps.executeQuery();
            //存放结果集
            while(rs.next()){
                 String[] result = new String[tab_fields.length];
                    for (int i = 0; i < tab_fields.length; i++) {
                        result[i] = rs.getString(tab_fields[i]);
                    }
                 list.add(result);    
                }
            //关闭流
            rs.close();
            ps.close();
            conn.close();    //关闭数据库连接
        } catch (SQLException e) {
             System.out.println("查询失败" + e.getMessage());
        }
        return list;
    }
    
    
    
    /**
     * 清空表数据
     * @param tabName 表名称
     */
    public static void delete(String tabName){
           conn = getConnection();    // 首先要获取连接,即连接到数据库
        
           try {
               String sql = "delete from  "+tabName+";"; 
               System.out.println("删除数据的sql:"+sql);
               //预处理SQL 防止注入
               ps = conn.prepareStatement(sql);
               //执行
               ps.executeUpdate();
               //关闭流
               ps.close();
               conn.close();    //关闭数据库连接
           } catch (SQLException e) {
               System.out.println("删除数据失败" + e.getMessage());
           }
    }
    
    /**
     * 用于注入参数
     * @param ps
     * @param data
     * @throws SQLException 
     */
     private static void excutePs(String sql,int length,String[] data) throws SQLException{
         //预处理SQL 防止注入
         ps = conn.prepareStatement(sql);
         //注入参数
         for(int i=0;i<length;i++){
              ps.setString(i+1,data[i]);
         }
     }
     
     
     /* 获取数据库连接的函数*/
    private static Connection getConnection() {
        Connection con = null;    //创建用于连接数据库的Connection对象
        try {
                Class.forName(bundle.getString("db.classname"));// 加载Mysql数据驱动
                con =  DriverManager.getConnection(bundle.getString("db.url"), bundle.getString("db.username"), bundle.getString("db.password"));// 创建数据连接
        } catch (Exception e) {
                System.out.println("数据库连接失败" + e.getMessage());
        }
        return con;    //返回所建立的数据库连接
    }
    
    /**
     * 判断表是否存在
     * @param tabName
     * @return
     */
    public static boolean exitTable(String tabName){
        
        boolean flag = false;
          conn = getConnection();    // 首先要获取连接,即连接到数据库
          try {
              String sql = "select id from  "+tabName+";"; 
              //预处理SQL 防止注入
              ps = conn.prepareStatement(sql);
              //执行
              flag =  ps.execute();
              //关闭流
              ps.close();
              conn.close();    //关闭数据库连接
          } catch (SQLException e) {
              System.out.println("删除数据失败" + e.getMessage());
          }
        return flag;
    }
    
    /**
     * 删除数据表
     * 如果执行成功则返回false
     * @param tabName
     * @return
     */
    public static boolean dropTable(String tabName){
        boolean flag = true;
          conn = getConnection();    // 首先要获取连接,即连接到数据库
             try {
                 String sql = "drop table  "+tabName+";"; 
                 //预处理SQL 防止注入
                 ps = conn.prepareStatement(sql);
                 //执行
                 flag =  ps.execute();
                 //关闭流
                 ps.close();
                 conn.close();    //关闭数据库连接
             } catch (SQLException e) {
                 System.out.println("删除数据失败" + e.getMessage());
             }
           return flag;  
    }
    
    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        //建表===========================================
        //表名
//        String tabName = "mytable";
        //表字段
//        String[] tab_fields = {"name","password","sex","age"};
        //创建表
//        createTable(tabName, tab_fields);
        
        //添加===========================================
        //模拟数据
//        String[] data1 = {"jack","123456","男","25"};
//        String[] data2 = {"tom","456789","女","20"};
//        String[] data3 = {"mark","aaa","哈哈","21"};
        //插入数据
//        insert(tabName, tab_fields, data1);
//        insert(tabName, tab_fields, data2);
//        insert(tabName, tab_fields, data3);
        
        
        //查询=============================================
//        String[] q_fileds ={"name","sex"};
//        String[] data4 = {"jack","男"};
//        
//        String[] result = query(tabName, q_fileds, data4, tab_fields);
//        for (String string : result) {
//            System.out.println("结果:\t"+string);
//        }
        
        //删除 清空=============================================
//        delete(tabName);
        
        //是否存在
//        System.out.println(exitTable("mytable"));
        //删除表
//        System.out.println(dropTable("mytable"));
    }
}


数据库的配置文件 db.properties

db.username=root
db.password=root
db.classname=com.mysql.jdbc.Driver
db.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull



  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是一段使用Javajdbc查询SQL语句的代码,同时也规避了SQL注入漏洞的风险: ``` import java.sql.*; import java.util.Scanner; public class SQLInjectionExample { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { // 加载驱动 Class.forName("com.mysql.jdbc.Driver"); // 创建连接 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "username", "password"); Scanner scanner = new Scanner(System.in); System.out.print("请输入表名:"); String tableName = scanner.nextLine(); // 使用PreparedStatement预处理语句,防止SQL注入 String sql = "SELECT * FROM " + tableName; preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { // 处理查询结果 ... } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (resultSet != null) { resultSet.close(); } if (preparedStatement != null) { preparedStatement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } ``` 通过使用`PreparedStatement`预处理语句,我们可以有效的防止SQL注入漏洞的发生。 ### 回答2: 对于使用JDBC查询SQL语句,规避SQL注入漏洞且其中的表名动态的,可以采用参数化查询的方式来实现。 代码示例: ```java import java.sql.*; public class JdbcDemo { public static void main(String[] args) { // 假设动态表名为tableName,替换为实际的表名 String tableName = "your_dynamic_table_name"; try { // 连接数据库 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "username", "password"); // 构造SQL语句 String sql = "SELECT * FROM " + tableName + " WHERE id = ?"; // 创建预编译的Statement对象 PreparedStatement statement = connection.prepareStatement(sql); // 设置参数值 statement.setInt(1, 1); // 假设需要查询id为1的记录,替换为实际需求 // 执行查询 ResultSet resultSet = statement.executeQuery(); // 处理查询结果 while(resultSet.next()) { // 获取数据,并进行相应处理 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); // 其他字段类似 System.out.println("id: " + id + ", name: " + name); } // 关闭资源 resultSet.close(); statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } ``` 上述代码中,使用PreparedStatement对象来进行参数化查询,即将动态表名通过占位符的方式进行替换,从而避免了SQL注入漏洞的风险。 在SQL语句中使用`?`作为占位符,然后使用`setXxx()`方法来设置参数值,其中`Xxx`表示具体的数据类型,比如`setInt()`用于整型,`setString()`用于字符串等。这种方式可以确保SQL语句的安全性,同时提高了代码的可读性和可维护性。 需要注意的是,上述代码中的数据库连接信息以及动态表名、参数值等都需要根据实际情况进行替换。 ### 回答3: 当我们使用JDBC查询SQL语句时,为了避免SQL注入漏洞,我们可以通过使用参数化查询来保护我们的代码。参数化查询是指将SQL语句中的参数用占位符替代,然后在执行查询时,将真正的参数值传递给占位符。 以下是一个示例代码,演示如何在JDBC中使用参数化查询,并规避SQL注入漏洞: ``` import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JdbcExample { public static void main(String[] args) { Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; try { // 连接数据库 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password"); // 编写SQL语句,并将参数用问号代替 String sql = "SELECT * FROM mytable WHERE column_name = ?"; // 使用PreparedStatement对象来预编译SQL语句 statement = connection.prepareStatement(sql); // 设置查询参数的值,这里使用了动态的标名 statement.setString(1, "动态的标名"); // 执行查询 resultSet = statement.executeQuery(); // 处理查询结果 while (resultSet.next()) { // 操作结果集的字段数据 String columnValue = resultSet.getString("column_name"); System.out.println(columnValue); } } catch (SQLException e) { e.printStackTrace(); } finally { // 释放资源 try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } ``` 在上述代码中,通过使用PreparedStatement对象来预编译SQL语句,并使用`setString()`方法来设置查询参数的值。这样可以确保参数值不会直接被拼接到SQL语句中,从而有效地规避了SQL注入漏洞。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值