视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
数据库技术-JDBC中的PreparedStatement和Transaction
2020-11-09 15:45:53 责编:小采
文档


数据库技术-JDBC中的PreparedStatement和Transaction PreparedStatement 首先介绍PreparedStatement: 1、PreparedStatement是一种Statement 2、比父接口提供了更多可以让我们用的方式. prepstmt = conn.prepareStatement(INSERT INTO animal VALUES(?,?,?))

数据库技术-JDBC中的PreparedStatement和Transaction

PreparedStatement
首先介绍PreparedStatement: 1、PreparedStatement是一种Statement 2、比父接口提供了更多可以让我们用的方式. prepstmt = conn.prepareStatement("INSERT INTO animal VALUES(?,?,?)"); prepstmt.setInt(1, 1);
prepstmt.setString(2, "pig");
prepstmt.setInt(3, 10);
prepstmt.execute();
三个? 表示三个占位符,设定三个位置的值。 1表示第一个问号的值,2表示第二个问号的值,3表示第三个问号的值。
可以这样理解: 我首先准备好一条sql语句,这条语句中有三个值等待确定,接下来依次确定三个值的类型和值。
package myjdbc;

import java.sql.*;

public class PreparedJdbc {
	private static String driver = "com.mysql.jdbc.Driver";
	private static String url = "jdbc:mysql://localhost:3308/zoo";
	private static String user = "root";
	private static String password = "123";
	private static Connection conn = null;
	private static PreparedStatement prepstmt = null;
	private static ResultSet rs = null;

	public static void main(String[] args) {
	try {
	Class.forName(driver);
	//
	conn = DriverManager.getConnection(url,user,password);
	prepstmt = conn
	.prepareStatement("INSERT INTO animal VALUES(?,?,?)");
	prepstmt.setInt(1, 1);
	prepstmt.setString(2, "pig");
	prepstmt.setInt(3, 10);
	prepstmt.execute();
	System.out.println("finish!");
	
	
	} catch (ClassNotFoundException e) {
	e.printStackTrace();

	} catch (SQLException e) {
	e.printStackTrace();
	} finally {
	try {
	if (rs != null) {
	rs.close();
	}
	if (prepstmt != null) {
	prepstmt.close();
	}
	if (conn != null) {
	conn.close();
	}
	} catch (Exception e2) {
	// TODO: handle exception
	}
	}
	}
}

MySQL:

Transaction

先举个简单的例子,A账户转账到B账户,一般需要两条sql语句,一条update A账户上的钱,一条update B账户的钱。这两天update语句必须同时执行成功,或者同时不执行成功,不予许出现中间情况,一条成功一条不成功。

这两条语句就构成了transaction。

conn.setAutoCommit(false);//首先设置自动提交false
stmt = conn.createStatement();
stmt.addBatch("insert into animal values (51, '500', 3)");
stmt.addBatch("insert into animal values (52, '500', 4)");
stmt.addBatch("insert into animal values (53, '500', 5)");
stmt.executeBatch();//三条语句批处理
conn.commit();
conn.setAutoCommit(true);//还原默认自动提交true

设置回滚

catch (SQLException e) {
e.printStackTrace();
try {
if (conn != null) {
conn.rollback();
conn.setAutoCommit(true);
}
}

下面代码:

package myjdbc;

import java.sql.*;

public class TestTransaction {

	public static void main(String[] args) {

	Connection conn = null;
	Statement stmt = null;

	try {
	Class.forName("com.mysql.jdbc.Driver");
	conn = DriverManager.getConnection(
	"jdbc:mysql://localhost:3308/zoo", "root", "123");

	conn.setAutoCommit(false);
	stmt = conn.createStatement();
	stmt.addBatch("insert into animal values (51, '500', 3)");
	stmt.addBatch("insert into animal values (52, '500', 4)");
	stmt.addBatch("insert into animal values (53, '500', 5)");
	stmt.executeBatch();
	conn.commit();
	conn.setAutoCommit(true);
	} catch (ClassNotFoundException e) {
	e.printStackTrace();
	} catch (SQLException e) {

	e.printStackTrace();

	try {
	if (conn != null) {
	conn.rollback();
	conn.setAutoCommit(true);
	}
	} catch (SQLException e1) {
	e1.printStackTrace();
	}
	} finally {
	try {
	if (stmt != null)
	stmt.close();
	if (conn != null)
	conn.close();
	} catch (SQLException e) {
	e.printStackTrace();
	}
	}

	}

} 

Mysql:

Words in the end

在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.
基于以下的原因:
一.代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:

stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");

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

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

三.极大地提高了安全性.

Transaction 用在需要同步数据时非常重要,确保在几条批处理语句的同时执行成功。

2014.1.9

下载本文
显示全文
专题