您的当前位置:首页正文

JDBC中PrepareStatement 和Statement

2023-11-13 来源:要发发知识网

在执行SQL命令时,我们有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象。无论多少次地使用同一个SQL命令,PreparedStatement都只对它解析和编译一次。当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译。

第一:

prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。

Statement不会初始化,没有预处理,没次都是从0开始执行SQL.

第二:

prepareStatement可以替换变量 :

在SQL语句中可以包含,可以用ps=conn.prepareStatement("select * from Cust where ID=?");      int sid=1001; 

ps.setInt(1, sid);     rs = ps.executeQuery();     可以把?替换成变量。     而Statement只能用     int sid=1001;     Statement stmt = conn.createStatement();     ResultSet rs = stmt.executeQuery("select * from Cust where ID="+sid);     来实现。使用PrepareStatement 和Statement的区别:

1.statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得, preparedstatement支持批处理,对于批量处理可以大大提高效率. 

2.在对数据库只执行一次性存取的时侯,可以优先使用 Statement 对象进行处理。因为PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。

3.当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度。

这种转换也给你带来很大的便利,不必重复SQL语句的句法,而只需更改其中变量的值,便可重新执行SQL语句。选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出它预编译的优越性。

4.在Oracle环境中,开发人员实际上有更大的灵活性。当使用Statement或PreparedStatement对象时,Oracle数据库会缓存SQL语句以便以后使用。在一些情况下,由于驱动器自身需要额外的处理和在Java应用程序和Oracle服务器间增加的网络活动,执行PreparedStatement对象实际上会花更长的时间。然而,除了缓冲的问题之外,至少还有一个更好的原因使我们在企业应用程序中更喜欢使用PreparedStatement对象,那就是安全性。传递给PreparedStatement对象的参数可以被强制进行类型转换,使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。

PrepareStatement和Statement在实际应用中该如何选择?

1.优先选择使用Statement而不是PreparedStatement对象:

JDBC驱动的最佳化是基于使用的是什么功能. 选择PreparedStatement还是Statement取决于你要怎么使用它们. 对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的.

PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行. 例如, 假设我使用Employee ID, 使用prepared的方式来执行一个针对Employee表的查询. JDBC驱动会发送一个网络请求到数据解析和优化这个查询. 而执行时会产生另一个网络请求.在JDBC驱动中,减少网络通讯是最终的目的. 如果我的程序在运行期间只需要一次请求, 那么就使用Statement. 对于Statement, 同一个查询只会产生一次网络到数据库的通讯.

2.使用PreparedStatement的Batch功能

Update大量的数据时, 先Prepare一个INSERT语句再多次的执行, 会导致很多次的网络连接. 要减少JDBC的调用次数改善性能, 你可以使用PreparedStatement的AddBatch()方法一次性发送多个查询给数据库. 让我们来比较一下下面的例子.

例 1: 多次执行PreparedStatement,多次数据库请求(网络请求)

1 PreparedStatement ps = conn.prepareStatement(  2    "INSERT into employees values (?, ?, ?)");   3 for (n = 0; n < 100; n++) {   4    ps.setString(name[n]);  5    ps.setLong(id[n]);  6    ps.setInt(salary[n]);  7    ps.executeUpdate();  8 }  

例 2: 使用Batch,以此请求执行多条

1 PreparedStatement ps = conn.prepareStatement(  2    "INSERT into employees values (?, ?, ?)");  3 for (n = 0; n < 100; n++) {  4 ps.setString(name[n]);  5 ps.setLong(id[n]);  6 ps.setInt(salary[n]);  7 ps.addBatch();  8 }  9 ps.executeBatch();  

分析:

在例 1中, PreparedStatement被用来多次执行INSERT语句. 在这里, 执行了100次INSERT操作, 共有101次网络往返.其中,1次往返是预储PreparedStatement, 另外100次往返执行每个迭代.

