Java PreparedStatement

Java PreparedStatementJavaPreparedStatementisjustlikeaStatementandit’spartoftheJavaJDBCFramework.JavaPreparedStatement就像一个Statement,它是JavaJDBCFramework的一部分。ItisusedtoperformcrudoperationswithData…

大家好,又见面了,我是你们的朋友全栈君。

  • Java PreparedStatement is just like a Statement and it’s part of the Java JDBC Framework.

    Java PreparedStatement就像一个Statement,它是Java JDBC Framework的一部分。

  • It is used to perform crud operations with Database. 

    它用于对数据库执行分类操作。

  • PreparedStatement extends the Statement interface.

    PreparedStatement扩展了Statement接口。

  • PreparedStatement is considered as more secure as it supports parameterized queries. PreparedStatement also prevents SQL Injection attacks.

    PreparedStatement支持参数​​化查询,因此被认为更安全。 PreparedStatement还可以防止SQL注入攻击。

  • We can obtain an instance of PreparedStatement by calling the prepareStatement(String query) method of Connection as shown below.

    我们可以通过调用ConnectionprepareStatement(String query)方法来获得PreparedStatement的实例,如下所示。

// Method :public PreparedStatement prepareStatement(String query)throws SQLException{}// Usage :Connection con = DriverManager.getConnection ("jdbc:mysql://localhost:3306/customerdb", "root", "root");PreparedStatement ps = con.prepareStatement("select id, firstname, lastname, email, birthdate from tblcustomer");

PreparedStatement的优势 (PreparedStatement Advantages)

  • PreparedStatement can be used for both parameterized query and normal query.

    PreparedStatement可以用于参数化查询和普通查询。

  • Query Performance of PreparedStatement is better than that of the Statement.

    PreparedStatement的查询性能优于语句的查询性能。

  • An instance of PreparedStatement can be reused to execute the same query with different parameters.

    可以重新使用PreparedStatement实例以执行具有不同参数的同一查询。

  • PreparedStatement saves application from SQL Injection attacks.

    PreparedStatement使应用程序免受SQL Injection攻击。

Java PreparedStatement Hierarchy
Java PreparedStatement Hierarchy
Java PreparedStatement层次结构

PreparedStatement方法 (PreparedStatement Methods)

We can divide the methods into different categories.

我们可以将方法分为不同的类别。

1.执行查询 (1. Executing Query)

  • ResultSet executeQuery(): This method is used perform read operation using PreparedStatement object. It returns an instance of ResultSet is used to get data.

    ResultSet executeQuery() :此方法用于通过PreparedStatement对象执行读取操作。 它返回一个ResultSet的实例,用于获取数据。

  • int executeUpdate(): This method is used to execute insert, delete and update queries. It will return an integer value indicating numbers database row affected by the query.

    int executeUpdate() :此方法用于执行插入,删除和更新查询。 它将返回一个整数值,指示受查询影响的数字数据库行。

2.将参数值传递给查询 (2. Passing Parameter values to Query)

All of the below methods have 2 arguments. 1st argument is Parameter Index and 2nd argument is the Value of Parameter.

以下所有方法都有2个参数。 第一个参数是参数索引,第二个参数是参数值。

  1. void setInt(int parameterIndex, int value): This method sets the Integer value to the specified parameter index.

    void setInt(int parameterIndex,int value) :此方法将Integer值设置为指定的参数索引。

  2. void setShort(int parameterIndex, short value): This method sets the short value to the specified parameter index.

    void setShort(int parameterIndex,short value) :此方法将short值设置为指定的参数索引。

  3. void setLong(int parameterIndex, long value): This method sets the Long value to the specified parameter index.

    setLong(int parameterIndex,long value) :此方法将Long值设置为指定的参数索引。

  4. void setFloat(int parameterIndex, float value): This method sets the Float value to the specified parameter index.

    void setFloat(int parameterIndex,float value) :此方法将Float值设置为指定的参数索引。

  5. void setDouble(int parameterIndex, double value): This method sets the Double value to the specified parameter index.

    void setDouble(int parameterIndex,double value) :此方法将Double值设置为指定的参数索引。

  6. void setBigDecimal(int parameterIndex, BigDecimal value): This method sets the BigDecimal value to the specified parameter index.

    void setBigDecimal(int parameterIndex,BigDecimal value) :此方法将BigDecimal值设置为指定的参数索引。

  7. void setString(int parameterIndex, String value): This method sets the String value to the specified parameter index.

    setString(int parameterIndex,String value) :此方法将String值设置为指定的参数索引。

  8. void setDate(int parameterIndex, Date value): This method sets the Date value to the specified parameter index.

    setDate(int parameterIndex,Date value) :此方法将Date值设置为指定的参数索引。

