zoukankan      html  css  js  c++  java
  • 执行SQL语句的方式

    JDBC不仅可执行查询,也可以执行DDL,DML等SQL语句,从而允许通过JDBC最大限度地控制数据库。

    使用executeUpdate或者使用executeLargeUpdate方法来执行DDL和DML语句:

     编写程序,通过executeUpdate方法在mysql当前数据库下创建一个数据库表 示范:

    public class JDBC {
        String driver;
        String url;
        String user;
        String password;
        
        //查询该数据库是否有对应的表,有则返回ture,没有返回false
        public boolean tableIsExists(String tableName){
            try{
                Connection conn =DriverManager.getConnection(url,user,password);
                Statement statement =conn.createStatement();
                String sql = "select table_name from information_schema.tables where table_schema='test'";
                ResultSet resultSet = statement.executeQuery(sql);
                while(resultSet.next()){
                    String queryTableName = resultSet.getString(1);
                    System.out.println(queryTableName);
                    if(queryTableName.equals("tb_test")){
                        return true;
                    }
                }
            }catch(Exception e){}
            return false;
        }
        
        public void createTableJDBC(String tableName){
            try{
                Connection conn =DriverManager.getConnection(url,user,password);
                Statement statement =conn.createStatement();
                if(!tableIsExists(tableName)){
                    System.out.println("当前数据库没有"+tableName+"表格,将创建"+tableName+"数据库表");
                    String sql = "create table "+tableName+"("
                            + "test_id int auto_increment primary key,"
                            + "test_name varchar(255),"
                            + "test_desc text)";
                    int result = statement.executeUpdate(sql);
                }else{
                    System.out.println("当前数据库有"+tableName+"表格,不创建"+tableName+"数据库表");
                }
                
            }catch(Exception e){}
        }
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            JDBC jdbc = new JDBC();
            
            jdbc.initParam("mysql.properties");
            jdbc.createTableJDBC("tb_test");
        }
    }

     第一次运行结果如下:

    tb_adminuser
    tb_user
    当前数据库没有tb_test表格,将创建tb_test数据库表

     第二此运行结果如下(假如没有操作mysql数据的话):

    tb_adminuser
    tb_test
    当前数据库有tb_test表格,不创建tb_test数据库表

     编写程序,对上述新增表添加数据:

    public class JDBC {
        String driver;
        String url;
        String user;
        String password;
        public void initParam(String paramFile){
            try{
                Properties props = new Properties();
                props.load(new FileInputStream(paramFile));
                driver = props.getProperty("driver");
                url = props.getProperty("Url");
                user = props.getProperty("user");
                password = props.getProperty("password");
                
            }catch(Exception e){}
        }
        
        public void addData(String table,String sql){
            try{
                Connection conn =DriverManager.getConnection(url,user,password);
                Statement statement =conn.createStatement();
                int resultRow = statement.executeUpdate(sql);
                System.out.println("对"+table+"表添加了1条数据,该表受影响行数为"+resultRow);
            }catch(Exception e){}
        }
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            JDBC jdbc = new JDBC();
    
            jdbc.initParam("mysql.properties");
            String table = "tb_test";
            String sql = "insert into "+table+"(test_name,test_desc) values('hjl','0');";
            jdbc.addData(table, sql);
        }
    }

     运行的效果为:

    对tb_test表添加了1条数据,该表受影响行数为1

     通过两个代码进行测试可以得知,使用executeUpdate(String sql) 是可以对数据库进行DML语句与DDL语句操作的,不同的是,DDL语句因为不是对表中内容进行操作,因此返回的值为0;而DML语句是对表格内容进行操作的,因此返回影响表格内容的行数。

    使用execute方法执行SQL语句:

     Statement的execute()方法几乎可以执行任何SQL语句,但它执行SQL语句时比较麻烦,通常都是使用executeQuery()方法或者executeUpdate()方法来执行SQL语句;只有不清楚SQL语句的类型,为了保证不出错,最好是用execute()方法来执行该SQL语句。

     使用execute()的返回值是boolean,那么如何来获取执行查询语句获得的ResultSet对象,以及如何获取执行DDL或者DML语句获得的int数值呢?针对这种情况,Statement提供了如下两个方法:

      1.getResultSet(): 该方法返回Statement执行查询语句所返回的ResultSet对象。

      2. getUpdateCount():该方法返回statementDDL,DML语句所影响的记录行数。

     下面程序示范了使用Statment的execute()方法来执行任意的SQL语句。

    public class JDBC {
        
        //使用execute方法进行对表查询
        public void queryByExecuteMethod(String table){
            try{
                String sql = "select * from "+table;
                boolean b = statement.execute(sql);
                if(b){
                    System.out.println("execute方法返回"+b);
                    ResultSet result = statement.getResultSet();
                    int count = 0;
                    while(result.next()){
                        count++;
                    }
                    System.out.println("一共查询了"+count+"条记录");
                }else{System.out.println("execute方法返回"+b);}
            }catch(Exception e){}
        }
        
        //使用execute方法进行DML删除该表的内容
        public void deleteDataByExecuteMethod(String table){
            try{
                String sql = "delete from "+table;
                boolean b = statement.execute(sql);
                if(!b){
                    System.out.println("execute方法返回"+b);
                    System.out.println(table+"受影响行数为:"+statement.getUpdateCount());
                }else{System.out.println("execute方法返回"+b);}
            }catch(Exception e){}
        }
        
        //使用execute方法进行DDL删除该表
        public void dropTableByExecuteMethod(String table){
            try{
                String sql = "drop table "+table;
                boolean b = statement.execute(sql);
                if(!b){
                    System.out.println("execute方法返回"+b);
                    System.out.println(table+"受影响行数为:"+statement.getUpdateCount());
                }else{System.out.println("execute方法返回"+b);}
            }catch(Exception e){}
        }
        
        Connection conn = null;
        Statement statement = null;
        public JDBC(String paramFile){
            try{
                Properties props = new Properties();
                props.load(new FileInputStream(paramFile));
                String driver = props.getProperty("driver");
                String url = props.getProperty("Url");
                String user = props.getProperty("user");
                String password = props.getProperty("password");
                conn =DriverManager.getConnection(url,user,password);
                statement =conn.createStatement();
                
            }catch(Exception e){}
        }
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            String table = "tb_test";
            JDBC jdbc_2 = new JDBC("mysql.properties");
            jdbc_2.queryByExecuteMethod(table);
            jdbc_2.deleteDataByExecuteMethod(table);
            jdbc_2.dropTableByExecuteMethod(table);
        }
    }

     上述程序中,使用了execute()方法执行了三种SQL语句,分别是查询语句,DML语句与DDL语句,其中查询语句返回的是True值,根据true值从Statement对象中获取ResultSet对象,而根据false值,从Statement对象中获取getUpdateCount()方法的值,其运行效果为:

    execute方法返回true
    一共查询了2条记录
    execute方法返回false
    tb_test受影响行数为:2
    execute方法返回false
    tb_test受影响行数为:0

    使用PreparedStatement执行SQL语句:

     如果在程序中有经常反复执行一条结构相似的SQL语句,例如下面两句:

    insert into tb_test values(null,'张三',1);
    insert into tb_test values(null,'李四',2);

     对于上述两句,它们的结构基本相似,值时执行插入时的值不同而已。对于这种情况,可以使用带占位符(?)参数的SQL语句来代替它们,即:

    insert into tb_test values(null,?,?)

     但Statement执行的SQL语句是不允许使用问号占位符参数,而且这个问号占位符参数必须获得值后才可以执行。为了满足这种情况,JDBC提供了PreparedStatement接口,该接口是Statement接口的子接口,它可以预编译SQL语句,预编译后的SQL语句被存储到PreparedStatement对象中,然后可以使用该对象对此高效地执行该语句。

     PreparedStatement接口也实现了Statement接口的execute,executeQuery,executeUpdate方法,不过都没有带参数,因为SQL语句早已经在PreparedStatement对象里。若要执行PreParedStatement对象里预编译的SQL语句,需要为问号占位符参数传入参数值,PrepatedStatement提供了一系列的setXxx(int index,Xxx value)方法传入参数值。(若不清楚传入值的数据类型,可以使用Object来代替)。

     下面使用Statement以及PrepareStatement分别对tb_test表插入10条数据,并作对比:

    public class JDBC {

       String driver;
         String url;
       String user;
       String password;

    public void addDatas(String table,boolean insertType){
            try{
                String sql =null;int result = 0;
                System.out.println("开始对"+table+"表插入数据");
                if(insertType){
                    sql = "insert into "+table+" values(null,?,?)";
                    System.out.println(sql);
                    PreparedStatement prepareStatement = conn.prepareStatement(sql);
                    for(int i=0;i<5;i++){
                        prepareStatement.setString(1, "name_HJL"+i);
                        prepareStatement.setString(2,"desc_"+i);
                        result = prepareStatement.executeUpdate();
                        System.out.println(table+"受影响行数为:"+result);
                    }
                }else{
                    for(int i=0;i<5;i++){
                        sql = "insert into "+table+" values(null,'HJL"+i+"','"+i+"')";
                        System.out.println(sql);
                        result = statement.executeUpdate(sql);
                        System.out.println(table+"受影响行数为:"+result);
                    }
                }
                System.out.println("插入数据完毕!");        
            }catch(Exception e){}
        }
        
        Connection conn = null;
        Statement statement = null;
        public JDBC(String paramFile){
            try{
                Properties props = new Properties();
                props.load(new FileInputStream(paramFile));
                driver = props.getProperty("driver");
                url = props.getProperty("Url");
                user = props.getProperty("user");
                password = props.getProperty("password");
                conn =DriverManager.getConnection(url,user,password);
                statement =conn.createStatement();
                
            }catch(Exception e){}
        }
        
        public static void main(String[] args) {
            JDBC jdbc_2 = new JDBC("mysql.properties");
            String table = "tb_test";
            
            jdbc_2.addDatas(table,true);
            jdbc_2.addDatas(table,false);
        }
    }

     根据上述的代码,我们可以看到使用Statement来编写SQL语句是比较麻烦的,不仅仅要区分双引号还有单引号,有时候是因为这个错误才导致程序执行不下去,同时编程时是没有提示说该sql是错误的,只有等到运行为止才知道。

     运行结果如下:

    开始对tb_test表插入数据
    insert into tb_test values(null,?,?)
    tb_test受影响行数为:1
    tb_test受影响行数为:1
    tb_test受影响行数为:1
    tb_test受影响行数为:1
    tb_test受影响行数为:1
    插入数据完毕!
    开始对tb_test表插入数据
    insert into tb_test values(null,'HJL0','0')
    tb_test受影响行数为:1
    insert into tb_test values(null,'HJL1','1')
    tb_test受影响行数为:1
    insert into tb_test values(null,'HJL2','2')
    tb_test受影响行数为:1
    insert into tb_test values(null,'HJL3','3')
    tb_test受影响行数为:1
    insert into tb_test values(null,'HJL4','4')
    tb_test受影响行数为:1
    插入数据完毕!
    View Code

     总体来看,PreparedStatement比使用Statement有以下的优势:

      1.PreparedStatement预编译SQL语句,性能更好

      2.PreparedStatement无须“拼接”SQL语句,编程更简单

      3.PreparedStatement可以放置SQL注入,安全性更好

    使用CallableStatement调用存储过程:

     在JDBC中,若想编写存储过程,是使用CallableStatement对象,该对象是由Connection的perpareCall(String sql)方法来创建,调用存储过程的SQL语句总是这种格式:{call 存储过程名称(?,?,?.....)},其中的问号作为存储过程参数的占位符。例如:

    delimiter //
    create procedure add_pro(a int, b int,out sum int)
    begin
    set sum = a+b;
    end;
    //

     上述代码是数据库存储过程的SQL语句,下面是将上述的SQL语句,变成perpareCall()方法使用对应格式的存储过程SQL格式:

    Connection.prepareCall("call add_pro(?,?,?)");

     存储过程的参数既有传入参数,也有传出参数。所谓传入参数就是Java程序必须为这些参数传入值,可以通过CallableStatement的setXxx()方法为传入参数设置值;所谓传出参数就是Java可以通过该参数获取存储过程里的值,CallableStatement需要调用registerOutParameter(int index,int SQLTypes)方法来注册该参数,第二个参数是直接调用Types的类属性便可。

     当设置完传入参数以及传出参数后,便可以调用CallableStatement的execute()方法来执行存储过程了,执行结束后,通过CallableStatement对象的getXxx(int index)方法来获取指定传出参数值。

     下面根据上述的存储过程SQL来进调用存储过程:

    public class JDBC {

       String driver;
       String url;
       String user;
       String password;

    public void callableStatementTest(){
            try{
                String sql = "call add_pro(?,?,?)";
                CallableStatement callableStatement = conn.prepareCall(sql);
                //设置存储过程的传入参数与传出参数
                callableStatement.setInt(1, 4);
                callableStatement.setInt(2, 5);
                callableStatement.registerOutParameter(3,Types.INTEGER);
                
                callableStatement.execute();
                
                //获取并输出存储过程传出参数的值:
                System.out.println("执行结果是:"+callableStatement.getInt(3));
                
            }catch(Exception e){}
        }
        
        Connection conn = null;
        Statement statement = null;
        public JDBC(String paramFile){
            try{
                Properties props = new Properties();
                props.load(new FileInputStream(paramFile));
                driver = props.getProperty("driver");
                url = props.getProperty("Url");
                user = props.getProperty("user");
                password = props.getProperty("password");
                conn =DriverManager.getConnection(url,user,password);
                statement =conn.createStatement();
                
            }catch(Exception e){}
        }
        
        public static void main(String[] args) {
            JDBC jdbc_2 = new JDBC("mysql.properties");
            jdbc_2.callableStatementTest();
        }
    }

     其运行结果为:

    执行结果是:9
  • 相关阅读:
    Codeforces Round #648 (Div. 2).D Solve The Maze
    Codeforces Round #648 (Div. 2).C Rotation Matching
    Codeforces Round #639 (Div. 2).C. Hilbert's Hotel
    C. Linova and Kingdom.Codeforces Round #635 (Div. 2)
    influxDB基本操作(详细)
    influxDB-介绍
    grafana的安装与启动
    104. HttpRequest对象详解
    103. 重定向详解
    102.限制请求的method装饰器:require_http_methods,require_GET,require_POST,require_safe
  • 原文地址:https://www.cnblogs.com/hjlin/p/11440060.html
Copyright © 2011-2022 走看看