在例2中, 当在100次INSERT操作中使用addBatch()方法时, 只有两次网络往返.1次往返是预储PreparedStatement, 另一次是执行batch命令. 虽然Batch命令会用到更多的数据库的CPU周期, 但是通过减少网络往返,性能得到提高.记住, JDBC的性能最大的增进是减少JDBC驱动与数据库之间的网络通讯次数.

  注:Oracel 10G的JDBC Driver限制最大Batch size是16383条,如果addBatch超过这个限制,那么executeBatch时就会出现“无效的批值”(Invalid Batch Value) 异常。因此在如果使用的是Oracle10G,在此bug减少前,Batch size需要控制在一定的限度。

同样mysql 5.5.28 批量执行的数据最大限度是多少不清楚,但自己试了1w,2w,3w 都没问题,记得在url 后面添加:rewriteBatchedStatements=true 表示批量插入,如果不添加的话即使使用addbatch() ,executeBatch() 在后台入库的地方还是不会一次请求入库而是多次请求入库。

3.使用有效的getter方法

JDBC提供多种方法从ResultSet中取得数据, 像getInt(), getString(), 和getObject()等等. 而getObject()方法是最泛化了的, 提供了最差的性能。 这是因为JDBC驱动必须对要取得的值的类型作额外的处理以映射为特定的对象. 所以就对特定的数据类型使用相应的方法.

要更进一步的改善性能, 应在取得数据时提供字段的索引号, 例如, getString(1), getLong(2), 和getInt(3)等来替代字段名. 如果没有指定字段索引号, 网络交通不会受影响, 但会使转换和查找的成本增加. 例如, 假设你使用getString("foo") ... JDBC驱动可能会将字段名转为大写(如果需要), 并且在到字段名列表中逐个比较来找到"foo"字段. 如果可以, 直接使用字段索引, 将为你节省大量的处理时间.

例如, 假设你有一个100行15列的ResultSet, 字段名不包含在其中. 你感兴趣的是三个字段 EMPLOYEENAME (字串型), EMPLOYEENUMBER (长整型), 和SALARY (整型). 如果你指定getString(“EmployeeName”), getLong(“EmployeeNumber”), 和getInt(“Salary”), 查询旱每个字段名必须被转换为metadata中相对应的大小写, 然后才进行查找. 如果你使用getString(1), getLong(2), 和getInt(15). 性能就会有显著改善.

4.获取自动生成的键值

有许多数据库提供了隐藏列为表中的每行记录分配一个唯一键值. 很典型, 在查询中使用这些字段类型是取得记录值的最快的方式, 因为这些隐含列通常反应了数据在磁盘上的物理位置. 在JDBC3.0之前, 应用程序只可在插入数据后通过立即执行一个SELECT语句来取得隐含列的值.

例 3: JDBC3.0之前

1 //插入行  2 int rowcount = stmt.executeUpdate (  3    "insert into LocalGeniusList (name) values (‘Karen‘)");  4 // 现在为新插入的行取得磁盘位置 - rowid  5 ResultSet rs = stmt.executeQuery (  6    "select rowid from LocalGeniusList where name = ‘Karen‘");  

这种取得隐含列的方式有两个主要缺点.

第一, 取得隐含列是在一个独立的查询中, 它要通过网络送到服务器后再执行.

第二, 因为不是主键, 查询条件可能不是表中的唯一性ID. 在后面一个例子中, 可能返回了多个隐含列的值, 程序无法知道哪个是最后插入的行的值.

JDBC3.0规范中的一个可选特性提供了一种能力, 可以取得刚刚插入到表中的记录的自动生成的键值. 

例 4: JDBC3.0之后 

1 // 插入行并返回键值 2 int rowcount = stmt.executeUpdate (  3    "insert into LocalGeniusList (name) values (‘Karen‘)", Statement.RETURN_GENERATED_KEYS);  4 // 得到生成的键值 5 ResultSet rs = stmt.getGeneratedKeys (); 

现在, 程序中包含了一个唯一性ID, 可以用来作为查询条件来快速的存取数据行, 甚至于表中没有主键的情况也可以.

这种取得自动生成的键值的方式给JDBC的开发者提供了灵活性, 并且使存取数据的性能得到提升.

Preparestatement 使用的好处:

