Java 数据库编程2---ResultSet接口,PreparedStatement接口,获取PreparedStatement中编译好的SQL语句

使用SQL中的select语句可以查询出数据库的全部结果,在JDBC的操作中数据库的所有查询记录将使用ResultSet进行接收,并使用ResultSet显示内容。
注意:开发中要限制查询数量
在JDBC的查询操作中,因为是将数据库表中的全部查询结果保存在了ResultSet对象中,实际上也就是保存在了内存中,所以如果查询出来的数据总量太大,占满了内存,系统将会出现问题。
上一篇中的全部数据库操作都是更新操作,更新操作使用Statement接口定义的executeUpdate()方法即可完成操作如果要进行数据库查询操作,则可以使用Statement接口定义的executeQuery()方法,executeQuery()方法的返回值类型就是一个ResultSet的对象,此对象中存放了所有的查询结果。ResultSet接口的常用操作方法如下表所示。

序号 方法 描述
1 boolean next() throws SQLException 将光标从当前位置向前移动一行。
2 int getInt(int columnIndex) throws SQLException 获取ResultSet中,当前行上列号为columnIndex的单元格里面的int类型整数
3 int getInt(String columnLabel) 获取ResultSet中,当前行上对应列名为columnLabel的单元格里面的int类型整数。
4 float getFloat(int columnIndex) 获取ResultSet中,当前行中列号为columnIndex的单元格里面的float类型数据。
5 float getFloat(String columnLabel) 获取ResultSet中,当前行中列名称为columnLabel的单元格上的float类型数据。
6 String getString(int columnIndex) 获取ResultSet中,当前行中列序号为columnIndex的单元格里面的字符串。
7 String getString(String columnLabel) 获取ResultSet中,当前行中列名称为columnLabel的单元格里面的字符串。
8 Date getDate(String columnLabel) 获取ResultSet中,当前行中列序号为columnLabel的单元格中的日期对象(java.sql.Date)
9 Date getDate(String columnLabel) 获取ResultSet中,当前行中列名称为columnLabel的单元格中的日期对象(java.sql.Date)

下面把student表中保存的数据提出出来,打印到控制台中。
student表:
student表结构和表中的数据
实例:查询student表中的数据

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

public class SelectDemo1
{
    // 定义MySQL的数据库驱动程序
    public static final String driver = "com.mysql.jdbc.Driver" ;
    // 定义MySQL数据库的连接地址
    public static final String url = "jdbc:mysql://localhost:3306/usersinfo" ;
    // MySQL数据库的连接用户名
    public static final String user = "root" ;
    // MySQL数据库的连接密码
    public static final String password = "root" ;
    public static void main(String[] args) throws SQLException, ClassNotFoundException
    {
        Connection conn = null ;        // 数据库连接
        Statement stmt = null ;     // 数据库的操作对象
        ResultSet rs = null ;       // 保存查询结果
//      学号,姓名性别,专业,年级,出生,课程,成绩
        String sql = "select 学号,姓名,性别,专业,年级,出生,课程,成绩 from student" ;
        System.out.println("执行SQL语句>"+sql);
        Class.forName(driver) ; // 加载驱动程序
        //建立数据库连接
        conn = DriverManager.getConnection(url,user,password) ;
        //实例化Statement操作对象
        stmt=conn.createStatement();
        //执行查询SQL语句,结果放在结果集rs中
        rs=stmt.executeQuery(sql);
        //指针移动到结果集下一行,如果结果集中有下一行就返回true,没有下一行就返回false
        while(rs.next())
        {
            System.out.print("学号:"+rs.getString("学号"));
            System.out.print(" 姓名:"+rs.getString("姓名"));
            System.out.print(" 性别:"+rs.getString("性别"));
            System.out.print(" 专业:"+rs.getString("专业"));
            System.out.print(" 出生:"+rs.getString("出生"));
            System.out.print(" 年级:"+rs.getString("年级"));
            System.out.print(" 课程:"+rs.getString("课程"));
            System.out.print(" 成绩:"+rs.getInt("成绩"));
            System.out.println();
        }
        rs.close();//关闭结果集
        stmt.close();//关闭数据库操作
        conn.close();//关闭数据库连接
    }
}

运行结果:

