JDK6笔记(5)----JDBC4(2)
1、理解Statements
有三种类型的Statements:
1)Statements接口
它通常用于只需不带参数的SQL语句。
2)PreparedStatement
预准备语句是从Statement接口中继承的;PreparedStatement对象在你需要提前建立和编译SQL语句时非常有用。
PreparedStatement对象还接受IN参数,后面将详述它。
3)CallableStatement
CallableStatement是从预准备语句中继承的,并且接受IN和OUT参数。
CallableStatement的主要用途是用于执行数据库存储过程。
2、研究Statement接口
Statement对象通常用于执行普通SQL语句调用,前提是已建立一个连接并且Connection对象存在。
如:
Connection cConn=dsDataSource.getConnection("username","password");
Statement sStatement=cConn.createStatement();
//Execute the following SQL query
ResultSet rsResults=sStatement.executeQuery("SELECT * FROM PLAYBOYS");
while(rsResults.next()){
//Perform operations
}
有以下的方法:
boolean execute(String sql);
boolean execute(String sql, int autoGenKeys);
boolean execute(String sql, int[] columnIndexes);
boolean execute(String sql, String[] columnNames);
int[] executeBatch(); //执行成批的数据库命令,返回更新计算的数组
ResultSet executeQuery(String sql);
int executeUpdate(String sql, int autoGeneratedKeys);
int executeUpdate(String sql, int[] columnIndexes);
int executeUpdate(String sql, String[] columnNames);
总的来说,只有在SQL语句是静态的时候才使用statements。如果含参数,你应该使用预准备语句接口,见下面。
3、PreparedStatement Interface
当你要多次执行SQL语句时,预准备语句是你极好的选择。它提高了程序的efficiency和performance。
PreparedStatement是Statement接口的子类,因此它继承了上面所列的各种方法。
当使用PreparedStatement对象的execute()方法时,你最好不要尝试传递参数到execute()、executeQuery()、executeUpdate()方法中。
1)设置IN参数
PreparedStatement对象向开发者提供了用于SQL语句的内嵌的IN参数。
无论在SQL语句的哪个地方,在PreparedStatement语句执行前,只要IN参数出现了,你都必须在你的应用程序中向IN参数填入一个值。填值使用适当的setter方法。如下:
(1)void setBoolean(int paramIndex, boolean x);
设置IN参数为一个布尔值;
(2)void setDate(int paramIndex, Date x);
设置IN参数为java.sql.Date值;
(3)void setDouble(int paramIndex, double x);
(4)void setFloat(int paramIndex, float x);
(5)void setInt(int paramIndex, int x);
(6)void setLong(int paramIndex, long x);
(7)void setString(int paramIndex, String x);
(8)void clearParameters();
清除通过setter方法设置的参数值的集。
预准备语句接口的典型用法如下:
一个名为CAR的表,定义如下:
CREATE TABLE CAR(
ID INTEGER NOT NULL,
MODEL VARCHAR(28),
MODEL_YEAR VARCHAR(10)
);
相一致的CAR类如下:
public class Car{
Long id;
String model;
String year;
//set 和 get 方法
}
下面,创建一个执行查询的方法,返回匹配你的选择条件的cars集。
public Collection getAllCars(String year){
Collection cars=new ArrayList();
Connection con=null;
PreparedStatement stmt=null;
ResultSet rs=null;
try{
String url="jdbc:derby://localhost:9527/mydb;create=true";
con=DriverManager.getConnection(url,"sa","password");
String sql="SELECT ID,MODEL,MODEL_YEAR FROM CAR WHERE MODEL_YEAR=?";
stmt=con.prepareStatement(sql);
stmt.setString(1,year);
rs=stmt.executeQuery();
把结果保存到对象集中。
while(rs.next()){
System.out.println("result");
Car car=new Car();
long id=rs.getLong("ID");
String model=rs.getString("MODEL");
String modelyear=rs.getString("MODEL_YEAR");
car.setID(id);
car.setModel(model);
car.setYear(modelyear);
cars.add(car);
}
}catch(SQLException e){}
在JDBC4.0中,你可以通过exception chain(例外链)来浏览:
while(ex!=null){
System.out.println("SQLState:"+ex.getSQLState());
System.out.println("Error Code:"+ex.getErrorCode());
System.out.println("Message:"+ex.getMessage());
Throwable t=ex.getCause();
while(t!=null){
System.out.println("Cause:"+t);
t=t.getCause();
}
ex=ex.getNextException();
}
最后是重要的一点,关闭ResultSet,Statement,Connection。
}finally{
try{
if(rs!=null) rs.close();
if(stmt!=null) stmt.close();
if(con!=null) con.close();
}catch(SQLException e){}
}
return cars;
}
总结:上面的代码有很多冗余,在下一节我将讨论两种减少重复代码的方法:Annotation和Hibernate。