1、代码的可读性和可维护性.

虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:

1 stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values (‘"+var1+"‘,‘"+var2+"‘,"+var3+",‘"+var4+"‘)");2 3 perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");4 perstmt.setString(1,var1);5 perstmt.setString(2,var2);6 perstmt.setString(3,var3);7 perstmt.setString(4,var4);8 perstmt.executeUpdate();

对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.

2、PreparedStatement尽最大可能提高性能.

每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个 Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同的操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:

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

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

即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次.

当然并不是所有预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句. 3、最重要的一点是极大地提高了安全性.

对于一些恶意语句:String sql = "select * from tb_name where name= ‘"+varname+"‘ and passwd=‘"+varpasswd+"‘";如果我们把[‘ or ‘1‘ = ‘1]作为varpasswd传入进来.因为‘1‘=‘1‘肯定成立,所以可以任何通过验证.

如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.(前提是数据库本身支持预编译,但目前可能没有什么服务端数据库不支持预编译了,只有少数的桌面数据库,就是直接文件访问的那些)只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement, 有可能要对drop,or 1=1;等做费尽心机的判断和过虑.

PreparedStatement最重要的addbatch()结构的使用.

PreparedStatement  的addBatch和executeBatch实现批量添加.

1.建立链接  

Connection    connection =getConnection();

2.不自动 Commit (瓜子不是一个一个吃,全部剥开放桌子上,然后一口舔了)

connection.setAutoCommit(false);   

3.预编译SQL语句,只编译一回哦,效率高啊.(发明一个剥瓜子的方法,以后不要总想怎么剥瓜子好.就这样剥.)

PreparedStatement statement = connection.prepareStatement("INSERT INTO TABLEX VALUES(?, ?)");   

4.来一个剥一个,然后放桌子上

//记录1

statement.setInt(1, 1);    statement.setString(2, "Cujo");    statement.addBatch();   

//记录2

statement.setInt(1, 2);    statement.setString(2, "Fred");    statement.addBatch();   

//记录3

statement.setInt(1, 3);    statement.setString(2, "Mark");    statement.addBatch();   

//批量执行上面3条语句. 一口吞了,很爽

int [] counts = statement.executeBatch();   

//Commit it 咽下去,到肚子(DB)里面

connection.commit();

 

statement 对象的addBatch 和 executeBatch 来实现批量添加:

   stmt.addBatch("update  TABLE1 set 题目="盛夏话足部保健1"   where id="3407"");