执行SQL语句>select 学号,姓名,性别,专业,年级,出生,课程,成绩 from student
学号:H1000 姓名:小郭 性别:女 专业:计算机科学与技术 出生:1999 年级:大二 课程:高等数学 成绩:100
学号:H1002 姓名:小王 性别:男 专业:软件工程 出生:1996 年级:大三 课程:高等数学 成绩:100

在执行查询语句时,是将数据库中的查询结果返回到内存中,所以rs.next()的作用是在返回的结果中依次判断有没有下一行,如果有的话返回true,此时可以使用getXxx()语句的形式将内容取出。
提示:ResultSet中的所有数据都可以通过getString()方法取得。
String可以接收表中任意类型的列中的内容,所以在上面的程序中可以全部都使用getString()来获取结果集中的数据。
如果觉得在上面的代码中取出数据是输入列的名称比较麻烦,则可以列的编号采用顺序的形式来取出数据。
把上面的while循环里面的代码改成下面的代码形式即可。

while(rs.next())
{
    System.out.print("学号:"+rs.getString(1));
    System.out.print(" 姓名:"+rs.getString(2));
    System.out.print(" 性别:"+rs.getString(3));
    System.out.print(" 专业:"+rs.getString(4));
    System.out.print(" 出生:"+rs.getString(5));
    System.out.print(" 年级:"+rs.getString(6));
    System.out.print(" 课程:"+rs.getString(7));
    System.out.print(" 成绩:"+rs.getInt(8));
    System.out.println();
}

这两种取出数据的方法的得到的结果都是一样的,明显第二种操作代码更加简洁,所以一般建议使用第二种方式来从结果集中取出数据。完整代码如下。
实例:通过列编号从结果集中取出数据

package my.select;

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

public class SelectDemo2
{
    // 定义MySQL的数据库驱动程序
    public static final String driver = "com.mysql.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    public static final String url = "jdbc:mysql://localhost:3306/usersinfo";
    // MySQL数据库的连接用户名
    public static final String user = "root";
    // MySQL数据库的连接密码
    public static final String password = "root";

    public static void main(String[] args) throws SQLException, ClassNotFoundException
    {
        Connection conn = null; // 数据库连接
        Statement stmt = null; // 数据库的操作对象
        ResultSet rs = null; // 保存查询结果
        // 学号,姓名性别,专业,年级,出生,课程,成绩
        String sql = "select 学号,姓名,性别,专业,年级,出生,课程,成绩 from student";
        System.out.println("执行SQL语句>" + sql);
        Class.forName(driver); // 加载驱动程序
        // 建立数据库连接
        conn = DriverManager.getConnection(url, user, password);
        // 实例化Statement操作对象
        stmt = conn.createStatement();
        // 执行查询SQL语句,结果放在结果集rs中
        rs = stmt.executeQuery(sql);
        // 指针移动到结果集下一行,如果结果集中有下一行就返回true,没有下一行就返回false
        // while(rs.next())
        // {
        // System.out.print("学号:"+rs.getString("学号"));
        // System.out.print(" 姓名:"+rs.getString("姓名"));
        // System.out.print(" 性别:"+rs.getString("性别"));
        // System.out.print(" 专业:"+rs.getString("专业"));
        // System.out.print(" 出生:"+rs.getString("出生"));
        // System.out.print(" 年级:"+rs.getString("年级"));
        // System.out.print(" 课程:"+rs.getString("课程"));
        // System.out.print(" 成绩:"+rs.getInt("成绩"));
        // System.out.println();
        // }
        while (rs.next())
        {
            System.out.print("学号:" + rs.getString(1));
            System.out.print(" 姓名:" + rs.getString(2));
            System.out.print(" 性别:" + rs.getString(3));
            System.out.print(" 专业:" + rs.getString(4));
            System.out.print(" 出生:" + rs.getString(5));
            System.out.print(" 年级:" + rs.getString(6));
            System.out.print(" 课程:" + rs.getString(7));
            System.out.print(" 成绩:" + rs.getInt(8));
            System.out.println();
        }

        rs.close();// 关闭结果集
        stmt.close();// 关闭数据库操作
        conn.close();// 关闭数据库连接
    }
}

运行结果还是和上面的一样的,都是:

执行SQL语句>select 学号,姓名,性别,专业,年级,出生,课程,成绩 from student
学号:H1000 姓名:小郭 性别:女 专业:计算机科学与技术 出生:大二 年级:1999 课程:高等数学 成绩:100
学号:H1002 姓名:小王 性别:男 专业:软件工程 出生:大三 年级:1996 课程:高等数学 成绩:100

疑惑点:上面的代码SQL语句中为什么不用 select * from student
如果直接使用select * from student方式不是更加简单吗?为什么还要明确的写出所有的列名来查询。
答:
直接写成按”*“形式,查询出所有列中的数据,本身没有任何问题,但是这样一来从查询语句上就很难看出所要查的具体列是什么,在使用ResultSet取出内容时会比较麻烦,所以在开发中建议不要使用”*“的方式查询。
实例:使用select * from student;

package my.select;

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

public class SelectDemo3
{
    // 定义MySQL的数据库驱动程序
    public static final String driver = "com.mysql.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    public static final String url = "jdbc:mysql://localhost:3306/usersinfo";
    // MySQL数据库的连接用户名
    public static final String user = "root";
    // MySQL数据库的连接密码
    public static final String password = "root";

    public static void main(String[] args) throws SQLException, ClassNotFoundException
    {
        Connection conn = null; // 数据库连接
        Statement stmt = null; // 数据库的操作对象
        ResultSet rs = null; // 保存查询结果
        String sql = "select * from student";
        System.out.println("执行SQL语句>" + sql);
        Class.forName(driver); // 加载驱动程序
        // 建立数据库连接
        conn = DriverManager.getConnection(url, user, password);
        // 实例化Statement操作对象
        stmt = conn.createStatement();
        // 执行查询SQL语句,结果放在结果集rs中
        rs = stmt.executeQuery(sql);
        while (rs.next())
        {
            System.out.print("学号:" + rs.getString(1));
            System.out.print(" 姓名:" + rs.getString(2));
            System.out.print(" 性别:" + rs.getString(3));
            System.out.print(" 专业:" + rs.getString(4));
            System.out.print(" 出生:" + rs.getString(5));
            System.out.print(" 年级:" + rs.getString(6));
            System.out.print(" 课程:" + rs.getString(7));
            System.out.print(" 成绩:" + rs.getInt(8));
            System.out.println();
        }
        rs.close();// 关闭结果集
        stmt.close();// 关闭数据库操作
        conn.close();// 关闭数据库连接
    }
}

运行结果与上面一致。

PreparedStatement接口

PreparedStatement接口简介
PreparedStatement接口是Statement接口的子接口,属于预处理操作,与直接使用Statement不同的是PerpareStatement在操作,显示在数据表中准备好一条SQL语句,但是此SQL语句的具体内容暂时不设置,而是之后再进行设置。以插入数据为例,使用PreparedStatement插入数据是,数据表中的指针首先指向最后一条数据之后,但是里面的内容时不知道的,而是等待用户分别设置。
提示:关于预处理的解释
预处理的操作实际上与实际生活中的占座的道理是一样的,A帮B占座,但是此时B又没有来,但是不管B是否来,A都会先把这个座位先占着,等待B的到来。
由于PreparedStatement对象已经预编译过了,所以其执行速度要高于Statement对象,因此对于需要多次执行的SQL语句经常使用PreparedStatement对象操作,以提高效率。
在PreparedStatement中执行的SQL语句与之前的并没有什么不同,但是具体内容是采用”?“的占位符形式出现的,设置时,要按照”?“的顺序设置具体的内容。
PreparedStatement处理继承Statement的所有操作之外,自己还增加了许多新的操作。下面先来介绍PreparedStatement的基本方法。

序号 方法 描述
1 int executeUpdate() 执行设置的预处理SQL,它必须是一个SQL数据操纵语言(DML)语句,如INSERT , UPDATE或DELETE ; 或不返回任何内容的SQL语句,例如DDL语句。
2 ResultSet executeQuery() 执行此 PreparedStatement对象中的SQL查询,返回ResultSet。
3 void setInt(int parameterIndex, int x) 找到要设置的索引编号,并设置整数内容
4 void setFloat(int parameterIndex, float x) 找打要设置的索引编号,并设置浮点数内容
5 void setString(int parameterIndex, String x) 找到要设置的索引编号,并设置字符串内容
6 void setDate(int parameterIndex, Date x) 找到要设置的索引编号,并设置java.sql.Date类型的日期内容。