Note: The parameterIndex value starts from 1 and all of these methods throw SQLException.

注意 :parameterIndex值从1开始,所有这些方法都抛出SQLException

Java PreparedStatement示例 (Java PreparedStatement Example)

We will be using the MySQL database to demonstrate the usage of PreparedSatement. Use below DB scripts to create database, tables and sample data.

我们将使用MySQL数据库来演示PreparedSatement的用法。 使用下面的DB脚本创建数据库,表和示例数据。


create database customerdb;

use customerdb;

create table tblcustomer(
    id integer AUTO_INCREMENT primary key,
    firstname varchar(32),
    lastname varchar(32),
    email varchar(32),
    birthdate datetime
);

insert into tblcustomer (id,firstname,lastname,email,birthdate) values(1,'Ricky','Smith','ricky@google.com','2001-12-10');

Database Connection Information:

数据库连接信息:

Name of MySql Database: customerdb
IP: localhost
Port: 3306
username: root
password: root

MySql数据库名称:customerdb
IP:本地主机
端口:3306
用户名:root
密码:root

Maven Dependency:

Maven依赖关系


<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.48</version>
    </dependency>
</dependencies>

1.使用PreparedStatement获取数据 (1. Get data using PreparedStatement)

In this case, we will fetch the row having specified id from tblcustomer. The Query will return a single row.

在这种情况下,我们将从tblcustomer获取具有指定id的行。 查询将返回单行。


package com.journaldev.examples;

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

