Java 数据库操作

JDBC连接数据库
首先要下载Connector/J地址:http://www.mysql.com/downloads/connector/j/
这是MySQL官方提供的连接方式:
解压后得到jar库文件,需要在工程中导入该库文件
下面是百度经验分享方式,不再介绍
[http://jingyan.baidu.com/article/ca41422fc76c4a1eae99ed9f.html]

JDBC操作数据库步骤:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * 测试使用JDBC连接oracle数据库
 * @author Administrator
 */
public class JDBCDemo {
    public static void main(String[] args){
        try{
            //加载驱动
            /*
             * 当出现了:
             * java.lang.ClassNotFoundException:
             *  oracle.jdbc.driver.OracleDriver
             * 
             * 这个异常时,说明数据库的驱动jar包没有
             * 导入到项目中。 
             * 若导入了jar包还报这个错误,大部分原因是
             * 书写的驱动有错误
             */
            Class.forName("oracle.jdbc.driver.OracleDriver");
            /*
             * 第二步:
             * 通过DriverManager获取数据库连接
             * 注意:
             * 导入的包都在java.sql.*
             * 
             * DriverManager连接ORACLE时的路径格式
             * jdbc:oracle:thin:@<host>:<port>:<sid>
             * 
             * Mysql的路径 端口号通常是:3306
             * jdbc:mysql://<host>:<port>/<dbname>
             */
            Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/test","chuanqi","chuanqi");

            /*
             * 通过Connection创建Statement
             * 用来执行sql语句
             */
            Statement state = conn.createStatement();

            /*
             * 通过Statement执行查询语句
             * 查询emp表中的信息
             * SELECT empno,ename,sal,deptno
             * FROM emp
             */
            String sql = "SELECT empno,ename,sal,deptno " +"FROM emp_fanchuanqi";

            //输出sql,用于检查拼写是否有错误
            System.out.println(sql);
            /*
             * 使用executeQuery来执行DQL语句
             * 并且查询后会得到一个查询结果集
             */
            ResultSet rs = state.executeQuery(sql);
            /*
             * 需要注意的是,ResultSet表示的
             * 是查询结果集,但实际上查询的结果集
             * 在ORACLE数据库服务器上,并没有全部
             * 保存在本地,所以,我们通过ResultSet
             * 的next方法获取下一条记录时,ResultSet
             * 会发送请求至服务端获取数据,若连接已经
             * 关闭,那么会抛出异常。
             */
            while(rs.next()){
                int empno = rs.getInt("empno");
                String ename = rs.getString("ename");
                int sal = rs.getInt("sal");
                int deptno = rs.getInt("deptno");
                System.out.println(
                        empno+","+ename+","+
                        sal+","+deptno);
            }
            //关闭连接
            conn.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

创建一个以JDBC连接数据库的程序,包含7个步骤:
1、加载JDBC驱动程序:
在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)实现。

  try{   
    //加载MySql的驱动类   
    Class.forName("com.mysql.jdbc.Driver") ;   
    }catch(ClassNotFoundException e){   
    System.out.println("找不到驱动程序类 ,加载驱动失败!");   
    e.printStackTrace() ;   
    }   

成功加载后,会将Driver类的实例注册到DriverManager类中。
2、提供JDBC连接的URL
•连接URL定义了连接数据库时的协议、子协议、数据源标识。
•书写形式:协议:子协议:数据源标识
协议:在JDBC中总是以jdbc开始
子协议:是桥连接的驱动程序或是数据库管理系统名称。
数据源标识:标记找到数据库来源的地址与连接端口。

   jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk ;` 

useUnicode=true:表示使Unicode字符集。如果characterEncoding设置为 gb2312或GBK,本参数必须设置为true 。characterEncoding=gbk:字符编码方式。
3、创建数据库的连接
•要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,
该对象就代表一个数据库的连接。
•使用DriverManager的getConnectin(String url , String username ,
String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和
密码来获得。

 //连接MySql数据库,用户名和密码都是root   
     String url = "jdbc:mysql://localhost:3306/test" ;    
     String username = "root" ;   
     String password = "root" ;   
     try{   
    Connection con =    
             DriverManager.getConnection(url , username , password ) ;   
     }catch(SQLException se){   
    System.out.println("数据库连接失败!");   
    se.printStackTrace() ;   
     }   

4、创建一个Statement
•要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
具体的实现方式:

     Statement stmt = con.createStatement() ;   
       PreparedStatement pstmt = con.prepareStatement(sql) ;   
       CallableStatement cstmt =    
                            con.prepareCall("{CALL demoSp(? , ?)}") ;   

5、执行SQL语句
Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate 和execute
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的 语句。

    ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;   
    int rows = stmt.executeUpdate("INSERT INTO ...") ;   
    boolean flag = stmt.execute(String sql) ;  

6、处理结果
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些 行中数据的访问。
• 使用结果集(ResultSet)对象的访问方法获取数据:

    while(rs.next()){   
         String name = rs.getString("name") ;   
    String pass = rs.getString(1) ; // 此方法比较高效   
     }   

(列是从左到右编号的,并且从列1开始)
7、关闭JDBC对象
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:
1、关闭记录集
2、关闭声明
3、关闭连接对象

      if(rs != null){   // 关闭记录集   
        try{   
            rs.close() ;   
        }catch(SQLException e){   
            e.printStackTrace() ;   
        }   
          }   
          if(stmt != null){   // 关闭声明   
        try{   
            stmt.close() ;   
        }catch(SQLException e){   
            e.printStackTrace() ;   
        }   
          }   
          if(conn != null){  // 关闭连接对象   
         try{   
            conn.close() ;   
         }catch(SQLException e){   
            e.printStackTrace() ;   
         }   
          }    

实例应用:

java 链接数据库

package day05;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class FileDemo {
    public static void main(String[] args) {
            System.out.println("Connecting mysql database !");
            Connection conn=null;
            try{
                Class.forName("com.mysql.jdbc.Driver");
                System.out.println("JDBC 加载成功!!!");
            }catch(Exception e){
                System.out.println("JDBC 加载失败!!!");
                e.printStackTrace();
            }

            try{
                conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","jiachangbin1989");
                System.out.println("JDBC 链接成功!!!");
            }catch(Exception e){
                System.out.println("JDBC 链接失败!!!");
                e.printStackTrace();
            }finally{
                try{
                    conn.close();
                    System.out.println("MySQL 数据库关闭成功!!!");
                }catch(Exception e){
                    System.out.println("MySQL 数据库关闭失败!!!");
                    e.printStackTrace();
                }
            }

            System.out.println("程序结束啦");
    }
}

输出为:

Connecting mysql database !
JDBC 加载成功!!!
JDBC 链接成功!!!
MySQL 数据库关闭成功!!!
程序结束啦

Java 对数据库的更新操作

静态输入

package day05;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;


public class FileDemo {
    public static void main(String[] args) {
            System.out.println("Connecting mysql database !");
            Connection conn=null;
            try{
                Class.forName("com.mysql.jdbc.Driver");//首先要加载想要连接的数据库的驱动到JVM
                System.out.println("JDBC 加载成功!!!");
            }catch(Exception e){
                System.out.println("JDBC 加载失败!!!");
                e.printStackTrace();
            }

            Statement stat=null;//声明Statement对象
            String sql="insert into StudentUser(id,name,password,sex,mail,college) values(123456,'小强','xiaoqiang','M','xiaoqiang@163.com','信息学院')";

            try{
                //提供JDBC连接的URL,创建数据库的连接
                conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","jiachangbin1989");
                System.out.println("JDBC 链接成功!!!");

                stat=conn.createStatement();//实例化Statement对象
                stat.executeUpdate(sql);//执行操作
                System.out.println("插入成功!!!");
            }catch(SQLException e){
                System.out.println("JDBC 链接失败!!!");
                e.printStackTrace();
            }finally{
                try{
                    conn.close();//关闭数据库连接
                    System.out.println("MySQL 数据库关闭成功!!!");
                }catch(SQLException e){
                    System.out.println("MySQL 数据库关闭失败!!!");
                    e.printStackTrace();
                }
            }

            System.out.println("程序结束啦");
    }
}

交互式输入

package day05;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class FileDemo {
    public static void main(String[] args) {
            System.out.println("Connecting mysql database !");
            Scanner scan=new Scanner(System.in);

            System.out.println("请输入账号:");
            int id=scan.nextInt();
            String name,password,sex,mail,college;
            System.out.println("\n请输入name:");
            name=scan.next();
            System.out.println("\n请输入password:");
            password=scan.next();
            System.out.println("\n请输入sex:");
            sex=scan.next();
            System.out.println("\n请输入mail:");
            mail=scan.next();
            System.out.println("\n请输入college:");
            college=scan.next();

            Connection conn=null;
            try{
                Class.forName("com.mysql.jdbc.Driver");//首先要加载想要连接的数据库的驱动到JVM
                System.out.println("JDBC 加载成功!!!");
            }catch(Exception e){
                System.out.println("JDBC 加载失败!!!");
                e.printStackTrace();
            }

            Statement stat=null;//声明Statement对象
            String sql="insert into StudentUser(id,name,password,sex,mail,college) values("+id+",'"+name+"','"+password+"','"+sex+"','"+mail+"','"+college+"')";

            try{
                //提供JDBC连接的URL,创建数据库的连接
                conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","jiachangbin1989");
                System.out.println("JDBC 链接成功!!!");

                stat=conn.createStatement();//实例化Statement对象
                stat.executeUpdate(sql);//执行操作
                System.out.println("插入成功!!!");
            }catch(SQLException e){
                System.out.println("JDBC 链接失败!!!");
                e.printStackTrace();
            }finally{
                try{
                    conn.close();//关闭数据库连接
                    System.out.println("MySQL 数据库关闭成功!!!");
                }catch(SQLException e){
                    System.out.println("MySQL 数据库关闭失败!!!");
                    e.printStackTrace();
                }
            }

            System.out.println("程序结束啦");
    }
}

规范写法

package day05;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class FileDemo {
    public static final String DBDRIVER="com.mysql.jdbc.Driver";
    public static final String DBURL="jdbc:mysql://localhost:3306/test";
    public static final String DBUSER="root";
    public static final String DBPASSWORD="jiachangbin1989";

    public static void main(String[] args) {
            System.out.println("Connecting mysql database !");
            Scanner scan=new Scanner(System.in);
            System.out.println("请输入账号:");
            int id=scan.nextInt();
            String name,password,sex,mail,college;
            System.out.println("\n请输入name:");
            name=scan.next();
            System.out.println("\n请输入password:");
            password=scan.next();
            System.out.println("\n请输入sex:");
            sex=scan.next();
            System.out.println("\n请输入mail:");
            mail=scan.next();
            System.out.println("\n请输入college:");
            college=scan.next();

            Connection conn=null;
            try{
                Class.forName(DBDRIVER);//首先要加载想要连接的数据库的驱动到JVM
                System.out.println("JDBC 加载成功!!!");
            }catch(Exception e){
                System.out.println("JDBC 加载失败!!!");
                e.printStackTrace();
            }

            Statement stat=null;//声明Statement对象
            String sql="insert into StudentUser(id,name,password,sex,mail,college) values("+id+",'"+name+"','"+password+"','"+sex+"','"+mail+"','"+college+"')";

            try{
                //提供JDBC连接的URL,创建数据库的连接
                conn=DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD);
                System.out.println("JDBC 链接成功!!!");

                stat=conn.createStatement();//实例化Statement对象
                stat.executeUpdate(sql);//执行操作
                System.out.println("插入成功!!!");
            }catch(SQLException e){
                System.out.println("JDBC 链接失败!!!");
                e.printStackTrace();
            }finally{
                try{
                    conn.close();//关闭数据库连接
                    System.out.println("MySQL 数据库关闭成功!!!");
                }catch(SQLException e){
                    System.out.println("MySQL 数据库关闭失败!!!");
                    e.printStackTrace();
                }
            }

            System.out.println("程序结束啦");
    }
}

接受操作数据库的结果

将查询结果放进ResultSet集中,然后遍历这个集合。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

public class JDBCDemo {
    public static final String DBDRIVER="com.mysql.jdbc.Driver";
    public static final String DBURL="jdbc:mysql://localhost:3306/test";
    public static final String DBUSER="root";
    public static final String DBPASSWORD="jiachangbin1989";
    public static void main(String[] args){
        Connection conn=null;//声明Connection对象
        Statement stat=null;//声明Statement对象
        ResultSet res=null;//声明ResultSet对象
        int count=0;

        String sql="select id,name,password,sex,mail,college from studentuser;";
        try{
            Class.forName(DBDRIVER);//首先要加载想要连接的数据库的驱动到JVM
            System.out.println("JDBC 加载成功!!!");
        }catch(Exception e){
            System.out.println("JDBC 加载失败!!!");
            e.printStackTrace();
        }
        try{
            //提供JDBC连接的URL,创建数据库的连接
            conn=DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD);
            System.out.println("JDBC 链接成功!!!");
            stat=conn.createStatement();//实例化Statement对象
            res=stat.executeQuery(sql);//执行操作,将结果返回给ResultSet实例 
            System.out.println("查询成功!!!");
            while(res.next()){
                count++;
                int id=res.getInt(1);////或者int id=res.getInt("id");
                String name=res.getString(2);
                String password=res.getString(3);
                String sex=res.getString(4);
                String mail=res.getString(5);
                String college=res.getString(6);
                System.out.println(id+"\t"+name+"\t"+password+"\t"+sex+"\t"+mail+"\t\t"+college);
            }
            System.out.println("共查的数据行数为: "+count);
        }catch(SQLException e){
            System.out.println("JDBC 链接失败!!!");
            e.printStackTrace();
        }finally{
            try{
                conn.close();//关闭数据库连接
                System.out.println("MySQL 数据库关闭成功!!!");
            }catch(SQLException e){
                System.out.println("MySQL 数据库关闭失败!!!");
                e.printStackTrace();
            }
        }
        System.out.println("程序结束啦,共查的数据行数为: "+count);
    }
}

预处理操作:PreparedStatement接口
1、Statement对象用于执行不带参数的简单SQL语句。
2、Prepared Statement 对象用于执行预编译SQL语句。
3、Callable Statement对象用于执行对存储过程的调用。
Statement为一条Sql语句生成执行计划,如果要执行两条sql语句
select colume from table where colume=1;
select colume from table where colume=2;
会生成两个执行计划,一千个查询就生成一千个执行计划!

  • 1.PreparedStatement是预编译的,对于批量处理可以大大提高效率.也叫JDBC存储过程
  • 2.使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
  • 3.statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得,preparedstatement支持批处理

preparedstatement

public interface PreparedStatement extends Statement

所以PreparedStatement是Statement子类接口,能够完成Statement的操作。

package preparedstatementDemo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;

public class preparedstatementDemo {
    public static final String DBDRIVER="com.mysql.jdbc.Driver";
    public static final String DBURL="jdbc:mysql://localhost:3306/test";
    public static final String DBUSER="root";
    public static final String DBPASSWORD="jiachangbin1989";

    /**
     * 连接数据库
     */
    public Connection connDatabase(){
        Connection conn=null;//声明Connection对象
        try{
            Class.forName(DBDRIVER);//首先要加载想要连接的数据库的驱动到JVM
            System.out.println("JDBC 加载成功!!!");
        }catch(Exception e){
            System.out.println("JDBC 加载失败!!!");
            e.printStackTrace();
        }
        try{
            //提供JDBC连接的URL,创建数据库的连接
            conn=DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD);
            System.out.println("JDBC 链接成功!!!");
        }catch(SQLException e){
            System.out.println("JDBC 链接失败!!!");
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 使用statement执行SQL语句
     */
    public void statement(){
        Connection conn=null;//声明Connection对象
        Statement stat=null;//声明Statement对象
        try{
            conn=connDatabase();
            stat=conn.createStatement();//实例化Statement对象
            long timel=System.currentTimeMillis();
            for(int i=1;i<50;i++){
                stat.executeUpdate("insert into StudentUser(id,name,password,sex,mail,college) values("+i+",'xiaoqiangq','xiaoqiangq','M','xiaoqiangq@163.com','xxxy')");
            }
            System.out.println("statement耗时 : "+(System.currentTimeMillis()-timel));
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try{
                conn.close();//关闭数据库连接
            }catch(SQLException e){
                System.out.println("MySQL 数据库关闭失败!!!");
                e.printStackTrace();
            }
        }       
    }
    /**
     * 使用PreparedStatement执行SQL语句
     */
    public void preparedStatement(){
        Connection conn=null;//声明Connection对象
        PreparedStatement perstat=null;//声明PreparedStatement对象
        try{
            conn=connDatabase();
            perstat=conn.prepareStatement("insert into StudentUser(id,name,password,sex,mail,college) values(?,'xiaoqiangq','xiaoqiangq','M','xiaoqiangq@163.com','xxxy')");
            long timel=System.currentTimeMillis();
            for(int i=51;i<=100;i++){
                perstat.setInt(1, i);
                perstat.executeUpdate();
            }
            System.out.println("PreparedStatement耗时 : "+(System.currentTimeMillis()-timel));
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try{
                conn.close();//关闭数据库连接
            }catch(SQLException e){
                System.out.println("MySQL 数据库关闭失败!!!");
                e.printStackTrace();
            }
        }       
    }
    public static void main(String[] args){
        preparedstatementDemo per=new preparedstatementDemo();
        per.statement();
        per.preparedStatement();
    }
}

这里写图片描述
preparedStatement的效率明显高于statement。

数据库链接面试题:

比较executeQuery(sql);、executeUpdate(sql);、stat.execute(sql);

首先,用哪一个方法由 SQL 语句所产生的内容决定。
方法executeQuery用于产生单个结果集的语句,例如 SELECT 语句。
方法executeUpdate用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句executeUpdate 的返回值总为零。使用executeUpdate方法是因为在 createTableCoffees 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 更多时间是用于更新表,因为表只需要创建一次,但经常被更新。
方法execute用于执行返回多个结果集、多个更新计数或二者组合的语句。因为多数程序员不会需要该高级功能execute方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。当执行某个已存储过程
或动态执行未知 SQL 字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。因为方法 execute 处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法 execute 执行该过程后,必须调用方法 getResultSet 获得第一个结果集,然后调用适当的 getXXX 方法获取其中的值。要获得第二个结果集,需要先调用 getMoreResults 方法,然后再调用 getResultSet 方法。如果已知某个过程返回两个更新计数,则首先调用方法 getUpdateCount,然后调用 getMoreResults,并再次调用 getUpdateCount。对于不知道返回内容,则情况更为复杂。如果结果是 ResultSet 对象,则方法 execute 返回 true;如果结果是 Java int,则返回 false。如果返回 int,则意味着结果是更新计数或执行的语句是 DDL 命令。在调用方法 execute 之后要做的第一件事情是调用 getResultSet 或 getUpdateCount。调用方法 getResultSet 可以获得两个或多个 ResultSet 对象中第一个对象;或调用方法 getUpdateCount 可以获得两个或多个更新计数中第一个更新计数的内容。

PreparedStatement和Statement的用法区别

1、 PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。
2、作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数。
3、在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.
PreparedStatement可读性和可维护性高

stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");//stmt是Statement对象实例

perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate(); //prestmt是 PreparedStatement 对象实例 

Statement执行SQL语句需要拼接而成,容易产生错误,而使用PreparedStatement则不需要拼接SQL语句,使用?占位符进行占位。
PreparedStatement尽最大可能提高性能
语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配。

insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');

即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。当然并不是所有预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句。
PreparedStatement极大地提高了安全性

String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";

如果我们把[’ or ‘1’ = ‘1]作为varpasswd传入进来.用户名随意,看看会成为什么?

select * from tb_name = '随意' and passwd = '' or '1' = '1';
因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者:
把[';drop table tb_name;]作为varpasswd传入进来,则:
select * from tb_name = '随意' and passwd = '';drop table tb_name;

有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值