上面的方法中要注意void setDate(int parameterIndex, Date x)方法,这个方法可以设置日期内容,但是使用时,后面的Date类型变量是java.sql.Date,而不是java.util.Date,所以如果要将一个java.util.Date类型的内容应该使用如下的语句形式:

//把java.util.Date类型的日期,转换成java.sql.Date类型的日期
java.util.Date temp = null;
//实例化java.util.Date
temp = new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
//把java.util.Date转为时间戳,然后再把时间戳,转成java.sql.Date类型。
java.sql.Date bir = new java.sql.Date(temp.getTime());

使用PerparedStatement执行数据库操作

上面的student表中并没用Date类型的列,这里建立一个新的表test:

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` varchar(20) NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `sex` varchar(4) DEFAULT NULL,
  `grade` varchar(10) DEFAULT NULL,
  `major` varchar(40) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

如下图所示:
新建的test表
下面对test表进行操作。

实例:使用PerparedStatement完成数据插入操作

package my.preparedstatement;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.text.SimpleDateFormat;

public class PreparedStatementDemo01
{
    // 定义MySQL的数据库驱动程序
    public static final String diver = "com.mysql.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    public static final String url = "jdbc:mysql://localhost:3306/usersinfo";
    // MySQL数据库的连接用户名
    public static final String user = "root";
    // MySQL数据库的连接密码
    public static final String password = "root";

    public static void main(String args[]) throws Exception
    { // 所有异常抛出
        Connection conn = null; // 数据库连接
        PreparedStatement pstmt = null; // 数据库操作
        String id="H1000";
        String name="小明";
        String sex="男";
        String grade="大三";
        String major="计算机科学与技术";
        String birthday = "2007-08-27"; // 生日

//把java.util.Date类型的日期,转换成java.sql.Date类型的日期
java.util.Date temp = null;
//实例化java.util.Date
temp = new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
//把java.util.Date转为时间戳,然后再把时间戳,转成java.sql.Date类型。
java.sql.Date bir = new java.sql.Date(temp.getTime());



//      id,name,sex,grade,major,birthday
        String sql = "insert into test(id,name,sex,grade,major,birthday) values (?,?,?,?,?,?) ";
        // 加载驱动程序
        Class.forName(diver); 
        //建立数据库连接
        conn = DriverManager.getConnection(url, user, password);
        // 实例化PreapredStatement(预编译操作对象)
        pstmt = conn.prepareStatement(sql); 
        pstmt.setString(1, id);
        pstmt.setString(2, name);
        pstmt.setString(3, sex);
        pstmt.setString(4, grade);
        pstmt.setString(5, major);
        pstmt.setDate(6, bir);
        //查看编译的SQL
        String toString=pstmt.toString();
        System.out.println(toString);
        //获取PrepareStatement里面编译好的SQL语句
        String preSQL=toString.substring(toString.lastIndexOf(":")+1);
        System.out.println(preSQL);

        //执行PreparedStatement操作里面的SQL
        int t = pstmt.executeUpdate(); // 执行更新

        System.out.println(t);
        pstmt.close();
        conn.close(); // 数据库关闭
    }
}

运行结果

  • 控制台输出:
com.mysql.jdbc.JDBC4PreparedStatement@7a07c5b4: insert into test(id,name,sex,grade,major,birthday) values ('H1000','小明','男','大三','计算机科学与技术','2007-08-27') 
 insert into test(id,name,sex,grade,major,birthday) values ('H1000','小明','男','大三','计算机科学与技术','2007-08-27') 
1
  • test表中的数据
    插入一条记录后的test表
    可以看到已经成功插入一条记录了。
    从上面的程序中可以发现,预处理就是使用”?“进行占位的,如下所示:
insert into test(id,name,sex,grade,major,birthday) values (?,?,?,?,?,?)

每一”?”对应一个具体的字段,在设置时,按照”?“的顺序设置即可,在上面的SQL语句中第一个”?“对应的是id的内容,第二个”?“对应的是name的内容。

使用PreparedStatement进行数据库查询操作

下面将使用模糊查询里查询数据库,为了更好的显示效果,在test表中多加入几条记录。
现在的test表中的数据为:
test表中的数据
重建test表的sql语句:

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` varchar(20) NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `sex` varchar(4) DEFAULT NULL,
  `grade` varchar(10) DEFAULT NULL,
  `major` varchar(40) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