public class PreparedStatementDemo {
    public static void main(String[] args) throws Exception {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        int customerId = 1;
        String query = "select id, firstname, lastname, email,     birthdate from tblcustomer where id = ?";
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root");
            ps = con.prepareStatement(query);
            ps.setInt(1, customerId);
            rs = ps.executeQuery();
            while (rs.next()) {
                System.out.println("Id:" + rs.getInt(1));
                System.out.println("First Name:" + rs.getString(2));
                System.out.println("Last Name:" + rs.getString("lastname"));
                System.out.println("Email:" + rs.getString("email"));
                System.out.println("BirthDate:" + rs.getDate("birthdate"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rs.close();
            ps.close();
            con.close();
        }
    }
}

Understanding the execution steps:

了解执行步骤:

Step 1: Loading JDBC Driver.

步骤1:加载JDBC驱动程序。

Class.forName(“com.mysql.jdbc.Driver”) loads jdbc driver into memory.

类。 forName“ com.mysql.jdbc.Driver” )将jdbc驱动程序加载到内存中。

Step 2: Now we need to obtain the Connection object. The following line will do it.

步骤2 :现在我们需要获取Connection对象。 下一行将执行此操作。

DriverManager.getConnection(“<<JDBC Url>>”, “<<Db username>>”, “<<db password>>”);

DriverManager.getConnection( “ << JDBC Url >>”“ << Db用户名>>”“ << db密码>>” );

Step 3: We can obtain instance of PreparedStatement from Connection object. We need to also specify query that we want to execute. e.g.

步骤3:我们可以从Connection对象获取PreparedStatement的实例。 我们还需要指定要执行的查询。 例如

PreparedSatement ps = con.prepareStatement(<<Query>>);

PreparedSatement ps = con.prepareStatement( << Query >> );

PreparedStatement also supports parameterized query.

PreparedStatement还支持参数化查询。

‘?’ is the parameter in the query. The value of this parameter needs to be provided before executing the Query.

‘?’ 是查询中的参数。 在执行查询之前,需要提供此参数的值。

Step 4: Providing Values of query Parameters. There is only one parameter in the above example i.e. id of type integer.

步骤4:提供查询参数的值。 上面的示例中只有一个参数,即整数类型的id。

int customerId = 1;
ps.setInt(1, customerId);
setInt(<<Parameter Number>>,<<Parameter Value>) method has 2 argument.
In the above example, ‘1’ is parameter number and variable customerId is the value of Parameter.

int customerId = 1;
ps.setInt(1,customerId);
setInt(<<参数编号>>,<<参数值>)方法具有2个参数。
在上面的示例中,“ 1”是参数编号,变量customerId是Parameter的值。

Step 5: Executing Query.

步骤5:执行查询。

executeQuery() method of PreparedStatement is used to execute the select query. It will return the instance of ResultSet. If your query if for insert, update or delete purpose then you can use executeUpdate().

PreparedStatement的executeQuery()方法用于执行选择查询。 它将返回ResultSet的实例。 如果查询用于插入,更新或删除,则可以使用executeUpdate()

Step 6: Iterating ResultSet. next() method of ResultSet is used to obtain query output.

步骤6:迭代ResultSet。 ResultSet的next()方法用于获取查询输出。

Step 7: Closing Resources: It’s one of the important steps. Many developers forget to close resources like ResultSet, PreparedStatement, and Connection. It will result in Resource leakage which can bring down your application.

步骤7:关闭资源:这是重要的步骤之一。 许多开发人员忘记关闭诸如ResultSet,PreparedStatement和Connection之类的资源。 这将导致资源泄漏,这可能会使您的应用程序崩溃。

Output of Program:

程序输出:


Id:1
First Name:Ricky
Last Name:Smith
Email:ricky@google.com
BirthDate:2001-12-1

2.使用PreparedStatement插入操作 (2. Insert Operation using  PreparedStatement)

In this example, we will use PreparedStatement to perform insert operation in tblcustomer table.

在此示例中,我们将使用PreparedStatement在tblcustomer表中执行插入操作。


package com.journaldev.examples;

import java.sql.*;
import java.text.SimpleDateFormat;

public class PrepareStatementInsertDemo {
    public static void main(String[] args) throws Exception {
        {
            Connection con = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            String firstname = "matthew";
            String lastname = "wade";
            String email = "matthew@java.com";
            Date birthdate = new Date(new SimpleDateFormat("YYYY-MM-DD").parse("2000-12-12").getTime());
            String query = "insert into tblcustomer (id,firstname,lastname,email,birthdate) values(default,?,?,?,?)";
            try {
                Class.forName("com.mysql.jdbc.Driver");
                con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root");
                ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, firstname);
                ps.setString(2, lastname);
                ps.setString(3, email);
                ps.setDate(4, birthdate);
                int row = ps.executeUpdate();
                System.out.println("No. of Rows inserted:" + row);
                rs = ps.getGeneratedKeys();
                if (rs.next()) {
                    System.out.println("Id of new Customer:" + rs.getInt(1));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                rs.close();
                ps.close();
                con.close();
            }
        }
    }
}

In this example, while creating an instance of PreparedStatement, we have passed 2 arguments. 1st is the query itself and 2nd is “Statement.RETURN_GENERATED_KEYS“, which will help us to get the primary key value of the new row.

在此示例中,在创建PreparedStatement实例时,我们传递了2个参数。 第一个是查询本身, 第二个是“语句。 RETURN_GENERATED_KEYS ”,这将帮助我们获取新行的主键值。

The below code is used to provide parameters for Insert Query.

以下代码用于为插入查询提供参数。


ps.setString(1, firstname);
ps.setString(2, lastname);
ps.setString(3, email);
ps.setDate(4, birthdate);

As stated in the previous program, executeUpdate() method is used to perform the insert operation. It will return the number of rows affected by our query.

如先前程序中所述,executeUpdate()方法用于执行插入操作。 它将返回受我们的查询影响的行数。

Output of Program:

程序输出:


No. of Rows inserted:1
Id of new Customer:2

If you go to DB and execute a select query then you will see the below result.

如果转到DB并执行选择查询,则将看到以下结果。


mysql> use customerdb;

Database changed

mysql> select * from tblcustomer;
+----+-----------+----------+------------------+---------------------+
| id | firstname | lastname | email            | birthdate           |
+----+-----------+----------+------------------+---------------------+
|  1 | Ricky     | Smith    | ricky@google.com | 2001-12-10 00:00:00 |
|  2 | matthew   | wade     | matthew@java.com | 1999-12-26 00:00:00 |
+----+-----------+----------+------------------+---------------------+
2 rows in set (0.00 sec)

3.使用PreparedStatement更新操作 (3. Update Operation using PreparedStatement)

Now we will perform the update operation. We will update the first name and last name of the customer having email “matthew@java.com”. This row was inserted in the previous example.

现在,我们将执行更新操作。 我们将更新电子邮件为“ matthew@java.com”的客户的名字和姓氏。 在上一个示例中插入了该行。


package com.journaldev.examples;

import java.sql.*;

public class PrepareStatementUpdateDemo {
    public static void main(String[] args) throws Exception {
        {
            Connection con = null;
            PreparedStatement ps = null;
            String email = "matthew@java.com";
            String newFirstname = "john";
            String newLastname = "smith";
            String query = "update tblcustomer set firstname = ?,lastname =? where email = ?";
            try {
                Class.forName("com.mysql.jdbc.Driver");
                con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root");
                ps = con.prepareStatement(query);
                ps.setString(1, newFirstname);
                ps.setString(2, newLastname);
                ps.setString(3, email);
                int row = ps.executeUpdate();
                System.out.println("No. of Rows Updated:" + row);
                if (row == 1) {
                    String selectQuery = "select id,firstname,lastname,email,birthdate from tblcustomer where email=?";
                    try (PreparedStatement selStatement = con.prepareStatement(selectQuery);
                    ) {
                        selStatement.setString(1, email);
                        ResultSet rs = selStatement.executeQuery();
                        if (rs.next()) {
                            System.out.println("Id:" + rs.getInt(1));
                            System.out.println("First Name:" + rs.getString(2));
                            System.out.println("Last Name:" + rs.getString("lastname"));
                            System.out.println("Email:" + rs.getString("email"));
                            System.out.println("BirthDate:" + rs.getDate("birthdate"));
                        }
                        rs.close();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                ps.close();
                con.close();
            }
        }
    }
}

Understanding the program:

了解程序:

In the above example, we have 3 parameters in the query. 1st is the new first name, 2nd is new last name and 3rd is the email of the customer.

在上面的示例中,我们在查询中有3个参数。 第一个是新的名字, 第二个是新的名字, 第三个是客户的电子邮件。

The below line of code provides value of this parameter to PreparedStatement.

下面的代码行将此参数的值提供给PreparedStatement。


ps.setString(1, newFirstname);
ps.setString(2, newLastname);
ps.setString(3, email);

executeUpdate() method is used to execute update query. It will return the number of rows updated by the query.

executeUpdate()方法用于执行更新查询。 它将返回查询更新的行数。

Output of Program:

程序输出:


No. of Rows Updated:1
Id:2
First Name:john
Last Name:smith
Email:matthew@java.com
BirthDate:1999-12-26

You can check the update in the database using the SQL query.

您可以使用SQL查询在数据库中检查更新。


mysql> select * from tblcustomer;
+----+-----------+----------+------------------+---------------------+
| id | firstname | lastname | email            | birthdate           |
+----+-----------+----------+------------------+---------------------+
|  1 | Ricky     | Smith    | ricky@google.com | 2001-12-10 00:00:00 |
|  2 | john      | smith    | matthew@java.com | 1999-12-26 00:00:00 |
+----+-----------+----------+------------------+---------------------+
2 rows in set (0.00 sec)

4.使用PreparedStatement删除操作 (4. Delete Operation using PreparedStatement)

Now we will delete customer record having email “matthew@java.com”.

现在,我们将删除电子邮件为“ matthew@java.com”的客户记录。


package com.journaldev.examples;

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

public class PrepareStatementDeleteDemo {
    public static void main(String[] args) throws Exception {
        {
            Connection con = null;
            PreparedStatement ps = null;
            String email = "matthew@java.com";
            String query = "delete from tblcustomer where email = ?";
            try {
                Class.forName("com.mysql.jdbc.Driver");
                con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root");
                ps = con.prepareStatement(query);
                ps.setString(1, email);
                int row = ps.executeUpdate();
                System.out.println("No. of Rows Deleted:" + row);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                ps.close();
                con.close();
            }
        }
    }
}

PreparedStatement中的批处理方法 (Batch Methods in PreparedStatement)

  • void addBatch(): This method used to adds sets of the parameter to this PreparedStatement object’s batch to update multiple rows.

    void addBatch() :此方法用于将参数集添加到此PreparedStatement对象的批处理中以更新多行。

  • int[] executeBatch(): This method executes all the SQL queries from PreparedStatement object’s batch and returns the array of update counts. This method throws a BatchUpdateException if it fails to execute and JDBC driver may or may not continue to process the remaining batch.

    int [] executeBatch() :此方法从PreparedStatement对象的批处理中执行所有SQL查询,并返回更新计数数组。 如果此方法无法执行,并且JDBC驱动程序可能会也可能不会继续处理剩余的批处理,则将抛出BatchUpdateException。

使用PreparedStatement的批量/批量操作 (Batch/Bulk Operation using PreparedStatement)

package com.journaldev.examples;import java.sql.*;import java.text.SimpleDateFormat;public class PrepareStatementBatchDemo {    public static void main(String[] args) throws Exception {        {            Connection con = null;            PreparedStatement ps = null;            ResultSet rs = null;            SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD");            String query = "insert into tblcustomer (id,firstname,lastname,email,birthdate) values(default,?,?,?,?)";            try {                Class.forName("com.mysql.jdbc.Driver");                con = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "root", "root");                ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);                // 1st Insert                ps.setString(1, "Ross");                ps.setString(2, "Southee");                ps.setString(3, "ross@java.com");                ps.setDate(4, new Date(sdf.parse("2000-12-12").getTime()));                ps.addBatch();                // 2nd Insert                ps.setString(1, "Mayank");                ps.setString(2, "Kohli");                ps.setString(3, "mayank@java.com");                ps.setDate(4, new Date(sdf.parse("2005-12-12").getTime()));                ps.addBatch();                // 3rd Insert                ps.setString(1, "Tom");                ps.setString(2, "Patel");                ps.setString(3, "tom@java.com");                ps.setDate(4, new Date(sdf.parse("1995-12-12").getTime()));                ps.addBatch();                // Execution                int[] rows = ps.executeBatch();                for (int row : rows) {                    System.out.println("No. of Rows inserted:" + row);                }                rs = ps.getGeneratedKeys();                while (rs.next()) {                    System.out.println("Id of new Customer:" + rs.getInt(1));                }            } catch (Exception e) {                e.printStackTrace();            } finally {                rs.close();                ps.close();                con.close();            }        }    }}

In the above example, we have inserted 3 records of customers in one batch. It is more effective to insert multiple rows in batch instead of single-row. The addBatch() method adds data in a batch. The executeBatch() executes all the queries in the batch.

在上面的示例中,我们分批插入了3个客户记录。 批量插入多行而不是单行更为有效。 addBatch()方法可批量添加数据。 executeBatch()执行批处理中的所有查询。

Output:

输出:


No. of Rows inserted:1
No. of Rows inserted:1
No. of Rows inserted:1
Id of new Customer:10
Id of new Customer:11
Id of new Customer:12
this link.
链接下载完整的Java项目。

Reference: Java doc

参考Java文档

翻译自: https://www.journaldev.com/37814/java-preparedstatement

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/134720.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • python 列表的基本操作

    python 列表的基本操作列表常用方法:name=['zhangsan','lisi','wangwu','xieqi']name2=[1,2,3,4]

  • 百度分享异步加载问题、分页,无效果解决[通俗易懂]

    百度分享异步加载问题、分页,无效果解决[通俗易懂]使用百度分享的时候,如果所涉及到的html部分是后加载进来的,如ajax等异步请求成功后,加载进来,那么百度分享就有可能出现错误。我在使用的时候,遇到了两个问题。在这里记录一下。1、无法把所需要分享的内容传值到百度分享里。  百度分享的配置里有两个值,bdText,bdDesc,这两个内容,分别分享标题和内容。  内容是异步加载进来的,所以在百度分享相关代码是在加载成功后运

  • Mac新手使用技巧——Mac如何强制关机

    Mac新手使用技巧——Mac如何强制关机一般情况下,Mac电脑是非常稳定的,但是偶尔也会碰到应用程序没有响应或死机的情况,那么我们需要强制关机,Mac如何强制关机呢?一起来看看吧!1.如果是电脑打开了太多的应用程序造成了没有响应,可以按Command+Q来强制退出。2.如果还是没有反应,很多人喜欢像windows电脑那样按电源键5秒进行强制关机。(这其实是有损坏系统文件的风险)3.如果要采用这种强制切断电源的方法,最好是同时按住control+command+电源键,这样也可以强制关闭电脑,并且不会损坏系统。4.一般关机都是点

  • Android开发前景(海洋药物开发前景)

    一、Android的产生过程和发展1.概念:Android是一种基于Linux的自由及开放源代码的操作系统,现在的主要适用范围一般是为移动端设备,如一类安卓手机和平板电脑。最初的安卓系统由Google公司和开放手机联盟领导及开发,2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。第一部Android智能手机发布于2008年10月,随后安卓系统也由手机平台逐渐像像平板电脑以及其他领域扩展。2011年第一季度,Android在全球的市

  • CCriticalSection与CSingleLock

    CCriticalSection与CSingleLockCCriticalSectionAnobjectofclassCCriticalSectionrepresentsa“criticalsection”—asynchronizationobjectthatallowsonethreadatatimetoaccessaresourceorsectionofcode.Criticalse

  • rsyslog日志管理[通俗易懂]

    rsyslog日志管理[通俗易懂]文章目录简介基本维护核心概念实例配置客户端日志服务器输出日志到mysql简介rsyslog是一个快速的日志处理系统,具有卓越的性能和出色的安全性,采用模块化设计,他可以从各种数据源中接收输入、转换数据再将结果输出到指定的位置。他不仅适用于企业,也适用于小型系统。rsyslog是一个c/s架构,既可以作为日志客户端上报日志,也可以作为服务端接收日志rsyslog是模块化设计,因此很多功能需要…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号