源书:《Java高级编程(JDK6.0版)》
读数笔记:现在似乎很少人了解到JDBC4.0的特性,包括内置的映射功能,其实JDBC已经完全可以由个人定制实现ORM。
JDBC的核心接口:
连接 (Connection)
语句 (Statement)
结果集 (ResultSet)
连接Connection
1、使用DriverManager
JDBC4.0规范之前,客户端应用程序通过Class.forName(“…”)来加载Database的驱动程序。现在新的规范要求供应商在被称为META-INF.services/java.sql.Driver的文件中实现jar时标记driver类。在这个文本文件中会有一行指定了实现java.sql.Driver接口的类,也就是具体的驱动类。
2、使用DataSource
现在建立一个连接的首选方法是通过DataSource接口。因为它使得代码更具有移植性,它允许简单的程序维护,同时它还允许Connection对象参与分布式事务管理以及透明连接池操作。当性能是应用程序的主要目标时,连接池就是一个非常好的实现思想。重用Connection对象的能力消除了每有一个连接请求发生时就需要创建一个新的物理连接的情况。分布式事务允许创建可以在健壮企业架构中运行良好的应用程序,在这种体系结构下可能会出现大量的并发数据库任务。
DataSource接口使用Java命名与目录接口(Java Naming and Directory Interface, JNDI)来存储数据源的逻辑名称,而不是使用完全限定的驱动程序名称连接到一个数据源。
DataSource对象非常巧妙的特征之一是它基本上表示的就是一个物理数据源,如果数据源变化了,那么这些变化会自动反映在DataSource对象中,而不需要调用任何代码。
语句Statement
三种主要类型的语句接口,第一种是Statement,当从Statement接口实现创建对象时,这些对象通常用于执行不带任何参数的一般SQL语句。第二种类型的语句是PreparedStatement,它继承于Statement接口,PreparedStatement对象用于需要提前创建和编译SQL语句的情况,PreparedStatement对象也接受IN参数。最后一个类型CallableStatement的语句是CallableStatement,CallableStatement继承于PreparedStatement,它可以接受IN和OUT参数,它的主要目的是执行已存储的数据库过程。
JDBC4.0新内容:导航异常键(SQLException)
// SQLException ex
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();
}
为了了解DBMS使用哪些标量函数,JDBC API在DatabaseMetaData类中提供了几种方法,用于获取一个用逗号分割的可用函数列表。这些方法如下—
Ø String getNumbericFunctions():返回可用于给定数据库的数学函数列表
Ø String getStringFunctions(): 返回可用于给定数据库的字符串操作函数列表
Ø String getSystemFunctions(): 返回可用于给定数据库的系统函数列表
Ø String getTimeDataFunctions():返回可用于给定数据库的时间和日期函数列表
使用批处理更新(Batch Update)
Statement.executeBatch成功执行时,它将返回更新计数值的一个数组,以命令被添加到Statement批处理列表的相同顺序进行排列。数组中的每个条目都将包含如下内容之一:
Ø 一个等于或者大于0的值,这表示命令已经被成功处理,表示执行命令所作用的行数。
Ø 一个Statement.SUCCESS_NO_INFO,它表示特定命令已经被成功处理。然而,它并不会包含有关该命令所作用行数的任意信息。
PreparedStatement对象批处理更新采用与Statement对象批处理更新几乎相同的操作方法,不同之处在于现在需要处理参数化的SQL语句并要在添加批处理命令之前设置每个参数。因此对于每一个命令,在进行PreparedStatement.addBatch调用之前需要设置必要的IN参数。
结果集ResultSet
简而言之,ResultSet对象就是一个创建的Java对象,它包含已执行的一个SQL查询结果,结果是表格的形式。这意味着它们包含列标题、类型和值。所有这些信息可以通过ResultSet或者ResultSetMetaData对象来获得。如何创建ResultSet对象至关重要:
处理结果集时必须知道主要有两个相关领域。第一个领域是如何在结果集中使用游标,游标可以设置为只向前移动或者向前后两个方向移动。第二个领域是数据源的变化如何影响结果集,可以指定一个结果集以了解底层数据源中发生的变化,并使用ResultSet来反映这些变化。
结果集对象ResultSet的常量列表—(通过createStatement指定这些参数)
- TYPE_FORWARD_ONLY: 游标只能向前移动到末尾,同时结果集对于数据源的变化不敏感
- TYPE_SCROLL_INSENSITIVE: 游标可以前后移动并且可以跳转到指定的行,同时结果集对数据源变化不敏感。
- TYPE_SCROLL_SENSITIVE: 游标可以前后移动并且可以跳转到指定的行,同时结果集对数据源的变化敏感。
- CURSOR_READ_ONLY:希望结果集为只读时指定为此常量,不能以编程的形式进行更新。
- CURSOR_URDATABLE: 希望结果集为可更新时指定此常量,能以编程的方式实现更新。
- HOLD_CURSORS_OVER_COMMIT:指定在调用Connection.commit时将不会关闭ResultSet对象,会影响性能。
- CLOSE_CURSORS_AT_COMMIT: 指定在调用Connection.commit时将关闭ResultSet对象,最佳性能。
ResultSet的游标方法— first()、last()、next()、previous()、absolute(int)、beforeFrist()、afterLast()、relative(int)
ResultSet的处理方法— updateRow()、deleteRow()、moveToInsertRow()、insertRow()
高级特性(Advance Feature)
使用Annotation,一个注释是一个说明性编程模型,在此模型中,与一个代码元素关联的注释被用于在运行时注入代码。注释解决方案由两个元素组成:第一个是Query接口的声明,Query接口扩展了java.sql.BaseQuery接口。第二个元素是用于执行查询的QueryObject。
import java.sql.BaseQuery;
import java.sql.DataSet;
import java.sql.Select;
public interface QueryAnnotationExample extends BaseQuery{
@Select(sql=”SELECT ID,MODEL,MODEL YEAR FROM CAR WHERE MODEL YEAR = ?1”)
public DataSet<Car> getCarsModelYear(String year);
}
public void testQueryAnnotation(){
QueryAnnotationExample qae = null;
try{
String url = “jdbc:derby://localhost:1527/wrox;create=true”;
Connection con = DriverManager.getConnection(url, “APP”, ”password”);
qae = con.createQueryObject(QueryAnnotationExample.class);
}catch(SQLException e){
e.printStackTrace();
}
}
Collection<Car> cars = qae.getCarsModelYear(“1999”);
为了使得非同名的数据库字段能够被填充到Java对象的值上,可以增加列名注释:
import java.sql.ResultColumn;
public class Car{
Long id;
String model;
@ResultColumn(name”MODEL YEAR”)
String year;
//……