INSERT INTO `test` VALUES ('B1000', '张三', '男', '大三', '计算机科学与技术', '2007-08-27');
INSERT INTO `test` VALUES ('B1001', '李四', '男', '大三', '计算机科学与技术', '2007-08-27');
INSERT INTO `test` VALUES ('B1002', '小赵', '男', '大三', '计算机科学与技术', '2007-08-27');
INSERT INTO `test` VALUES ('B1003', '小钱', '男', '大三', '计算机科学与技术', '2007-08-27');
INSERT INTO `test` VALUES ('H1000', '小明', '男', '大三', '计算机科学与技术', '2007-08-27');
INSERT INTO `test` VALUES ('H1001', '小芳', '男', '大三', '计算机科学与技术', '2007-08-27');

下面要求使用模糊查询,选出学号中有字母”B“,或者名字里带的学生的信息

从PreparedStatement实例中提取编译好的SQL语句

PreparedStatement接口提供编译好的SQL语句,但是有时候我们想看看编译好的SQL语句的具体内容怎么办,这个时候就可以直接调用PreparedStatement的toString()方法,就可看到PreparedStatement实例中编译好的SQL语句。

System.out.println(pre.toString());//pre是PreparedStatement的一个实例

运行结果:

com.mysql.jdbc.JDBC4PreparedStatement@31221be2: select id,name,sex,grade,major,birthday from test where id like '%B%' or name like '%小%'

不过打印的字符串太长了,有好多不需要的东西。下面提供一个方法来实现。

/**
     * 从PreparedStatement中取出SQL语句字符串。
     * 
     * @param pre
     *            PreparedStatement对象,该对象中存放中预编译的SQL语句
     * @return SQL语句。
     */
    private static String getSQLString(PreparedStatement pre)
    {
        String toString = pre.toString();
        return toString.substring(toString.lastIndexOf(":") + 1).trim();
    }

调用方式:

System.out.println("SQL语句-->"+getSQLString(pre));

运行结果:

SQL语句-->select id,name,sex,grade,major,birthday from test where id like '%B%' or name like '%小%'

上述getSQLString(PreparedStatement pre)方法的具体用法,请看下面的实例。

实例:使用模糊查询查询数据库

package my.preparedstatement;

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

public class PreparedStatementDemo2
{
    //数据库驱动
    public static final String driver="com.mysql.jdbc.Driver";
    //url: 协议名:子协议名:数据库地址(ip地址:端口号/数据库名)
    public static final String url="jdbc:mysql://localhost:3306/usersinfo";
    //设置用户名
    public static final String user="root";
    //设置密码
    public static final String password="root";

    public static void main(String[] args) throws ClassNotFoundException, SQLException
    {
        //数据库连接引用
        Connection con=null;
        //定义数据库预编译操作引用
        PreparedStatement pre=null;
        String sql="select id,name,sex,grade,major,birthday from test "
                + "where id like ? or name like ?";
        String idmode="B";
        String namemode="小";
        //加载数据库驱动
        Class.forName(driver);
        //取得数据库连接
        con=DriverManager.getConnection(url,user,password);
        //实例化预编译数据库操作对象
        pre=con.prepareStatement(sql);
        //设置第一个占位符
        pre.setString(1, "%"+idmode+"%");
        //设置第二个占位符
        pre.setString(2, "%"+namemode+"%");
        //执行编译好的查询操作,结果反倒ResultSet中
        System.out.println("SQL语句-->"+getSQLString(pre));
        ResultSet rs=pre.executeQuery();
        //如果结果集中有下一个元素
        while(rs.next())
        {
            System.out.print("学号:"+rs.getString(1)+",");
            System.out.print("姓名:"+rs.getString(2)+",");
            System.out.print("性别:"+rs.getString(3)+",");
            System.out.print("年级:"+rs.getString(4)+",");
            System.out.print("专业:"+rs.getString(5)+",");
            System.out.print("出生日期:"+rs.getString(6));
            System.out.println();
        }
    }
    /**
     * 从PreparedStatement中取出SQL语句字符串。
     * @param pre PreparedStatement对象,该对象中存放中预编译的SQL语句
     * @return SQL语句。
     */
    private static String getSQLString(PreparedStatement pre)
    {
        String toString=pre.toString();
        return toString.substring(toString.lastIndexOf(":")+1).trim();
    }

}