stmt.addBatch("update  TABLE1 set 题目="夏季预防中暑膳食1" where id="3408"");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("11","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("12","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("13","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("14","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("15","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("16","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("17","12","13","","")");    stmt.addBatch("INSERT INTO  TABLE1  VALUES("18","12","13","","")");

int [] updateCounts=stmt.executeBatch();

cn.commit();

实例:批量添加

 

 1 public static void insertData(List<Map<String,String>> list,Logger log){ 2 //获取的数据 3 List <Map<String,String>> nlist= list; 4 String upsql="update hrd_staff set position =? where id=?"; 5 Iterator<Map<String,String>> iter= nlist.iterator(); 6 Connection con= Utils.getCon(); 7 int count=0; 8 try { 9 //在批量添加的时候注意事务提交方式10 con.setAutoCommit(false);11 //PreparedStatement方法的使用12 PreparedStatement pstm = con.prepareStatement(upsql);13 while(iter.hasNext()){14 count++;15 Map<String,String> map= iter.next();16 String jon_name= map.get("job_name");17 String uid= map.get("uid");18 pstm.setString(1,jon_name);19 pstm.setString(2,uid);20 //添加到缓存中21 pstm.addBatch();22 // 如果数据量很大,不能一次性批量添加所以我们要分批次添加,这里就是300条一次23 if(count%300==0){24 //持久化25 int []res=pstm.executeBatch();26 //提交事务,持久化数据27 con.commit();28 pstm.clearBatch();29 log.info("300整除插入结果: "+res.length);30 }31 }32 //小于300条的在这里持久化33 int []ress= pstm.executeBatch();34 //事务提交持久化35 con.commit();36 pstm.clearBatch();37 log.info("插入数据结果:"+ress.length);38 } catch (SQLException e) {39 try {40 con.rollback();41 } catch (SQLException e1) {42 // TODO Auto-generated catch block43 e1.printStackTrace();44 }45 e.printStackTrace();46 }finally{47 try {48 if(null!=con){49 con.close();50 con.setAutoCommit(true);51 }52 } catch (SQLException e) {53 // TODO Auto-generated catch block54 e.printStackTrace();55 }56 }57 }

 

我们也要注意事务的设置,不能设置为自动提交,要批量添加后在提交事务

总结:

addBatch() 就是把你的处理内容添加到批处理单元中。即添加到了batch中。你可以循环加入很多,数据库都不会处理,直到调用如下代码executeBatch() 此时,数据库把刚才加到batch中的命令批量处理。

使用批量插入的好处:

当在100次INSERT操作中使用addBatch()方法时, 只有两次网络往返. 1次往返是预储statement, 另一次是执行batch命令. 虽然Batch命令会用到更多的数据库的CPU周期, 但是通过减少网络往返,性能得到提高. 记住, JDBC的性能最大的增进是减少JDBC驱动与数据库之间的网络通讯. 如果没有使用批处理则网络往返101次这样会耗很多时间,自然效率也就一般.

这里要注意:在mysql 下使用批量执行的时候要在,url 后面添加手动设置支持批量添加 实例如下:

String url="jdbc:mysql://localhost:3306/music?rewriteBatchedStatements=true";

默认情况下rewriteBatchedStatements 的值为false 也就是批量添加功能是关闭的,如果使用则要手动开启!

还有就是事务的设置,不能使自动提交,要批量添加后才提交!!!

 

JDBC中PrepareStatement 和Statement

标签:参数   position   桌子   connect   https   安全   color   strong   假设   

小编还为您整理了以下内容,可能对您也有帮助:

JDBC中Statement和PrepareStatement的区别及特性

主要区别:

Statement执行一条sql就得编译一次,PrepareStatement只编译一次;常用后者原因在于参数设置非常方便;执行一条sql就得编译一次,后者只编译一次;还有就是sql放置的位置不同; 常用后者原因在于参数设置非常方便;

特性:

jdbc的api中的主要的四个类之一的java.sql.statement要求开发者付出大量的时间和精力。在使用statement获取jdbc访问时所具有的一个共通的问题是输入适当格式的日期和时间戳:2002-02-05 20:56 或者 02/05/02 8:56 pm。

通过使用java.sql.preparedstatement,这个问题可以自动解决。一个preparedstatement是从 java.sql.connection对象和所提供的sql字符串得到的,sql字符串中包含问号(?),这些问号标明变量的位置,然后提供变量的值, 最后执行语句,例如:

stringsql = "select * from people p where p.id = ? and p.name = ?";

preparedstatement ps = connection.preparestatement(sql);

ps.setint(1,id);

ps.setstring(2,name);

resultset rs = ps.executequery();

使用preparedstatement的另一个优点是字符串不是动态创建的。下面是一个动态创建字符串的例子:

stringsql = "select * from people p where p.i = "+id;

preparedstatement也提供数据库无关性。当显示声明的sql越少,那么潜在的sql语句的数据库依赖性就越小。

由于preparedstatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement。

JDBC中的Statement和PreparedStatement的区别

1、 PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。2、作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法

execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数

3、在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替

Statement.也就是说,在任何时候都不要使用Statement.

基于以下的原因:

一.代码的可读性和可维护性.

虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:

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 对象实例

不用我多说,对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.

二.PreparedStatement尽最大可能提高性能.

语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:

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

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

即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.

当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.

JDBC中的Statement和PreparedStatement的区别

statement是语句,prepared statement是预定义语句。

书写合格的程序代码,是进行程序设计的根本。熟练地掌握了这些内容,在以后的编程中才不会捉襟见肘。编程的语法就像人类语言的语法一样,是用一些词汇和词汇的组织规则来表达自己的。

Visual Basic的程序代码由语句、常数和声明等部分组成。这些语句就叫做statements,使用最频繁的语句是赋值语句,在程序运行的过程中改变对象的属性、变量的值。语法如下:

对象.属性或变量=表达式

赋值语句是把等号右边表达式的值赋给等号左边的变量或对象的属性。

要添加注释,只需要用单引号’作为注释文字的开头。注释符告诉Visual Basic,忽略这个符号后面的内容,这些内容就是代码段中的注释部分,在代码编辑器中以绿色字符显示。

注释可以和语句在同一行,写在语句的后面,也可占据一整行。

可以在代码编辑器中,用续行符(_)把长语句分成几行。使用续行符,在电脑上和打印出来时,代码变得更加易读。

在同一行内,续行符后面不能加注释。续行符也不能把变量名和属性名分隔在两行中。

一行有一个Visual Basic语句,不用像C语言那样,一条语句后面要加一个分号作为语句的终结符,但是也可以把两个或几个语句放在同一行,只是要用冒号把它们分开。但是,为了便于阅读,最好还是一行放一个语句。

java中对数据库的操作Statement和PrepareStatement这两个方法有什么不同?它们是一个类还是一个方法?

它们是JDBC提供的类:statement 与preparestatement 区别 1.

PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度。这种转换也给你带来很大的便利,不必重复SQL语句的句法,而只需要更改其中变量的值,便可重新执行SQL语句。选择 PreParedStatement对象与否,在于相同的句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量不同,如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出她预编译的优越性。 2.prepareStatement是把你的sql语句预先“编译”好,每次只替换定义的变量,

他的作用是减少与数据库的通信量,从而加快执行速度,主要用在循环执行SQL语句 3.

prepareStatement已经予编译,速度比Statement快些

prepareStatement解决有关特殊字符插入到数据库的问题。如(',",),?) 4.

Statement ─ 由方法 createStatement 所创建。Statement 对象用于发送简单的 SQL 语句。 

PreparedStatement ─ 由方法 prepareStatement 所创建。PreparedStatement 对象用于发送带有一个或多个输入参数( IN 参数)的 SQL 语句。PreparedStatement 拥有一组方法,用于设置 IN 参数的值。执行语句时,这些 IN 参数将被送到数据库中。PreparedStatement 的实例扩展了 Statement ,因此它们都包括了 Statement 的方法。PreparedStatement 对象有可能比 Statement 对象的效率更高,因为它已被预编译过并存放在那以供将来使用。 

CallableStatement ─ 由方法 prepareCall 所创建。CallableStatement 对象用于执行 SQL 储存程序 ─ 一组可通过名称来调用(就象函数的调用那样)的 SQL 语句。CallableStatement 对象从 PreparedStatement 中继承了用于处理 IN 参数的方法,而且还增加了用于处理 OUT 参数和 INOUT 参数的方法。 

以下所列提供的方法可以快速决定应用哪个 Connection 方法来创建不同类型的 SQL 语句: 

createStatement 方法用于:

简单的 SQL 语句(不带参数) 

prepareStatement 方法用于: 

带一个或多个 IN 参数的 SQL 语句 

经常被执行的简单 SQL 语句

prepareCall 方法用于: 

调用已储存过程 Statement用法 stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')"); prepareStatement用法

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();

Statement没有设置缓存,prepareStatement有,并且一次性可以插入n个数据 利用PreparedStatement对象提高数据库的总体效率

在使用PreparedStatement对象执行SQL命令时,命令被数据库进行解析和编译,然后被放到命令缓冲区。然后,每当执行同一个 PreparedStatement对象时,它就会被再解析一次,但不会被再次编译。在缓冲区中可以发现预编译的命令,并且可以重新使用。在有大量用户的企业级应用软件中,经常会重复执行相同的SQL命令,使用PreparedStatement对象带来的编译次数的减少能够提高数据库的总体性能。如果不是在客户端创建、预备、执行PreparedStatement任务需要的时间长于Statement任务,我会建议在除动态SQL命令之外的所有情况下使用PreparedStatement对象