以mysql数据库为基础,用junit做jdbc技术之preparestatement的相关测试,以及探讨statement和preparestatement在获取自动增长列的值时和executeBatch操作的区别。
该测试所需的表book和stud,建表语句如下:
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`price` double DEFAULT NULL,
`birth` datetime NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `stud` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`)
);
该测试创建了一个数据库对象,用来操作数据库,附代码:
package com.cw.cw.mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Mysql {
private static final String URL = "jdbc:mysql://localhost:3306/dbgirl";
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String USER = "root";
private static final String PWD = "123456";
public Connection conn = null;
public Statement stmt = null;
public PreparedStatement pstmt = null;
public ResultSet rs = null;
public Mysql() throws SQLException{
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL,USER,PWD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void getStatement() throws SQLException, ClassNotFoundException{
stmt = conn.createStatement();
}
public void getPsStatement(String sql) throws SQLException, ClassNotFoundException{
pstmt = conn.prepareStatement(sql);
}
public void close(){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(pstmt!=null){
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
该测试创建的测试类,附代码:
package com.cw.cw;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import org.junit.Test;
import com.cw.cw.mysql.Mysql;
public class JdbcPrepareStatementTest {
Mysql mysql = null;
public JdbcPrepareStatementTest(){
try {
mysql = new Mysql();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* PrepareStatement的executeQuery
* 不会被黑:如输入name值为: a' or '1'='1
*/
@SuppressWarnings("resource")
@Test
public void test1() throws Exception{
System.out.println("test1");
Scanner sc = new Scanner(System.in);
String id = sc.nextLine();
String name = sc.nextLine();
//创建预处理语句对象
String sql = "select count(*) from stud where id=? and name=? ";//凡是用户输入的地方,用“?”号(称占位符)填入
mysql.getPsStatement(sql);
//给占位设置值---设置参数
mysql.pstmt.setString(1, id); //给第1个参数设置
mysql.pstmt.setString(2, name); //给第2个参数设置
mysql.rs = mysql.pstmt.executeQuery();//这里不能传参数sql
//取一条数据
mysql.rs.next();
int n = mysql.rs.getInt(1);
if(n<=0){
System.out.println("登录失败...");
}else{
System.out.println("登录成功....");
}
mysql.close();
System.err.println("=================================================");
}
/**
* PrepareStatement的executeUpdate
* 能够防护bug:如输入name值为: aa,b'c
*/
@SuppressWarnings("resource")
@Test
public void test2() throws Exception{
System.out.println("test2");
Scanner sc = new Scanner(System.in);
String id = sc.nextLine();
String name = sc.nextLine();
int age = Integer.parseInt(sc.nextLine());
//String sql = "insert into stud values('P2001','kobe',25) ";
String sql = "insert into stud values(?,?,?) ";
mysql.getPsStatement(sql);
mysql.pstmt.setString(1, id);
mysql.pstmt.setString(2, name);
mysql.pstmt.setInt(3, age);
mysql.pstmt.executeUpdate();
mysql.close();
System.err.println("=================================================");
}
/**
* Statement的executeUpdate
* 获取自动增长列的值,报错
*/
@Test
public void test3() throws Exception{
System.out.println("test3");
String sql = "insert into book(name,price,birth) values('三国演义',45.66,'2012-10-18 12:00:05' )";
mysql.stmt.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);
mysql.rs = mysql.stmt.getGeneratedKeys();
if(mysql.rs.next()){
int id = mysql.rs.getInt(1);
System.out.println("自动生成的字段值:"+id);
}
mysql.close();
System.err.println("=================================================");
}
/**
* PrepareStatement的executeUpdate
* 获取自动增长列的值
*/
@Test //获取自动增长列的值--PreparedStatement
public void test4() throws Exception{
System.out.println("test4");
String sql = "insert into book(name,price,birth) values(?,?,'2012-10-18 12:00:05' )";
mysql.pstmt = mysql.conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
mysql.pstmt.setString(1, "水流利");
mysql.pstmt.setDouble(2, 123.23);
mysql.pstmt.executeUpdate();
mysql.rs = mysql.pstmt.getGeneratedKeys();
if(mysql.rs.next()){
int id = mysql.rs.getInt(1);
System.out.println("自动生成的字段值:"+id);
}
mysql.close();
System.err.println("=================================================");
}
/**
* Statement的executeBatch
* executeBatch返回影响的行数
* 执行批处理---自己本身不带事务,如果其中某条sql挂,则后续的sql执行失败,前面的还是有效的。
* 如果要事务,另外再采用:con.setAutoCommit(false)+try-cacth+ rollback/commit
*/
@Test
public void test5() throws Exception{
System.out.println("test5");
String sql = "insert into book(name,price,birth) values('aaa',11.11,'2013-11-28 19:00:15' )";
mysql.getStatement();
for(int i=0;i<5;i++){
if(i==2){
//去掉注释,执行错误,但前面2条sql还是插进去了,后面三条都没有插入进去
// sql = "insert into book(name,price,birth) values('aaa','aa','2013-11-28 19:00:15' )";
}
mysql.stmt.addBatch(sql);
}
sql = "update book set price =price*1.1 where price<30";
mysql.stmt.addBatch(sql);
int a[] = mysql.stmt.executeBatch();
for(int x:a){
System.out.println(x);
}
mysql.close();
System.err.println("=================================================");
}
/**
* prepareStatement的executeBatch
* executeBatch返回影响的行数
* 执行批处理---自己本身不带事务,如果其中某条sql挂,则后续的sql执行失败,前面的还是有效的。
* 如果要事务,另外再采用:con.setAutoCommit(false)+try-cacth+ rollback/commit
*/
@Test //执行批处理---
public void test6() throws Exception{
System.out.println("test6");
String sql = "insert into book(name,price,birth) values(?,?,'2013-11-28 19:00:15' )";
mysql.getPsStatement(sql);
//插入5条,数组a返回两次addBatch后executeBatch所影响的行数
for(int i=0;i<5;i++){
mysql.pstmt.setString(1, "bb"+i);
mysql.pstmt.setDouble(2, 25+i);
mysql.pstmt.addBatch();
}
//去掉注释,执行错误,只有第三条数据没有插入进去,其他4条sql都插进去了,update操作也执行了,但是执行完executeBatch,没有执行数组a的输出,不知为啥???
/*for(int i=0;i<5;i++){
if(i==2){
mysql.pstmt.setString(1, "bb"+i);
mysql.pstmt.setString(2, "bb"+i);
mysql.pstmt.addBatch();
}else{
mysql.pstmt.setString(1, "bb"+i);
mysql.pstmt.setDouble(2, 25+i);
mysql.pstmt.addBatch();
}
}*/
sql = "update book set price =price*1.1 where price<30";
mysql.pstmt.addBatch(sql);
int a[] = mysql.pstmt.executeBatch();
for(int x:a){
System.out.println(x);
}
mysql.close();
System.err.println("=================================================");
System.out.println("junit测试方法执行完毕");
}
}
参考:http://m.blog.csdn.net/jrdgogo/article/details/52212553