运行结果:

SQL语句-->select id,name,sex,grade,major,birthday from test where id like '%B%' or name like '%小%'
学号:B1000,姓名:张三,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:B1001,姓名:李四,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:B1002,姓名:小赵,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:B1003,姓名:小钱,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:H1000,姓名:小明,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:H1001,姓名:小芳,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27

以上程序中使用了模糊查询,在模糊查询中使用了”%“表示通配符,这个统配符在设置具体查询内容(setXxx()方法调用)时才使用。

使用PrepareStatement查询全部数据

如果要查询表中的全部数据,则不用需要使用占位符”?“,也就不需要再使用setXxx()方法来设置占位符了。如下所示:

//查询全部数据,也就不用再使用占位符
String sql = "select id,name,sex,grade,major,birthday from test";
// 加载数据库驱动
Class.forName(driver);
// 取得数据库连接
con = DriverManager.getConnection(url, user, password);
// 实例化预编译数据库操作对象
pre = con.prepareStatement(sql);
// 执行编译好的查询操作,结果反倒ResultSet中
System.out.println("SQL语句-->" + getSQLString(pre));
//没有使用占位符,也就不用再设置占位符了,现在的用法跟Statement方式一样。
ResultSet rs = pre.executeQuery();

完整的代码如下:

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

public class PrepareStatementDemo03
{
    // 数据库驱动
    public static final String driver = "com.mysql.jdbc.Driver";
    // url: 协议名:子协议名:数据库地址(ip地址:端口号/数据库名)
    public static final String url = "jdbc:mysql://localhost:3306/usersinfo";
    // 设置用户名
    public static final String user = "root";
    // 设置密码
    public static final String password = "root";

    public static void main(String[] args) throws ClassNotFoundException, SQLException
    {
        // 数据库连接引用
        Connection con = null;
        // 定义数据库预编译操作引用
        PreparedStatement pre = null;
        String sql = "select id,name,sex,grade,major,birthday from test";
        // 加载数据库驱动
        Class.forName(driver);
        // 取得数据库连接
        con = DriverManager.getConnection(url, user, password);
        // 实例化预编译数据库操作对象
        pre = con.prepareStatement(sql);
        // 执行编译好的查询操作,结果反倒ResultSet中
        System.out.println("SQL语句-->" + getSQLString(pre));
        ResultSet rs = pre.executeQuery();
        // 如果结果集中有下一个元素
        while (rs.next())
        {
            System.out.print("学号:" + rs.getString(1) + ",");
            System.out.print("姓名:" + rs.getString(2) + ",");
            System.out.print("性别:" + rs.getString(3) + ",");
            System.out.print("年级:" + rs.getString(4) + ",");
            System.out.print("专业:" + rs.getString(5) + ",");
            System.out.print("出生日期:" + rs.getString(6));
            System.out.println();
        }
    }

    /**
     * 从PreparedStatement中取出SQL语句字符串。
     * 
     * @param pre
     *            PreparedStatement对象,该对象中存放中预编译的SQL语句
     * @return SQL语句。
     */
    private static String getSQLString(PreparedStatement pre)
    {
        String toString = pre.toString();
        return toString.substring(toString.lastIndexOf(":") + 1).trim();
    }
}

运行结果:

SQL语句-->select id,name,sex,grade,major,birthday from test
学号:B1000,姓名:张三,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:B1001,姓名:李四,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:B1002,姓名:小赵,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:B1003,姓名:小钱,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:H1000,姓名:小明,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27
学号:H1001,姓名:小芳,性别:男,年级:大三,专业:计算机科学与技术,出生日期:2007-08-27

test表中的数据:
此时test表中的数据

到底使用Statement还是PreparedStatement

这两个对象的操作目的都是一样的,那么开发中到底使用哪一个更好呢。
回答:
在开发中很少使用Statement对象进行操作,因为Statement执行的是一个完整的SQL语句,这样在程序用往往要使用拼接的SQL语句完成,而且此时由用户自己输入数据,往往会出现非法字符而造成程序出错,也可能引起系统的安全漏洞,所以开发中不建议只用Statement操作,而是使用PreparedStatement完成操作。

猜你喜欢

转载自blog.csdn.net/qq_21808961/article/details/80947773