DBC成为JAVA类库中最常使用的API之一
5.1 JDBC的设计
JDBC和ODBC都基于同一个思想:根据API编写的程序都可以与驱动管理器进行通信,而驱动管理器则通过驱动程序与实际的数据库进行通信。
5.1 .1 JDBC驱动程序类型
- 将JDBC翻译成ODBC,然后使用一个ODBC驱动城区与数据库进行通信
- 部分Java程序和部分本地代码组成
- 纯Java客户端类库
- 纯Java类库
总之,JDBC是为实现以下目标:
- 通过使用标准的SQL语句,甚至是专门的SQL扩展,程序员就可以利用Java语言开发访问数据库的应用。
- 数据库供应商和数据库工具开发商可以提供底层的驱动程序。
5.1.2 JDBC 典型用法
5.2 结构化查询语言
基于服务器的数据库只能使用SQL来访问。
可以将JDBC包看成是一个用于将SQL语句传递给数据库的API
5.3 JDBC配置
5.3.1 数据库URL
在链接数据库时,我们必须使用各种与数据库类型相关的参数,例如主机名、端口号和数据库名。
下面是URL示例
jdbc:derby://localhost:8080/COREJAVA;create=true
jdbc:postgresql:COREJAVA
JDBC URL一般语法:
jdbc:subprotocol:other staff subprotocol用于选择连接到数据库的具体驱动程序。otherstaff根据subprotocol不同有变化
5.3.2 驱动程序Jar文件
在运行访问数据库的程序时,将驱动程序的jar文件包括到类路径中
当从命令行启动程序时,执行下面的命令:
java -classpath driverpath:ProgramName
在Windows上,使用分号将当前路径与驱动程序JAR文件分隔开
5.3.4 注册驱动器类
ps:有的JAR文件自动注册,可以跳过该步
使用DriverManager,可以使用两种方法注册驱动器,一种方法实在Java程序中加载驱动器
Class.forName("org.postgresql.Driver");
另一种方法是设置jdbc.drivers属性
5.3.5 连接到数据库
例:
package hotel.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* 数据库操作基类
*/
public class BaseDao {
public static String DRIVER; // 数据库驱动
public static String URL ; // url
public static String DBNAME; // 数据库用户名
public static String DBPASS; // 数据库密码
Connection conn = null;// 数据连接对象
static{//静态代码块,在类加载的时候执行
init();
}
/**
* 初始化连接参数,从配置文件里获得
*/
public static void init(){
Properties params=new Properties();
String configFile = "database.properties";//配置文件路径
//加载配置文件到输入流中
InputStream is=BaseDao.class.getClassLoader().getResourceAsStream(configFile);
try {
//从输入流中读取属性列表
params.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//根据指定的获取对应的值
DRIVER=params.getProperty("driver");
URL=params.getProperty("url");
DBNAME=params.getProperty("user");
DBPASS=params.getProperty("password");
}
/**
* 得到数据库连接
*
* @throws ClassNotFoundException
* @throws SQLException
* @return 数据库连接
*/
public Connection getConn() throws ClassNotFoundException, SQLException {
Connection conn = null;
try {
Class.forName(DRIVER); // 注册驱动
Connection cnn=DriverManager.getConnection("jdbc:mysql:"+"//127.0.0.1:3306/haha","","");
conn = DriverManager.getConnection(URL, DBNAME, DBPASS); // 获得数据库连接
} catch (SQLException e) {
e.printStackTrace();
}
return conn; // 返回连接
}
/**
* 释放资源
*
* @param conn
* 数据库连接
* @param pstmt
* PreparedStatement对象
* @param rs
* 结果集
*/
public void closeAll(Connection conn, PreparedStatement pstmt, ResultSet rs) {
/* 如果rs不空,关闭rs */
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/* 如果pstmt不空,关闭pstmt */
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/* 如果conn不空,关闭conn */
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 执行SQL语句,可以进行增、删、改的操作,不能执行查询
*
* @param sql
* 预编译的 SQL 语句
* @param param
* 预编译的 SQL 语句中的‘?’参数的字符串数组
* @return 影响的条数
*/
public int executeSQL(String preparedSql, Object[] param) {
Connection conn = null;
PreparedStatement pstmt = null;
int num = 0;
/* 处理SQL,执行SQL */
try {
conn = getConn(); // 得到数据库连接
pstmt = conn.prepareStatement(preparedSql); // 得到PreparedStatement对象
if (param != null) {
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i + 1, param[i]); // 为预编译sql设置参数
}
}
// System.out.println(preparedSql);
num = pstmt.executeUpdate(); // 执行SQL语句
} catch (ClassNotFoundException e) {
e.printStackTrace(); // 处理ClassNotFoundException异常
} catch (SQLException e) {
e.printStackTrace(); // 处理SQLException异常
} finally {
this.closeAll(conn, pstmt, null);
}
return num;
}
}
package Section5;
import java.sql.*;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() {
try {
Connection conn=getConn();
Statement stat=conn.createStatement();
ResultSet rs= stat.executeQuery("select * from user");
String id=null;
String password=null;
while(rs.next()) {
id=rs.getString("id");
password=rs.getString("password");
System.out.println(id+ " "+ password);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new testDao();
}
}
5.4 使用JDBC语句
5.4.1 执行sql语句
Connection conn=getConn();
Statement stat=conn.createStatement();
ResultSet rs= stat.executeQuery("select * from user");
对于ResultSet接口,迭代器初始化时被设定在第一行之前的位置,必须调用next方法将它移动到第一行。每个访问器都有两种形式,一种接收数字型参数,一种接受字符型参数。
与数组的索引不同,数据库的列号是从一开始的。
当get方法的类型和列型不一致时,每个get方法都会进行合理的类型转换。例如,调用rs.getString("Price")时,该方法将会将Price列的服殿直转换成字符串。
java.sql.Connection:
-
-
Modifier and Type Method and Description void
abort(Executor executor)
终止打开的连接。
void
clearWarnings()
清除为此
Connection
对象报告的所有警告。void
close()
Connection
发布此Connection
对象的数据库和JDBC资源,而不是等待它们自动释放。void
commit()
使自上次提交/回滚以来所做的所有更改都将永久性,并释放此
Connection
对象当前持有的任何数据库锁。Array
createArrayOf(String typeName, Object[] elements)
用于创建Array对象的Factory方法。
Blob
createBlob()
构造实现的对象
Blob
接口。Clob
createClob()
构造实现的对象
Clob
接口。NClob
createNClob()
构造实现的对象
NClob
接口。SQLXML
createSQLXML()
构造实现的对象
SQLXML
接口。Statement
createStatement()
创建一个
Statement
对象,用于将SQL语句发送到数据库。Statement
createStatement(int resultSetType, int resultSetConcurrency)
创建一个
Statement
对象,该对象将生成具有给定类型和并发性的ResultSet
对象。Statement
createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
创建一个
Statement
对象,将产生ResultSet
对象具有给定类型,并发性和可保存性。
-
-
-
Struct
createStruct(String typeName, Object[] attributes)
用于创建Struct对象的工厂方法。
boolean
getAutoCommit()
检索此
Connection
对象的当前自动提交模式。String
getCatalog()
检索此
Connection
对象的当前目录名称。Properties
getClientInfo()
返回包含驱动程序支持的每个客户端信息属性的名称和当前值的列表。
String
getClientInfo(String name)
返回由name指定的客户端信息属性的值。
int
getHoldability()
检索使用此
Connection
对象创建的ResultSet
对象的当前保持性。DatabaseMetaData
getMetaData()
检索
DatabaseMetaData
对象包含有关哪个这个数据库的元数据Connection
对象表示的连接。int
getNetworkTimeout()
检索驱动程序等待数据库请求完成的毫秒数。
String
getSchema()
检索此
Connection
对象的当前模式名称。int
getTransactionIsolation()
获取此
Connection
对象的当前事务隔离级别。Map<String,类<?>>
getTypeMap()
检索
Map
与此相关联的对象Connection
对象。SQLWarning
getWarnings()
检索通过此
Connection
对象的呼叫报告的第一个警告。boolean
isClosed()
检索此
Connection
对象是否已关闭。boolean
isReadOnly()
检索此
Connection
对象是否处于只读模式。boolean
isValid(int timeout)
如果连接尚未关闭并且仍然有效,则返回true。
String
nativeSQL(String sql)
将给定的SQL语句转换为系统的本机SQL语法。
CallableStatement
prepareCall(String sql)
创建一个调用数据库存储过程的
CallableStatement
对象。CallableStatement
prepareCall(String sql, int resultSetType, int resultSetConcurrency)
创建一个
CallableStatement
对象,该对象将生成具有给定类型和并发性的ResultSet
对象。CallableStatement
prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
创建一个
CallableStatement
对象,该对象将生成具有给定类型和并发性的ResultSet
对象。PreparedStatement
prepareStatement(String sql)
创建一个
PreparedStatement
对象,用于将参数化的SQL语句发送到数据库。PreparedStatement
prepareStatement(String sql, int autoGeneratedKeys)
创建一个默认的
PreparedStatement
对象,该对象具有检索自动生成的密钥的能力。PreparedStatement
prepareStatement(String sql, int[] columnIndexes)
创建一个默认的
PreparedStatement
对象,能够返回给定数组指定的自动生成的键。PreparedStatement
prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
创建一个
PreparedStatement
对象,该对象将生成具有给定类型和并发性的ResultSet
对象。PreparedStatement
prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
创建一个
PreparedStatement
对象,将产生ResultSet
对象具有给定类型,并发性和可保存性。PreparedStatement
prepareStatement(String sql, String[] columnNames)
创建一个默认的
PreparedStatement
对象,能够返回给定数组指定的自动生成的键。void
releaseSavepoint(Savepoint savepoint)
删除指定的
Savepoint
和随后Savepoint
从目前的交易对象。void
rollback()
撤消在当前事务中所做的所有更改,并释放此
Connection
对象当前持有的任何数据库锁。void
rollback(Savepoint savepoint)
撤消在给定的
Savepoint
对象设置后进行的所有更改。void
setAutoCommit(boolean autoCommit)
将此连接的自动提交模式设置为给定状态。
void
setCatalog(String catalog)
设置给定的目录名称,以便选择要在其中工作的
Connection
对象的数据库的子空间。void
setClientInfo(Properties properties)
设置连接的客户端信息属性的值。
void
setClientInfo(String name, String value)
将由name指定的客户端信息属性的值设置为由值指定的值。
void
setHoldability(int holdability)
将使用此
Connection
对象创建的ResultSet
对象的默认保持性更改为给定的可保存性。void
setNetworkTimeout(Executor executor, int milliseconds)
设置最大周期a
Connection
或从Connection
创建的Connection
将等待数据库回复任何一个请求。void
setReadOnly(boolean readOnly)
将此连接设置为只读模式,作为驱动程序的提示以启用数据库优化。
Savepoint
setSavepoint()
在当前事务中创建一个未命名的保存点,并返回代表它的新的
Savepoint
对象。Savepoint
setSavepoint(String name)
在当前事务中创建具有给定名称的保存点,并返回代表它的新的
Savepoint
对象。void
setSchema(String schema)
设置要访问的给定模式名称。
void
setTransactionIsolation(int level)
尝试将此
Connection
对象的事务隔离级别更改为给定的对象。void
setTypeMap(Map<String,类<?>> map)
将给定的
TypeMap
对象作为此Connection
对象的类型映射。
-
java.sql.Statement:
-
-
Modifier and Type Method and Description void
addBatch(String sql)
将给定的SQL命令添加到此
Statement
对象的当前命令列表中。void
cancel()
如果DBMS和驱动程序都支持中止SQL语句,则取消此
Statement
对象。void
clearBatch()
清空此
Statement
对象的当前SQL命令列表。void
clearWarnings()
清除此
Statement
对象上报告的所有警告。void
close()
Statement
对象的数据库和JDBC资源,而不是等待它自动关闭时发生。void
closeOnCompletion()
指定当其所有相关结果集都关闭时,此
Statement
将关闭。boolean
execute(String sql)
执行给定的SQL语句,这可能会返回多个结果。
boolean
execute(String sql, int autoGeneratedKeys)
执行给定的SQL语句,这可能返回多个结果,并向驱动程序发出信号,指出任何自动生成的密钥应该可用于检索。
boolean
execute(String sql, int[] columnIndexes)
执行给定的SQL语句,这可能会返回多个结果,并向驱动程序发出信号,指出给定数组中指定的自动生成的键应该可用于检索。
boolean
execute(String sql, String[] columnNames)
执行给定的SQL语句,这可能会返回多个结果,并向驱动程序发出信号,指出给定数组中指定的自动生成的键应该可用于检索。
int[]
executeBatch()
将一批命令提交到数据库以执行,并且所有命令都执行成功,返回一个更新计数的数组。
default long[]
executeLargeBatch()
将一批命令提交到数据库以执行,并且所有命令都执行成功,返回一个更新计数的数组。
default long
executeLargeUpdate(String sql)
执行给定的SQL语句,这可能是
INSERT
,UPDATE
,或DELETE
语句,或者不返回任何内容,如SQL DDL语句的SQL语句。default long
executeLargeUpdate(String sql, int autoGeneratedKeys)
执行给定的SQL语句并用给定的标志来向驱动程序发出信号,指出这个
Statement
对象产生的自动生成的密钥是否应该可用于检索。default long
executeLargeUpdate(String sql, int[] columnIndexes)
执行给定的SQL语句,并向驱动程序发出信号,指出给定数组中指示的自动生成的键应该可用于检索。
default long
executeLargeUpdate(String sql, String[] columnNames)
执行给定的SQL语句,并向驱动程序发出信号,指出给定数组中指示的自动生成的键应该可用于检索。
ResultSet
executeQuery(String sql)
执行给定的SQL语句,该语句返回单个
ResultSet
对象。int
executeUpdate(String sql)
执行给定的SQL语句,这可能是
INSERT
,UPDATE
,或DELETE
语句,或者不返回任何内容,如SQL DDL语句的SQL语句。int
executeUpdate(String sql, int autoGeneratedKeys)
执行给定的SQL语句并用给定的标志来向驱动程序发出信号,以了解该
Statement
对象产生的自动生成的密钥是否应该可用于检索。int
executeUpdate(String sql, int[] columnIndexes)
执行给定的SQL语句,并向驱动程序发出信号,指出给定数组中指示的自动生成的键应该可用于检索。
int
executeUpdate(String sql, String[] columnNames)
执行给定的SQL语句,并向驱动程序发出信号,指出给定数组中指示的自动生成的键应该可用于检索。
Connection
getConnection()
检索
Connection
生成此对象Statement
对象。int
getFetchDirection()
检索从数据库表中获取行的方向,这是
Statement
对象生成的结果集的默认值。int
getFetchSize()
检索结果集合的行数是默认为获取大小
ResultSet
从该生成的对象Statement
对象。ResultSet
getGeneratedKeys()
检索由执行此
Statement
对象而创建的任何自动生成的密钥。default long
getLargeMaxRows()
检索由此
ResultSet
对象生成的Statement
对象可以包含的最大行数。default long
getLargeUpdateCount()
将当前结果作为更新计数检索; 如果结果是一个
ResultSet
对象或没有更多结果,则返回-1。int
getMaxFieldSize()
检索由此
ResultSet
对象生成的Statement
对象中的ResultSet
和二进制列值可以返回的最大字节数。int
getMaxRows()
检索一个的最大行数
ResultSet
由此产生对象Statement
对象可以包含。boolean
getMoreResults()
移动到这个
Statement
对象的下一个结果,如果它是一个ResultSet
对象返回true
,并隐式关闭使用方法getResultSet
获取的任何当前的ResultSet
对象。boolean
getMoreResults(int current)
移动到此
Statement
对象的下一个结果,根据给定标志指定的指令处理任何当前的ResultSet
对象,如果下一个结果是一个ResultSet
对象,则返回true
。int
getQueryTimeout()
检索驱动程序等待
Statement
对象执行的Statement
。ResultSet
getResultSet()
以
ResultSet
对象的形式获取当前结果。int
getResultSetConcurrency()
检索由此
ResultSet
对象生成的Statement
对象的结果集并发。int
getResultSetHoldability()
检索由此
ResultSet
对象生成的Statement
对象的结果集可保持ResultSet
。int
getResultSetType()
检索由此
ResultSet
对象生成的Statement
对象的结果集类型。int
getUpdateCount()
将当前结果作为更新计数检索; 如果结果是一个
ResultSet
对象或没有更多的结果,则返回-1。SQLWarning
getWarnings()
检索此
Statement
对象上的呼叫报告的第一个警告。boolean
isClosed()
检索此
Statement
对象是否已关闭。boolean
isCloseOnCompletion()
返回指示是否该值
Statement
时,其所有相关结果集的关闭将被关闭。boolean
isPoolable()
返回指示是否值
Statement
是池化与否。void
setCursorName(String name)
将SQL游标名称设置为给定的
String
,后者将由Statement
对象使用execute
方法。void
setEscapeProcessing(boolean enable)
设置逃脱处理打开或关闭。
void
setFetchDirection(int direction)
给驱动程序一个提示,在
ResultSet
对象中使用这个Statement
对象创建的对象将处理行的Statement
。void
setFetchSize(int rows)
为JDBC驱动程序提供提示以应该从数据库时,需要更多的行中获取的行数
ResultSet
由此生成的对象Statement
。default void
setLargeMaxRows(long max)
设置的任何行的最大数目的极限
ResultSet
由此生成的对象Statement
对象可以包含给定数目。void
setMaxFieldSize(int max)
设置由此
ResultSet
对象生成的Statement
对象中字符和二进制列值可以返回的最大字节数限制。void
setMaxRows(int max)
设置由此
ResultSet
对象生成的任何Statement
对象可以包含给给定数量的最大行数的限制。void
setPoolable(boolean poolable)
要求汇集或不汇集
Statement
。void
setQueryTimeout(int seconds)
设置驱动程序等待
Statement
对象执行到给定秒数的秒数。
-
java.sql.ResultSet:
-
-
Modifier and Type Method and Description boolean
absolute(int row)
将光标移动到此
ResultSet
对象中的给定行号。void
afterLast()
将光标移动到这个
ResultSet
对象的末尾,就在最后一行之后。void
beforeFirst()
将光标移动到这个
ResultSet
对象的正面,就在第一行之前。void
cancelRowUpdates()
取消对此
ResultSet
对象中当前行的更新。void
clearWarnings()
清除此
ResultSet
对象上报告的所有警告。void
close()
ResultSet
释放此ResultSet
对象的数据库和JDBC资源,而不是等待其自动关闭时发生。void
deleteRow()
从此
ResultSet
对象和底层数据库中删除当前行。int
findColumn(String columnLabel)
将给定的
ResultSet
列标签映射到其ResultSet
列索引。boolean
first()
将光标移动到此
ResultSet
对象中的第一行。Array
getArray(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Array
对象检索。Array
getArray(String columnLabel)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Array
对象检索。InputStream
getAsciiStream(int columnIndex)
将此
ResultSet
对象的当前行中指定列的值作为ASCII字符流检索。InputStream
getAsciiStream(String columnLabel)
将此
ResultSet
对象的当前行中指定列的值作为ASCII字符流检索。BigDecimal
getBigDecimal(int columnIndex)
将此
ResultSet
对象的当前行中指定列的值作为java.math.BigDecimal
以完全精确的方式获取。BigDecimal
getBigDecimal(int columnIndex, int scale)
已弃用使用
getBigDecimal(int columnIndex)
或getBigDecimal(String columnLabel)
BigDecimal
getBigDecimal(String columnLabel)
将此
ResultSet
对象的当前行中的指定列的值作为java.math.BigDecimal
完全精确检索。BigDecimal
getBigDecimal(String columnLabel, int scale)
已弃用使用
getBigDecimal(int columnIndex)
或getBigDecimal(String columnLabel)
InputStream
getBinaryStream(int columnIndex)
将此
ResultSet
对象的当前行中的指定列的值作为未解释的字节流检索。InputStream
getBinaryStream(String columnLabel)
将此
ResultSet
对象的当前行中的指定列的值ResultSet
为未解释的流byte
s。Blob
getBlob(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Blob
对象检索。Blob
getBlob(String columnLabel)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Blob
对象检索。boolean
getBoolean(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为boolean
的Java编程语言。boolean
getBoolean(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为boolean
的Java编程语言。byte
getByte(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为byte
的Java编程语言。byte
getByte(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为byte
的Java编程语言。byte[]
getBytes(int columnIndex)
将该
ResultSet
对象的当前行中的指定列的值作为Java编程语言中的byte
数组检索。byte[]
getBytes(String columnLabel)
将该
ResultSet
对象的当前行中的指定列的值作为Java编程语言中的byte
数组检索。Reader
getCharacterStream(int columnIndex)
将此
ResultSet
对象的当前行中的指定列的值ResultSet
为java.io.Reader
对象。Reader
getCharacterStream(String columnLabel)
将此
ResultSet
对象的当前行中的指定列的值ResultSet
为java.io.Reader
对象。Clob
getClob(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Clob
对象检索。Clob
getClob(String columnLabel)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Clob
对象检索。int
getConcurrency()
检索此
ResultSet
对象的并发模式。String
getCursorName()
检索此
ResultSet
对象使用的SQL游标的名称。Date
getDate(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Date
对象检索。Date
getDate(int columnIndex, Calendar cal)
将此
ResultSet
对象的当前行中指定列的值ResultSet
为Java编程语言中的java.sql.Date
对象。Date
getDate(String columnLabel)
将此
ResultSet
对象的当前行中的指定列的值作为Java编程语言中的java.sql.Date
对象检索。Date
getDate(String columnLabel, Calendar cal)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Date
对象检索。double
getDouble(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为double
的Java编程语言。double
getDouble(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为double
的Java编程语言。int
getFetchDirection()
检索此
ResultSet
对象的抓取方向。int
getFetchSize()
检索此
ResultSet
对象的提取大小。float
getFloat(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为float
的Java编程语言。float
getFloat(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为float
的Java编程语言。int
getHoldability()
检索此
ResultSet
对象的ResultSet
int
getInt(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
作为对象int
在Java编程语言。int
getInt(String columnLabel)
以Java编程语言中的
int
此ResultSet
对象的当前行中指定列的值。long
getLong(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为long
的Java编程语言。long
getLong(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为long
的Java编程语言。ResultSetMetaData
getMetaData()
检索此
ResultSet
对象的列的数量,类型和属性。Reader
getNCharacterStream(int columnIndex)
将此
ResultSet
对象的当前行中的指定列的值ResultSet
为java.io.Reader
对象。Reader
getNCharacterStream(String columnLabel)
将此
ResultSet
对象的当前行中的指定列的值ResultSet
为java.io.Reader
对象。NClob
getNClob(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的NClob
对象检索。NClob
getNClob(String columnLabel)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的NClob
对象检索。String
getNString(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为String
的Java编程语言。String
getNString(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为String
的Java编程语言。Object
getObject(int columnIndex)
获取此的当前行中指定列的值
ResultSet
作为对象Object
在Java编程语言。<T> T
getObject(int columnIndex, 类<T> type)
检索此
ResultSet
对象的当前行中指定列的值,并将转换为SQL类型的列到所请求的Java数据类型,如果转换支持。Object
getObject(int columnIndex, Map<String,类<?>> map)
这个检索的当前行中指定列的值
ResultSet
作为对象Object
在Java编程语言。Object
getObject(String columnLabel)
获取此的当前行中指定列的值
ResultSet
作为对象Object
在Java编程语言。<T> T
getObject(String columnLabel, 类<T> type)
检索此
ResultSet
对象的当前行中指定列的值,并将转换为SQL类型的列到所请求的Java数据类型,如果转换支持。Object
getObject(String columnLabel, Map<String,类<?>> map)
这个检索的当前行中指定列的值
ResultSet
作为对象Object
在Java编程语言。Ref
getRef(int columnIndex)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Ref
对象检索。Ref
getRef(String columnLabel)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的Ref
对象检索。int
getRow()
检索当前行号。
RowId
getRowId(int columnIndex)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.RowId
对象检索。RowId
getRowId(String columnLabel)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.RowId
对象检索。short
getShort(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为short
的Java编程语言。short
getShort(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为short
的Java编程语言。SQLXML
getSQLXML(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
为java.sql.SQLXML
的Java编程语言对象。SQLXML
getSQLXML(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
为java.sql.SQLXML
的Java编程语言对象。Statement
getStatement()
检索
Statement
生成此对象ResultSet
对象。String
getString(int columnIndex)
这个检索的当前行中指定列的值
ResultSet
对象为String
的Java编程语言。String
getString(String columnLabel)
这个检索的当前行中指定列的值
ResultSet
对象为String
的Java编程语言。Time
getTime(int columnIndex)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Time
对象检索。Time
getTime(int columnIndex, Calendar cal)
将此
ResultSet
对象的当前行中的指定列的值作为Java编程语言中的java.sql.Time
对象检索。Time
getTime(String columnLabel)
将此
ResultSet
对象的当前行中的指定列的值作为Java编程语言中的java.sql.Time
对象检索。Time
getTime(String columnLabel, Calendar cal)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Time
对象检索。Timestamp
getTimestamp(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Timestamp
对象检索。Timestamp
getTimestamp(int columnIndex, Calendar cal)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Timestamp
对象检索。Timestamp
getTimestamp(String columnLabel)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Timestamp
对象检索。Timestamp
getTimestamp(String columnLabel, Calendar cal)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.sql.Timestamp
对象检索。int
getType()
检索此
ResultSet
对象的类型。InputStream
getUnicodeStream(int columnIndex)
已弃用使用
getCharacterStream
代替getUnicodeStream
InputStream
getUnicodeStream(String columnLabel)
已弃用使用
getCharacterStream
代替URL
getURL(int columnIndex)
将该
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.net.URL
对象检索。URL
getURL(String columnLabel)
将此
ResultSet
对象的当前行中指定列的值作为Java编程语言中的java.net.URL
对象检索。SQLWarning
getWarnings()
检索通过此
ResultSet
对象的呼叫报告的第一个警告。void
insertRow()
将插入行的内容插入到此
ResultSet
对象中并进入数据库。boolean
isAfterLast()
检索光标是否在此
ResultSet
对象中的最后一行之后。boolean
isBeforeFirst()
检索光标是否在此
ResultSet
对象中的第一行之前。boolean
isClosed()
检索此
ResultSet
对象是否已关闭。boolean
isFirst()
检索光标是否在此
ResultSet
对象的第一行。boolean
isLast()
检索光标是否位于此
ResultSet
对象的最后一行。boolean
last()
将光标移动到此
ResultSet
对象中的最后一行。void
moveToCurrentRow()
将光标移动到记住的光标位置,通常是当前行。
void
moveToInsertRow()
将光标移动到插入行。
boolean
next()
将光标从当前位置向前移动一行。
boolean
previous()
将光标移动到此
ResultSet
对象中的上一行。void
refreshRow()
用数据库中最新的值刷新当前行。
boolean
relative(int rows)
将光标移动到正或负的相对行数。
boolean
rowDeleted()
检索行是否被删除。
boolean
rowInserted()
检索当前行是否有插入。
boolean
rowUpdated()
检索当前行是否已更新。
void
setFetchDirection(int direction)
给出这个
ResultSet
对象中的行将被处理的方向的提示。void
setFetchSize(int rows)
给JDBC驱动程序一个提示,当这个
ResultSet
对象需要更多的行时,应该从数据库中获取的行数。void
updateArray(int columnIndex, Array x)
使用
java.sql.Array
值更新指定的列。void
updateArray(String columnLabel, Array x)
使用
java.sql.Array
值更新指定的列。void
updateAsciiStream(int columnIndex, InputStream x)
使用ascii流值更新指定的列。
void
updateAsciiStream(int columnIndex, InputStream x, int length)
使用ascii流值更新指定的列,该值将具有指定的字节数。
void
updateAsciiStream(int columnIndex, InputStream x, long length)
使用ascii流值更新指定的列,该值将具有指定的字节数。
void
updateAsciiStream(String columnLabel, InputStream x)
使用ascii流值更新指定的列。
void
updateAsciiStream(String columnLabel, InputStream x, int length)
使用ascii流值更新指定的列,该值将具有指定的字节数。
void
updateAsciiStream(String columnLabel, InputStream x, long length)
使用ascii流值更新指定的列,该值将具有指定的字节数。
void
updateBigDecimal(int columnIndex, BigDecimal x)
使用
java.math.BigDecimal
值更新指定的列。void
updateBigDecimal(String columnLabel, BigDecimal x)
使用
java.sql.BigDecimal
值更新指定的列。void
updateBinaryStream(int columnIndex, InputStream x)
使用二进制流值更新指定的列。
void
updateBinaryStream(int columnIndex, InputStream x, int length)
使用二进制流值更新指定的列,该值将具有指定的字节数。
void
updateBinaryStream(int columnIndex, InputStream x, long length)
使用二进制流值更新指定的列,该值将具有指定的字节数。
void
updateBinaryStream(String columnLabel, InputStream x)
使用二进制流值更新指定的列。
void
updateBinaryStream(String columnLabel, InputStream x, int length)
使用二进制流值更新指定的列,该值将具有指定的字节数。
void
updateBinaryStream(String columnLabel, InputStream x, long length)
使用二进制流值更新指定的列,该值将具有指定的字节数。
void
updateBlob(int columnIndex, Blob x)
使用
java.sql.Blob
值更新指定的列。void
updateBlob(int columnIndex, InputStream inputStream)
使用给定的输入流更新指定的列。
void
updateBlob(int columnIndex, InputStream inputStream, long length)
使用给定的输入流更新指定列,该输入流将具有指定的字节数。
void
updateBlob(String columnLabel, Blob x)
使用
java.sql.Blob
值更新指定的列。void
updateBlob(String columnLabel, InputStream inputStream)
使用给定的输入流更新指定的列。
void
updateBlob(String columnLabel, InputStream inputStream, long length)
使用给定的输入流更新指定列,该输入流将具有指定的字节数。
void
updateBoolean(int columnIndex, boolean x)
使用
boolean
值更新指定的列。void
updateBoolean(String columnLabel, boolean x)
使用
boolean
值更新指定的列。void
updateByte(int columnIndex, byte x)
使用
byte
值更新指定的列。void
updateByte(String columnLabel, byte x)
使用
byte
值更新指定的列。void
updateBytes(int columnIndex, byte[] x)
使用
byte
数组值更新指定的列。void
updateBytes(String columnLabel, byte[] x)
使用字节数组值更新指定的列。
void
updateCharacterStream(int columnIndex, Reader x)
使用字符流值更新指定的列。
void
updateCharacterStream(int columnIndex, Reader x, int length)
使用字符流值更新指定的列,该值将具有指定的字节数。
void
updateCharacterStream(int columnIndex, Reader x, long length)
使用字符流值更新指定的列,该值将具有指定的字节数。
void
updateCharacterStream(String columnLabel, Reader reader)
使用字符流值更新指定的列。
void
updateCharacterStream(String columnLabel, Reader reader, int length)
使用字符流值更新指定的列,该值将具有指定的字节数。
void
updateCharacterStream(String columnLabel, Reader reader, long length)
使用字符流值更新指定的列,该值将具有指定的字节数。
void
updateClob(int columnIndex, Clob x)
使用
java.sql.Clob
值更新指定的列。void
updateClob(int columnIndex, Reader reader)
使用给定的
Reader
对象更新指定的列。void
updateClob(int columnIndex, Reader reader, long length)
使用给定的
Reader
对象来更新指定的列,这是给定的长度的字符数。void
updateClob(String columnLabel, Clob x)
使用
java.sql.Clob
值更新指定的列。void
updateClob(String columnLabel, Reader reader)
使用给定的
Reader
对象更新指定的列。void
updateClob(String columnLabel, Reader reader, long length)
使用给定的
Reader
对象更新指定的列,这是给定的长度的字符数。void
updateDate(int columnIndex, Date x)
使用
java.sql.Date
值更新指定的列。void
updateDate(String columnLabel, Date x)
使用
java.sql.Date
值更新指定的列。void
updateDouble(int columnIndex, double x)
使用
double
值更新指定的列。void
updateDouble(String columnLabel, double x)
使用
double
值更新指定的列。void
updateFloat(int columnIndex, float x)
使用
float
值更新指定的列。void
updateFloat(String columnLabel, float x)
使用
float
值更新指定的列。void
updateInt(int columnIndex, int x)
使用
int
值更新指定的列。void
updateInt(String columnLabel, int x)
使用
int
值更新指定的列。void
updateLong(int columnIndex, long x)
使用
long
值更新指定的列。void
updateLong(String columnLabel, long x)
使用
long
值更新指定的列。void
updateNCharacterStream(int columnIndex, Reader x)
使用字符流值更新指定的列。
void
updateNCharacterStream(int columnIndex, Reader x, long length)
使用字符流值更新指定的列,该值将具有指定的字节数。
void
updateNCharacterStream(String columnLabel, Reader reader)
使用字符流值更新指定的列。
void
updateNCharacterStream(String columnLabel, Reader reader, long length)
使用字符流值更新指定的列,该值将具有指定的字节数。
void
updateNClob(int columnIndex, NClob nClob)
使用
java.sql.NClob
值更新指定的列。void
updateNClob(int columnIndex, Reader reader)
使用给定的
Reader
更新指定的列数据将从流中读取数据,直到达到流出端。void
updateNClob(int columnIndex, Reader reader, long length)
使用给定的
Reader
对象更新指定的列,这是给定的字符数。void
updateNClob(String columnLabel, NClob nClob)
使用
java.sql.NClob
值更新指定的列。void
updateNClob(String columnLabel, Reader reader)
使用给定的
Reader
对象更新指定的列。void
updateNClob(String columnLabel, Reader reader, long length)
使用给定的
Reader
对象更新指定的列,这是给定的长度的字符数。void
updateNString(int columnIndex, String nString)
使用
String
值更新指定的列。void
updateNString(String columnLabel, String nString)
使用
String
值更新指定的列。void
updateNull(int columnIndex)
使用
null
值更新指定的列。void
updateNull(String columnLabel)
使用
null
值更新指定的列。void
updateObject(int columnIndex, Object x)
使用
Object
值更新指定的列。void
updateObject(int columnIndex, Object x, int scaleOrLength)
使用
Object
值更新指定的列。default void
updateObject(int columnIndex, Object x, SQLType targetSqlType)
使用
Object
值更新指定的列。default void
updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength)
使用
Object
值更新指定的列。void
updateObject(String columnLabel, Object x)
使用
Object
值更新指定的列。void
updateObject(String columnLabel, Object x, int scaleOrLength)
使用
Object
值更新指定的列。default void
updateObject(String columnLabel, Object x, SQLType targetSqlType)
使用
Object
值更新指定的列。default void
updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength)
使用
Object
值更新指定的列。void
updateRef(int columnIndex, Ref x)
使用
java.sql.Ref
值更新指定的列。void
updateRef(String columnLabel, Ref x)
使用
java.sql.Ref
值更新指定的列。void
updateRow()
使用此
ResultSet
对象的当前行的新内容更新底层数据库。void
updateRowId(int columnIndex, RowId x)
使用
RowId
值更新指定的列。void
updateRowId(String columnLabel, RowId x)
使用
RowId
值更新指定的列。void
updateShort(int columnIndex, short x)
使用
short
值更新指定的列。void
updateShort(String columnLabel, short x)
使用
short
值更新指定的列。void
updateSQLXML(int columnIndex, SQLXML xmlObject)
使用
java.sql.SQLXML
值更新指定的列。void
updateSQLXML(String columnLabel, SQLXML xmlObject)
使用
java.sql.SQLXML
值更新指定的列。void
updateString(int columnIndex, String x)
使用
String
值更新指定的列。void
updateString(String columnLabel, String x)
使用
String
值更新指定的列。void
updateTime(int columnIndex, Time x)
使用
java.sql.Time
值更新指定的列。void
updateTime(String columnLabel, Time x)
使用
java.sql.Time
值更新指定的列。void
updateTimestamp(int columnIndex, Timestamp x)
使用
java.sql.Timestamp
值更新指定的列。void
updateTimestamp(String columnLabel, Timestamp x)
使用
java.sql.Timestamp
值更新指定的列。boolean
wasNull()
报告最后一列读取的值是否为SQL
NULL
。
-
5.4.2 管理连接、语句和结果集
在使用完ResultSet,Statement,Connection对象后,应立即调用close方法。
如果Statement上有一个打开的结果集,那么调用close方法将自动关闭该结果集。同样的,调用Connection的close方法将关闭该连接上的所有语句。
应该使用带资源的try语句块关闭链接,并使用一个单独的try/catch语句块处理异常。分离try程序快可以提高代码的可读性和可维护性。
5.4.3 分析SQL异常
每个SQLException都有一个由多个SQLException对象构成的链,这些对象可以通过getNextException获取。
java.sql.Exception:
-
-
Modifier and Type Method and Description int
getErrorCode()
检索此
SQLException
对象的供应商特定异常代码。SQLException
getNextException()
通过setNextException(SQLException ex)检索链接到此
SQLException
对象的异常。String
getSQLState()
检索此
SQLException
对象的SQLState。Iterator<Throwable>
iterator()
返回链接的SQLExceptions的迭代器。
void
setNextException(SQLException ex)
将
SQLException
对象添加到链的末尾。
-
java.sql.SQLWarning:
-
-
Modifier and Type Method and Description SQLWarning
getNextWarning()
检索
SQLWarning
对象由setNextWarning
链接的警告。void
setNextWarning(SQLWarning w)
将
SQLWarning
对象添加到链的末尾。
-
java.sql.DataTruncation:SQLWaring的子类当数据产生意外截断时,DataTruncation被当作异常抛出
-
-
Modifier and Type Method and Description int
getDataSize()
获取应该传输的数据的字节数。
int
getIndex()
检索被截断的列或参数的索引。
boolean
getParameter()
指示truncated的值是参数值还是列值。
boolean
getRead()
指示值是否在读取时被截断。
int
getTransferSize()
获取实际传输的数据的字节数。
-
5.4.4 组装数据库
package exec;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.sql.*;
/**
* Executes all SQL statements in a file. Call this program as <br>
* java -classpath driverPath:. ExecSQL commandFile
*
* @version 1.32 2016-04-27
* @author Cay Horstmann
*/
class ExecSQL
{
public static void main(String args[]) throws IOException
{
try (Scanner in = args.length == 0 ? new Scanner(System.in)
: new Scanner(Paths.get(args[0]), "UTF-8"))
{
try (Connection conn = getConnection();
Statement stat = conn.createStatement())
{
while (true)
{
if (args.length == 0) System.out.println("Enter command or EXIT to exit:");
if (!in.hasNextLine()) return;
String line = in.nextLine().trim();
if (line.equalsIgnoreCase("EXIT")) return;
if (line.endsWith(";")) // remove trailing semicolon
{
line = line.substring(0, line.length() - 1);
}
try
{
boolean isResult = stat.execute(line);
if (isResult)
{
try (ResultSet rs = stat.getResultSet())
{
showResultSet(rs);
}
}
else
{
int updateCount = stat.getUpdateCount();
System.out.println(updateCount + " rows updated");
}
}
catch (SQLException ex)
{
for (Throwable e : ex)
e.printStackTrace();
}
}
}
}
catch (SQLException e)
{
for (Throwable t : e)
t.printStackTrace();
}
}
/**
* Gets a connection from the properties specified in the file database.properties
* @return the database connection
*/
public static Connection getConnection() throws SQLException, IOException
{
Properties props = new Properties();
try (InputStream in = Files.newInputStream(Paths.get("database.properties")))
{
props.load(in);
}
String drivers = props.getProperty("jdbc.drivers");
if (drivers != null) System.setProperty("jdbc.drivers", drivers);
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");
return DriverManager.getConnection(url, username, password);
}
/**
* Prints a result set.
* @param result the result set to be printed
*/
public static void showResultSet(ResultSet result) throws SQLException
{
ResultSetMetaData metaData = result.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++)
{
if (i > 1) System.out.print(", ");
System.out.print(metaData.getColumnLabel(i));
}
System.out.println();
while (result.next())
{
for (int i = 1; i <= columnCount; i++)
{
if (i > 1) System.out.print(", ");
System.out.print(result.getString(i));
}
System.out.println();
}
}
}
5.5 执行查询操作
5.5.1 预备语句
/**
* 执行SQL语句,可以进行增、删、改的操作,不能执行查询
*
* @param sql
* 预编译的 SQL 语句
* @param param
* 预编译的 SQL 语句中的‘?’参数的字符串数组
* @return 影响的条数
*/
public int executeSQL(String preparedSql, Object[] param) {
Connection conn = null;
PreparedStatement pstmt = null;
int num = 0;
/* 处理SQL,执行SQL */
try {
conn = getConn(); // 得到数据库连接
pstmt = conn.prepareStatement(preparedSql); // 得到PreparedStatement对象
if (param != null) {
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i + 1, param[i]); // 为预编译sql设置参数
}
}
// System.out.println(preparedSql);
num = pstmt.executeUpdate(); // 执行SQL语句
} catch (ClassNotFoundException e) {
e.printStackTrace(); // 处理ClassNotFoundException异常
} catch (SQLException e) {
e.printStackTrace(); // 处理SQLException异常
} finally {
this.closeAll(conn, pstmt, null);
}
return num;
}
通过实现准备好查询并多次重用它,我们就可以确保查询所需的步骤只被执行一次
在从一个查询到另一个查询的过程中,只需使用setXXX方法重新绑定那些需要改变的变量即可。
通常,使用数据库的查询代码要比Java程序好的多——这是数据库的一个重要有点。一般而言,可以使用SQL解决的问题,就不要使用Java程序。
package query;
import java.io.*;
import java.nio.file.*;
import java.sql.*;
import java.util.*;
/**
* This program demonstrates several complex database queries.
* @version 1.30 2012-06-05
* @author Cay Horstmann
*/
public class QueryTest
{
private static final String allQuery = "SELECT Books.Price, Books.Title FROM Books";
private static final String authorPublisherQuery = "SELECT Books.Price, Books.Title"
+ " FROM Books, BooksAuthors, Authors, Publishers"
+ " WHERE Authors.Author_Id = BooksAuthors.Author_Id AND BooksAuthors.ISBN = Books.ISBN"
+ " AND Books.Publisher_Id = Publishers.Publisher_Id AND Authors.Name = ?"
+ " AND Publishers.Name = ?";
private static final String authorQuery
= "SELECT Books.Price, Books.Title FROM Books, BooksAuthors, Authors"
+ " WHERE Authors.Author_Id = BooksAuthors.Author_Id AND BooksAuthors.ISBN = Books.ISBN"
+ " AND Authors.Name = ?";
private static final String publisherQuery
= "SELECT Books.Price, Books.Title FROM Books, Publishers"
+ " WHERE Books.Publisher_Id = Publishers.Publisher_Id AND Publishers.Name = ?";
private static final String priceUpdate = "UPDATE Books " + "SET Price = Price + ? "
+ " WHERE Books.Publisher_Id = (SELECT Publisher_Id FROM Publishers WHERE Name = ?)";
private static Scanner in;
private static ArrayList<String> authors = new ArrayList<>();
private static ArrayList<String> publishers = new ArrayList<>();
public static void main(String[] args) throws IOException
{
try (Connection conn = getConnection())
{
in = new Scanner(System.in);
authors.add("Any");
publishers.add("Any");
try (Statement stat = conn.createStatement())
{
// Fill the authors array list
String query = "SELECT Name FROM Authors";
try (ResultSet rs = stat.executeQuery(query))
{
while (rs.next())
authors.add(rs.getString(1));
}
// Fill the publishers array list
query = "SELECT Name FROM Publishers";
try (ResultSet rs = stat.executeQuery(query))
{
while (rs.next())
publishers.add(rs.getString(1));
}
}
boolean done = false;
while (!done)
{
System.out.print("Q)uery C)hange prices E)xit: ");
String input = in.next().toUpperCase();
if (input.equals("Q"))
executeQuery(conn);
else if (input.equals("C"))
changePrices(conn);
else
done = true;
}
}
catch (SQLException e)
{
for (Throwable t : e)
System.out.println(t.getMessage());
}
}
/**
* Executes the selected query.
* @param conn the database connection
*/
private static void executeQuery(Connection conn) throws SQLException
{
String author = select("Authors:", authors);
String publisher = select("Publishers:", publishers);
PreparedStatement stat;
if (!author.equals("Any") && !publisher.equals("Any"))
{
stat = conn.prepareStatement(authorPublisherQuery);
stat.setString(1, author);
stat.setString(2, publisher);
}
else if (!author.equals("Any") && publisher.equals("Any"))
{
stat = conn.prepareStatement(authorQuery);
stat.setString(1, author);
}
else if (author.equals("Any") && !publisher.equals("Any"))
{
stat = conn.prepareStatement(publisherQuery);
stat.setString(1, publisher);
}
else
stat = conn.prepareStatement(allQuery);
try (ResultSet rs = stat.executeQuery())
{
while (rs.next())
System.out.println(rs.getString(1) + ", " + rs.getString(2));
}
}
/**
* Executes an update statement to change prices.
* @param conn the database connection
*/
public static void changePrices(Connection conn) throws SQLException
{
String publisher = select("Publishers:", publishers.subList(1, publishers.size()));
System.out.print("Change prices by: ");
double priceChange = in.nextDouble();
PreparedStatement stat = conn.prepareStatement(priceUpdate);
stat.setDouble(1, priceChange);
stat.setString(2, publisher);
int r = stat.executeUpdate();
System.out.println(r + " records updated.");
}
/**
* Asks the user to select a string.
* @param prompt the prompt to display
* @param options the options from which the user can choose
* @return the option that the user chose
*/
public static String select(String prompt, List<String> options)
{
while (true)
{
System.out.println(prompt);
for (int i = 0; i < options.size(); i++)
System.out.printf("%2d) %s%n", i + 1, options.get(i));
int sel = in.nextInt();
if (sel > 0 && sel <= options.size())
return options.get(sel - 1);
}
}
/**
* Gets a connection from the properties specified in the file database.properties.
* @return the database connection
*/
public static Connection getConnection() throws SQLException, IOException
{
Properties props = new Properties();
try (InputStream in = Files.newInputStream(Paths.get("database.properties")))
{
props.load(in);
}
String drivers = props.getProperty("jdbc.drivers");
if (drivers != null) System.setProperty("jdbc.drivers", drivers);
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");
return DriverManager.getConnection(url, username, password);
}
}
java.util.PreparedStatement:
-
-
Modifier and Type Method and Description void
addBatch()
向这个
PreparedStatement
对象的一批命令添加一组参数。void
clearParameters()
立即清除当前参数值。
boolean
execute()
执行此
PreparedStatement
对象中的SQL语句,这可能是任何类型的SQL语句。default long
executeLargeUpdate()
执行在该SQL语句
PreparedStatement
对象,它必须是一个SQL数据操纵语言(DML)语句,如INSERT
,UPDATE
或DELETE
; 或不返回任何内容的SQL语句,例如DDL语句。ResultSet
executeQuery()
执行此
PreparedStatement
对象中的SQL查询,并返回查询PreparedStatement
的ResultSet
对象。int
executeUpdate()
执行在该SQL语句
PreparedStatement
对象,它必须是一个SQL数据操纵语言(DML)语句,如INSERT
,UPDATE
或DELETE
; 或不返回任何内容的SQL语句,例如DDL语句。ResultSetMetaData
getMetaData()
检索一个
ResultSetMetaData
对象,其中包含有关执行此PreparedStatement
对象时将返回的ResultSet
对象的列的信息。ParameterMetaData
getParameterMetaData()
检索此
PreparedStatement
对象的参数的数量,类型和属性。void
setArray(int parameterIndex, Array x)
将指定的参数设置为给定的
java.sql.Array
对象。void
setAsciiStream(int parameterIndex, InputStream x)
将指定的参数设置为给定的输入流。
void
setAsciiStream(int parameterIndex, InputStream x, int length)
将指定的参数设置为给定的输入流,它将具有指定的字节数。
void
setAsciiStream(int parameterIndex, InputStream x, long length)
将指定的参数设置为给定的输入流,它将具有指定的字节数。
void
setBigDecimal(int parameterIndex, BigDecimal x)
将指定的参数设置为给定的
java.math.BigDecimal
值。void
setBinaryStream(int parameterIndex, InputStream x)
将指定的参数设置为给定的输入流。
void
setBinaryStream(int parameterIndex, InputStream x, int length)
将指定的参数设置为给定的输入流,它将具有指定的字节数。
void
setBinaryStream(int parameterIndex, InputStream x, long length)
将指定的参数设置为给定的输入流,它将具有指定的字节数。
void
setBlob(int parameterIndex, Blob x)
将指定的参数设置为给定的
java.sql.Blob
对象。void
setBlob(int parameterIndex, InputStream inputStream)
将指定的参数设置为
InputStream
对象。void
setBlob(int parameterIndex, InputStream inputStream, long length)
将指定的参数设置为
InputStream
对象。void
setBoolean(int parameterIndex, boolean x)
将指定的参数设置为给定的Java
boolean
值。void
setByte(int parameterIndex, byte x)
将指定的参数设置为给定的Java
byte
值。void
setBytes(int parameterIndex, byte[] x)
将指定的参数设置为给定的Java字节数组。
void
setCharacterStream(int parameterIndex, Reader reader)
将指定的参数设置为给定的
Reader
对象。void
setCharacterStream(int parameterIndex, Reader reader, int length)
将指定的参数设置为给定的
Reader
对象,这是给定的长度的字符数。void
setCharacterStream(int parameterIndex, Reader reader, long length)
将指定的参数设置为给定的
Reader
对象,这是给定的长度的字符数。void
setClob(int parameterIndex, Clob x)
将指定的参数设置为给定的
java.sql.Clob
对象。void
setClob(int parameterIndex, Reader reader)
将指定的参数设置为
Reader
对象。void
setClob(int parameterIndex, Reader reader, long length)
将指定的参数设置为
Reader
对象。void
setDate(int parameterIndex, Date x)
使用运行应用程序的虚拟机的默认时区将指定的
java.sql.Date
设置为给定的java.sql.Date
值。void
setDate(int parameterIndex, Date x, Calendar cal)
使用给定的
Calendar
对象将指定的Calendar
设置为给定的java.sql.Date
值。void
setDouble(int parameterIndex, double x)
将指定的参数设置为给定的Java
double
值。void
setFloat(int parameterIndex, float x)
将指定的参数设置为给定的Java
float
值。void
setInt(int parameterIndex, int x)
将指定的参数设置为给定的Java
int
值。void
setLong(int parameterIndex, long x)
将指定的参数设置为给定的Java
long
值。void
setNCharacterStream(int parameterIndex, Reader value)
将指定的参数设置为
Reader
对象。void
setNCharacterStream(int parameterIndex, Reader value, long length)
将指定的参数设置为
Reader
对象。void
setNClob(int parameterIndex, NClob value)
将指定的参数设置为
java.sql.NClob
对象。void
setNClob(int parameterIndex, Reader reader)
将指定的参数设置为
Reader
对象。void
setNClob(int parameterIndex, Reader reader, long length)
将指定的参数设置为
Reader
对象。void
setNString(int parameterIndex, String value)
将指定的参数设置为给定的
String
对象。void
setNull(int parameterIndex, int sqlType)
将指定的参数设置为SQL
NULL
。void
setNull(int parameterIndex, int sqlType, String typeName)
将指定的参数设置为SQL
NULL
。void
setObject(int parameterIndex, Object x)
使用给定对象设置指定参数的值。
void
setObject(int parameterIndex, Object x, int targetSqlType)
使用给定对象设置指定参数的值。
void
setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength)
使用给定对象设置指定参数的值。
default void
setObject(int parameterIndex, Object x, SQLType targetSqlType)
使用给定对象设置指定参数的值。
default void
setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength)
使用给定对象设置指定参数的值。
void
setRef(int parameterIndex, Ref x)
将指定的参数设置为给定的
REF(<structured-type>)
值。void
setRowId(int parameterIndex, RowId x)
将指定的参数设置为给定的
java.sql.RowId
对象。void
setShort(int parameterIndex, short x)
将指定的参数设置为给定的Java
short
值。void
setSQLXML(int parameterIndex, SQLXML xmlObject)
将指定的参数设置为给定的
java.sql.SQLXML
对象。void
setString(int parameterIndex, String x)
将指定的参数设置为给定的Java
String
值。void
setTime(int parameterIndex, Time x)
将指定的参数设置为给定的
java.sql.Time
值。void
setTime(int parameterIndex, Time x, Calendar cal)
使用给定的
Calendar
对象将指定的Calendar
设置为给定的java.sql.Time
值。void
setTimestamp(int parameterIndex, Timestamp x)
将指定的参数设置为给定的
java.sql.Timestamp
值。void
setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
使用给定的
Calendar
对象将指定的Calendar
设置为给定的java.sql.Timestamp
值。void
setUnicodeStream(int parameterIndex, InputStream x, int length)
已弃用使用
setCharacterStream
void
setURL(int parameterIndex, URL x)
将指定的参数设置为给定的
java.net.URL
值。
-
5.5.2 读写LOB
在SQL中,二进制大对象成为BLOB,字符型大对象称为CLOB
要从Blob中获取二进制数据,可以调用getBytes或getBinaryStream.例如,如果有一张保存图书封面图像的表,那么就可以像线面这样获取一张图像:
java.sql.Blob(Clob同理)
-
-
Modifier and Type Method and Description void
free()
该方法释放了
Blob
对象并释放了它所拥有的资源。InputStream
getBinaryStream()
将此
Blob
实例指定的BLOB
值作为流Blob
。InputStream
getBinaryStream(long pos, long length)
返回包含部分
Blob
值的InputStream
对象,从pos指定的字节开始,长度为长度字节。byte[]
getBytes(long pos, int length)
检索此
Blob
对象所BLOB
BLOB的全部或部分值,作为字节数组。long
length()
返回此
Blob
对象指定的BLOB
值中的字节数。long
position(Blob pattern, long start)
检索在该字节位置
BLOB
通过该指定值Blob
对象在该pattern
开始。long
position(byte[] pattern, long start)
检索指定字节数组
pattern
在该Blob
对象表示的BLOB
值内开始的字节位置。OutputStream
setBinaryStream(long pos)
检索可用于写入此
Blob
对象所代表的BLOB
值的流。int
setBytes(long pos, byte[] bytes)
将给定的字节数组写入
Blob
对象表示的BLOB
值,从位置pos
开始,并返回写入的字节数。int
setBytes(long pos, byte[] bytes, int offset, int len)
将所有或部分给定的
byte
数组写入该Blob
对象表示的BLOB
值,并返回写入的字节数。void
truncate(long len)
截断此
Blob
对象表示的长度为len
个字节的BLOB
值。
-
5.5.3 SQL转义
5.5.4 多结果集
存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。
delimiter //
create procedure X (IN n_id int)
begin
select * from test_table1 where id=1;
select * from test_table2 where id=2;
select * from test_table3 where id=3;
end //
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
String sql = "{call x(3)}"; //SQL转义
CallableStatement stmt=conn.prepareCall(sql);
boolean isResult = stmt.execute();
boolean done = false;
while(!done) {
if(isResult) {
ResultSet rs=stmt.getResultSet();
while(rs.next()) {
System.out.println(rs.getString("id"));
}
}else {
int updateCount= stmt.getUpdateCount();
if(updateCount>=0) {
}else {
done=true;
}
}
if(!done) {
isResult=stmt.getMoreResults();
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.5.5 获取自动生成的键
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
Statement stmt = conn.createStatement();
String sql="insert into person(password) values('123456')";
stmt.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.6 可滚动和可更新的结果集
5.6.1 可滚动的结果集
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from person";
ResultSet rs=stmt.executeQuery(sql);
rs.absolute(3); //定位到第三行
int currentRow=rs.getRow(); //得到当前行
System.out.println(rs.getInt(1)+" "+currentRow);
rs.previous(); //向行数小走一行
System.out.println(rs.getInt(1)+" "+currentRow);
rs.relative(2); //向行数大走两行
System.out.println(rs.getInt(1)+" "+currentRow);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.6.2 可更新的结果集
可更新的结果集并非必须是可滚动的。
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from person";
ResultSet rs=stmt.executeQuery(sql);
rs.next();
rs.updateString("password", "nihao");
rs.updateRow(); //更新
rs.absolute(3);
rs.deleteRow(); //删除
rs.moveToInsertRow(); //插入(插到了尾部,事实上是移动到插入行)
rs.updateString(2, "hellowprld");
rs.insertRow();
rs.moveToCurrentRow();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.7 行集
可滚动的结果集虽然功能强大,但是在于用户交互的整个过程中,必须始终与数据库保持连接。
我们可以使用行集。RowSet接口扩展自ResultSet接口,却无需始终保持与数据库的连接。
行集还适用于将查询结果移动到复杂应用的其它层,或者是诸如手机之类的其它设备中。
5.7.1 构建行集
5.7.2 被缓冲的行集
一个被缓冲的行集中包含了一个结果集中所有的数据。
Connection conn=getConn();
Statement stmt = conn.createStatement();
String sql="select * from person";
ResultSet rs=stmt.executeQuery(sql);
//获取行集的标准方式
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
//使用一个结果集填充CachedRowSet对象
crs.populate(rs);
conn.close();
//CachedRowSet是ResultSet的子接口,可以像使用ResultSet一样使用
while(crs.next()) {
System.out.println(crs.getInt(1));
}
也可以让CachedRowSet对象自动建立一个数据库连接:
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.sql.rowset.*;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
//获取行集的标准方式
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
/**
* CachedRowSet自动建立一个数据库连接
*/
//设置数据库参数
crs.setUrl(BaseDao.URL);
crs.setUsername(BaseDao.DBNAME);
crs.setPassword(BaseDao.DBPASS);
//设置查询语句和所有参数
crs.setCommand("select * from person where id=?");
crs.setInt(1, 1);
//将查询结果田中到行集
crs.execute();
/**
* CachedRowSet是ResultSet的子接口,可以像使用ResultSet一样使用
*/
while(crs.next()) {
System.out.println(crs.getInt(1));
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.sql.rowset.*;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
//获取行集的标准方式
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet crs = factory.createCachedRowSet();
/**
* CachedRowSet自动建立一个数据库连接
*/
//设置数据库参数
crs.setUrl(BaseDao.URL);
crs.setUsername(BaseDao.DBNAME);
crs.setPassword(BaseDao.DBPASS);
//设置查询语句和所有参数
crs.setCommand("select * from person where id=?");
crs.setPageSize(1); //有的时候,查询结果非常大,指定每一页的尺寸。
crs.setInt(1, 1);
//将查询结果田中到行集
crs.execute();
crs.nextPage(); //获得下一批数据
//如果修改了行集中的内容,必须调用一下方法将修改写回到数据库中
crs.acceptChanges(conn);
//或
crs.acceptChanges();//只有在行集中设置了数据库参数时才有效
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
java.sql.RowSet:
-
-
Modifier and Type Method and Description void
addRowSetListener(RowSetListener listener)
注册给定的侦听器,以便将通知发生在此
RowSet
对象上的事件。void
clearParameters()
清除为此
RowSet
对象的命令设置的参数。void
execute()
用数据填充这个
RowSet
对象。String
getCommand()
检索此
RowSet
对象的命令属性。String
getDataSourceName()
检索标识此
RowSet
对象的数据源的逻辑名称。boolean
getEscapeProcessing()
检索是否为此
RowSet
对象启用了转义处理。int
getMaxFieldSize()
检索某些列值可能返回的最大字节数。
int
getMaxRows()
检索此
RowSet
对象可以包含的最大行数。String
getPassword()
检索用于创建数据库连接的密码。
int
getQueryTimeout()
检索驱动程序等待语句执行的最大秒数。
int
getTransactionIsolation()
检索为此
RowSet
对象设置的事务隔离级别。Map<String,类<?>>
getTypeMap()
检索与此
RowSet
对象关联的Map
对象,该对象指定SQL用户定义类型的自定义映射(如果有)。String
getUrl()
检索此
RowSet
对象将用于创建连接的url属性,如果使用DriverManager
而不是DataSource
对象来建立连接。String
getUsername()
检索用于创建此
RowSet
对象的数据库连接的用户名。boolean
isReadOnly()
检索此
RowSet
对象是否为只读。void
removeRowSetListener(RowSetListener listener)
从在
RowSet
对象发生事件时将被通知的组件列表中删除指定的侦听器。void
setArray(int i, Array x)
使用给定的
Array
值设置此RowSet
对象的命令中的指定Array
。void
setAsciiStream(int parameterIndex, InputStream x)
将此
RowSet
对象的命令中的指定参数设置为给定的输入流。void
setAsciiStream(int parameterIndex, InputStream x, int length)
将此
RowSet
对象的命令中的指定参数设置为给定的java.io.InputStream
值。void
setAsciiStream(String parameterName, InputStream x)
将指定的参数设置为给定的输入流。
void
setAsciiStream(String parameterName, InputStream x, int length)
将指定的参数设置为给定的输入流,它将具有指定的字节数。
void
setBigDecimal(int parameterIndex, BigDecimal x)
将此
RowSet
对象的命令中的指定参数设置为给定的java.math.BigDeciaml
值。void
setBigDecimal(String parameterName, BigDecimal x)
将指定的参数设置为给定的
java.math.BigDecimal
值。void
setBinaryStream(int parameterIndex, InputStream x)
将此
RowSet
对象的命令中的指定参数设置为给定的输入流。void
setBinaryStream(int parameterIndex, InputStream x, int length)
将此
RowSet
对象的命令中的指定参数设置为给定的java.io.InputStream
值。void
setBinaryStream(String parameterName, InputStream x)
将指定的参数设置为给定的输入流。
void
setBinaryStream(String parameterName, InputStream x, int length)
将指定的参数设置为给定的输入流,它将具有指定的字节数。
void
setBlob(int i, Blob x)
使用给定的
Blob
值在此RowSet
对象的命令中设置指定的Blob
。void
setBlob(int parameterIndex, InputStream inputStream)
将指定的参数设置为
InputStream
对象。void
setBlob(int parameterIndex, InputStream inputStream, long length)
将指定的参数设置为
InputStream
对象。void
setBlob(String parameterName, Blob x)
将指定的参数设置为给定的
java.sql.Blob
对象。void
setBlob(String parameterName, InputStream inputStream)
将指定的参数设置为
InputStream
对象。void
setBlob(String parameterName, InputStream inputStream, long length)
将指定的参数设置为
InputStream
对象。void
setBoolean(int parameterIndex, boolean x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javaboolean
值。void
setBoolean(String parameterName, boolean x)
将指定的参数设置为给定的Java
boolean
值。void
setByte(int parameterIndex, byte x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javabyte
值。void
setByte(String parameterName, byte x)
将指定的参数设置为给定的Java
byte
值。void
setBytes(int parameterIndex, byte[] x)
将此
RowSet
对象的命令中的指定参数设置为给定的byte
Java数组。void
setBytes(String parameterName, byte[] x)
将指定的参数设置为给定的Java字节数组。
void
setCharacterStream(int parameterIndex, Reader reader)
将此
RowSet
对象的命令中的指定参数设置为给定的Reader
对象。void
setCharacterStream(int parameterIndex, Reader reader, int length)
将此
RowSet
对象的命令中的指定参数设置为给定的java.io.Reader
值。void
setCharacterStream(String parameterName, Reader reader)
将指定的参数设置为给定的
Reader
对象。void
setCharacterStream(String parameterName, Reader reader, int length)
将指定的参数设置为给定的
Reader
对象,这是给定的长度的字符数。void
setClob(int i, Clob x)
使用给定的
Clob
值设置此RowSet
对象的命令中的指定Clob
。void
setClob(int parameterIndex, Reader reader)
将指定的参数设置为
Reader
对象。void
setClob(int parameterIndex, Reader reader, long length)
将指定的参数设置为
Reader
对象。void
setClob(String parameterName, Clob x)
将指定的参数设置为给定的
java.sql.Clob
对象。void
setClob(String parameterName, Reader reader)
将指定的参数设置为
Reader
对象。void
setClob(String parameterName, Reader reader, long length)
将指定的参数设置为
Reader
对象。void
setCommand(String cmd)
将此
RowSet
对象的命令属性设置为给定的SQL查询。void
setConcurrency(int concurrency)
将此
RowSet
对象的并发设置为给定的并发级别。void
setDataSourceName(String name)
将此
RowSet
对象的数据源名称属性设置为给定的String
。void
setDate(int parameterIndex, Date x)
将此
RowSet
对象的命令中的指定参数设置为给定的java.sql.Date
值。void
setDate(int parameterIndex, Date x, Calendar cal)
使用给定的
java.sql.Date
值设置此RowSet
对象的命令中的指定java.sql.Date
。void
setDate(String parameterName, Date x)
使用运行应用程序的虚拟机的默认时区将指定的
java.sql.Date
设置为给定的java.sql.Date
值。void
setDate(String parameterName, Date x, Calendar cal)
使用给定的
Calendar
对象将指定的Calendar
设置为给定的java.sql.Date
值。void
setDouble(int parameterIndex, double x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javadouble
值。void
setDouble(String parameterName, double x)
将指定的参数设置为给定的Java
double
值。void
setEscapeProcessing(boolean enable)
设置此
RowSet
对象的转义处理开启或关闭。void
setFloat(int parameterIndex, float x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javafloat
值。void
setFloat(String parameterName, float x)
将指定的参数设置为给定的Java
float
值。void
setInt(int parameterIndex, int x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javaint
值。void
setInt(String parameterName, int x)
将指定的参数设置为给定的Java
int
值。void
setLong(int parameterIndex, long x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javalong
值。void
setLong(String parameterName, long x)
将指定的参数设置为给定的Java
long
值。void
setMaxFieldSize(int max)
将列值返回的最大字节数设置为给定的字节数。
void
setMaxRows(int max)
将此
RowSet
对象的最大行数设置为指定的数字。void
setNCharacterStream(int parameterIndex, Reader value)
将此
RowSet
对象的命令中的Reader
参数设置为Reader
对象。void
setNCharacterStream(int parameterIndex, Reader value, long length)
将指定的参数设置为
Reader
对象。void
setNCharacterStream(String parameterName, Reader value)
将指定的参数设置为
Reader
对象。void
setNCharacterStream(String parameterName, Reader value, long length)
将指定的参数设置为
Reader
对象。void
setNClob(int parameterIndex, NClob value)
将指定的参数设置为
java.sql.NClob
对象。void
setNClob(int parameterIndex, Reader reader)
将指定的参数设置为
Reader
对象。void
setNClob(int parameterIndex, Reader reader, long length)
将指定的参数设置为
Reader
对象。void
setNClob(String parameterName, NClob value)
将指定的参数设置为
java.sql.NClob
对象。void
setNClob(String parameterName, Reader reader)
将指定的参数设置为
Reader
对象。void
setNClob(String parameterName, Reader reader, long length)
将指定的参数设置为
Reader
对象。void
setNString(int parameterIndex, String value)
将指定的参数设置为给定的
String
对象。void
setNString(String parameterName, String value)
将指定的参数设置为给定的
String
对象。void
setNull(int parameterIndex, int sqlType)
将此
RowSet
对象的SQL命令中的指定参数设置为SQLNULL
。void
setNull(int paramIndex, int sqlType, String typeName)
将此
RowSet
对象的SQL命令中的指定参数设置为SQLNULL
。void
setNull(String parameterName, int sqlType)
将指定的参数设置为SQL
NULL
。void
setNull(String parameterName, int sqlType, String typeName)
将指定的参数设置为SQL
NULL
。void
setObject(int parameterIndex, Object x)
使用Java
Object
设置此RowSet
对象的命令中的Object
。void
setObject(int parameterIndex, Object x, int targetSqlType)
使用Java
Object
设置此RowSet
对象的命令中的Object
。void
setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength)
使用给定的Java
Object
在此RowSet
对象的命令中设置指定的Object
。void
setObject(String parameterName, Object x)
使用给定对象设置指定参数的值。
void
setObject(String parameterName, Object x, int targetSqlType)
使用给定对象设置指定参数的值。
void
setObject(String parameterName, Object x, int targetSqlType, int scale)
使用给定对象设置指定参数的值。
void
setPassword(String password)
将
RowSet
对象的数据库密码设置为给定的String
。void
setQueryTimeout(int seconds)
设置驱动程序等待语句执行到给定秒数的最长时间。
void
setReadOnly(boolean value)
设置此
RowSet
对象是否为只读给定的boolean
。void
setRef(int i, Ref x)
使用给定的
Ref
值设置此RowSet
对象的命令中的指定Ref
。void
setRowId(int parameterIndex, RowId x)
将指定的参数设置为给定的
java.sql.RowId
对象。void
setRowId(String parameterName, RowId x)
将指定的参数设置为给定的
java.sql.RowId
对象。void
setShort(int parameterIndex, short x)
将此
RowSet
对象的命令中的指定参数设置为给定的Javashort
值。void
setShort(String parameterName, short x)
将指定的参数设置为给定的Java
short
值。void
setSQLXML(int parameterIndex, SQLXML xmlObject)
将指定的参数设置为给定的
java.sql.SQLXML
对象。void
setSQLXML(String parameterName, SQLXML xmlObject)
将指定的参数设置为给定的
java.sql.SQLXML
对象。void
setString(int parameterIndex, String x)
将此
RowSet
对象的命令中的指定参数设置为给定的JavaString
值。void
setString(String parameterName, String x)
将指定的参数设置为给定的Java
String
值。void
setTime(int parameterIndex, Time x)
将此
RowSet
对象的命令中的指定参数设置为给定的java.sql.Time
值。void
setTime(int parameterIndex, Time x, Calendar cal)
使用给定的
java.sql.Time
值在此RowSet
对象的命令中设置指定的java.sql.Time
。void
setTime(String parameterName, Time x)
将指定的参数设置为给定的
java.sql.Time
值。void
setTime(String parameterName, Time x, Calendar cal)
使用给定的
Calendar
对象将指定的Calendar
设置为给定的java.sql.Time
值。void
setTimestamp(int parameterIndex, Timestamp x)
将此
RowSet
对象的命令中的指定参数设置为给定的java.sql.Timestamp
值。void
setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
使用给定的
java.sql.Timestamp
值在此RowSet
对象的命令中设置指定的java.sql.Timestamp
。void
setTimestamp(String parameterName, Timestamp x)
将指定的参数设置为给定的
java.sql.Timestamp
值。void
setTimestamp(String parameterName, Timestamp x, Calendar cal)
使用给定的
Calendar
对象将指定的Calendar
设置为给定的java.sql.Timestamp
值。void
setTransactionIsolation(int level)
设置此
RowSet
对象的事务隔离级别。void
setType(int type)
将此
RowSet
对象的类型设置为给定类型。void
setTypeMap(Map<String,类<?>> map)
安装给定
java.util.Map
对象的默认类型映射此RowSet
对象。void
setURL(int parameterIndex, URL x)
将指定的参数设置为给定的
java.net.URL
值。void
setUrl(String url)
设置
RowSet
对象在使用DriverManager
创建连接时将使用的URL。void
setUsername(String name)
将此
RowSet
对象的用户名属性设置为给定的String
。
-
java.sql.rowset.CachedRowSet:
-
-
Modifier and Type Method and Description void
acceptChanges()
传播行更新,插入和删除对此
CachedRowSet
对象的更改对基础数据源。void
acceptChanges(Connection con)
使用指定的
Connection
对象传播所有行更新,插入和删除对此CachedRowSet
对象的数据源的更改,以建立与数据源的连接。boolean
columnUpdated(int idx)
指示此
CachedRowSet
对象的当前行中的指定列是否已更新。boolean
columnUpdated(String columnName)
指示此
CachedRowSet
对象当前行中的指定列是否已更新。void
commit()
每个
CachedRowSet
对象的SyncProvider
包含一个Connection
对象从ResultSet
或JDBC属性传递给它的构造函数。CachedRowSet
createCopy()
创建一个
RowSet
对象,该对象是此CachedRowSet
对象中的数据的深层副本。CachedRowSet
createCopyNoConstraints()
创建一个
CachedRowSet
对象,这是该CachedRowSet
对象的数据的深层副本,但是与之无关。CachedRowSet
createCopySchema()
创建一个
CachedRowSet
对象,该对象是此CachedRowSet
对象的空白副本。RowSet
createShared()
返回一个新
RowSet
通过相同的数据与此的支持对象CachedRowSet
对象。void
execute(Connection conn)
用数据填充此
CachedRowSet
对象,使用给定的连接生成将从中读取数据的结果集。int[]
getKeyColumns()
返回一个数组,其中包含一个或多个列号,表示形成唯一标识此
CachedRowSet
对象行的键的列。ResultSet
getOriginal()
返回一个
ResultSet
此CachedRowSet
对象的原始值的CachedRowSet
对象。ResultSet
getOriginalRow()
返回一个
ResultSet
对象,该对象只包含此CachedRowSet
对象的当前行的原始值。int
getPageSize()
返回
CachedRowSet
对象的页面大小RowSetWarning
getRowSetWarnings()
检索此
RowSet
对象上的呼叫报告的第一个警告。boolean
getShowDeleted()
检索一个
boolean
指示标记为删除的行是否显示在当前行的集合中。SyncProvider
getSyncProvider()
检索
SyncProvider
执行此CachedRowSet
对象。String
getTableName()
返回用于创建此
CachedRowSet
对象的对象(表)的CachedRowSet
。boolean
nextPage()
递增的当前页
CachedRowSet
。void
populate(ResultSet data)
填充此
CachedRowSet
从给定数据对象ResultSet
对象。void
populate(ResultSet rs, int startRow)
填充此
CachedRowSet
从给定数据对象ResultSet
对象。boolean
previousPage()
递减的当前页
CachedRowSet
。void
release()
释放此
CachedRowSet
对象的当前内容,并向所有注册的监听器发送一个rowSetChanged
事件。void
restoreOriginal()
将此
CachedRowSet
对象恢复为其原始值,即其最后一组更改前的值。void
rollback()
每个
CachedRowSet
对象的SyncProvider
包含一个Connection
对象,从原始的ResultSet
或传递给它的JDBC属性。void
rollback(Savepoint s)
每个
CachedRowSet
对象的SyncProvider
包含来自原始ResultSet
或传递给它的JDBC属性的Connection
对象。void
rowSetPopulated(RowSetEvent event, int numRows)
通知已注册的侦听器给定的RowSetEvent对象中的RowSet对象已经填充了许多其他行。
void
setKeyColumns(int[] keys)
使用给定的列号数组来设置此
CachedRowSet
对象的keyCols
字段,该列表形成唯一标识此CachedRowSet
对象中的行的键。void
setMetaData(RowSetMetaData md)
使用给定的
RowSetMetaData
对象设置此CachedRowSet
对象的元数据。void
setOriginalRow()
将此
CachedRowSet
对象中的当前行设置为原始行。void
setPageSize(int size)
设置
CachedRowSet
对象的页面大小。void
setShowDeleted(boolean b)
将属性
showDeleted
设置为给定的boolean
值,该值确定标记为删除的行是否显示在当前行的集合中。void
setSyncProvider(String provider)
设置
SyncProvider
此对象CachedRowSet
对象到指定的一个。void
setTableName(String tabName)
设置此
CachedRowSet
对象派生到给定表名称的表的标识符。int
size()
返回此
CachedRowSet
对象中的行数。Collection<?>
toCollection()
这个转换
CachedRowSet
对象为Collection
包含所有这些对象CachedRowSet
对象的数据。Collection<?>
toCollection(int column)
将此
CachedRowSet
对象中的指定列转换为Collection
对象。Collection<?>
toCollection(String column)
将此
CachedRowSet
对象中的指定列转换为Collection
对象。void
undoDelete()
取消删除当前行并通知侦听器行已更改。
void
undoInsert()
如果已插入该行,则
CachedRowSet
从当前行删除该对象,并通知侦听器行已更改。void
undoUpdate()
如果该行已被修改,立即反转最后一次更新操作。
-
java.sql.rowset.RowSetProvider:
-
-
Modifier and Type Method and Description static RowSetFactory
newFactory()
创建一个
RowSetFactory
实现的新实例。static RowSetFactory
newFactory(String factoryClassName, ClassLoader cl)
从指定的工厂类名称创建一个
RowSetFactory
的新实例。
-
5.3 元数据
第二个元数据接口ResultSetMedaData则用于提供结果集的相关信息。
例:
package view;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.sql.*;
import java.util.*;
import javax.sql.*;
import javax.sql.rowset.*;
import javax.swing.*;
/**
* This program uses metadata to display arbitrary tables in a database.
* @version 1.33 2016-04-27
* @author Cay Horstmann
*/
public class ViewDB
{
public static void main(String[] args)
{
EventQueue.invokeLater(() ->
{
JFrame frame = new ViewDBFrame();
frame.setTitle("ViewDB");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
/**
* The frame that holds the data panel and the navigation buttons.
*/
class ViewDBFrame extends JFrame
{
private JButton previousButton;
private JButton nextButton;
private JButton deleteButton;
private JButton saveButton;
private DataPanel dataPanel;
private Component scrollPane;
private JComboBox<String> tableNames;
private Properties props;
private CachedRowSet crs;
private Connection conn;
public ViewDBFrame()
{
tableNames = new JComboBox<String>();
try
{
readDatabaseProperties();
conn = getConnection();
DatabaseMetaData meta = conn.getMetaData();
try (ResultSet mrs = meta.getTables(null, null, null, new String[] { "TABLE" }))
{
while (mrs.next())
tableNames.addItem(mrs.getString(3));
}
}
catch (SQLException ex)
{
for (Throwable t : ex)
t.printStackTrace();
}
catch (IOException ex)
{
ex.printStackTrace();
}
tableNames.addActionListener(
event -> showTable((String) tableNames.getSelectedItem(), conn));
add(tableNames, BorderLayout.NORTH);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent event)
{
try
{
if (conn != null) conn.close();
}
catch (SQLException ex)
{
for (Throwable t : ex)
t.printStackTrace();
}
}
});
JPanel buttonPanel = new JPanel();
add(buttonPanel, BorderLayout.SOUTH);
previousButton = new JButton("Previous");
previousButton.addActionListener(event -> showPreviousRow());
buttonPanel.add(previousButton);
nextButton = new JButton("Next");
nextButton.addActionListener(event -> showNextRow());
buttonPanel.add(nextButton);
deleteButton = new JButton("Delete");
deleteButton.addActionListener(event -> deleteRow());
buttonPanel.add(deleteButton);
saveButton = new JButton("Save");
saveButton.addActionListener(event -> saveChanges());
buttonPanel.add(saveButton);
if (tableNames.getItemCount() > 0)
showTable(tableNames.getItemAt(0), conn);
}
/**
* Prepares the text fields for showing a new table, and shows the first row.
* @param tableName the name of the table to display
* @param conn the database connection
*/
public void showTable(String tableName, Connection conn)
{
try (Statement stat = conn.createStatement();
ResultSet result = stat.executeQuery("SELECT * FROM " + tableName))
{
// get result set
// copy into cached row set
RowSetFactory factory = RowSetProvider.newFactory();
crs = factory.createCachedRowSet();
crs.setTableName(tableName);
crs.populate(result);
if (scrollPane != null) remove(scrollPane);
dataPanel = new DataPanel(crs);
scrollPane = new JScrollPane(dataPanel);
add(scrollPane, BorderLayout.CENTER);
pack();
showNextRow();
}
catch (SQLException ex)
{
for (Throwable t : ex)
t.printStackTrace();
}
}
/**
* Moves to the previous table row.
*/
public void showPreviousRow()
{
try
{
if (crs == null || crs.isFirst()) return;
crs.previous();
dataPanel.showRow(crs);
}
catch (SQLException ex)
{
for (Throwable t : ex)
t.printStackTrace();
}
}
/**
* Moves to the next table row.
*/
public void showNextRow()
{
try
{
if (crs == null || crs.isLast()) return;
crs.next();
dataPanel.showRow(crs);
}
catch (SQLException ex)
{
for (Throwable t : ex)
t.printStackTrace();
}
}
/**
* Deletes current table row.
*/
public void deleteRow()
{
if (crs == null) return;
new SwingWorker<Void, Void>()
{
public Void doInBackground() throws SQLException
{
crs.deleteRow();
crs.acceptChanges(conn);
if (crs.isAfterLast())
if (!crs.last()) crs = null;
return null;
}
public void done()
{
dataPanel.showRow(crs);
}
}.execute();
}
/**
* Saves all changes.
*/
public void saveChanges()
{
if (crs == null) return;
new SwingWorker<Void, Void>()
{
public Void doInBackground() throws SQLException
{
dataPanel.setRow(crs);
crs.acceptChanges(conn);
return null;
}
}.execute();
}
private void readDatabaseProperties() throws IOException
{
props = new Properties();
try (InputStream in = Files.newInputStream(Paths.get("database.properties")))
{
props.load(in);
}
String drivers = props.getProperty("jdbc.drivers");
if (drivers != null) System.setProperty("jdbc.drivers", drivers);
}
/**
* Gets a connection from the properties specified in the file database.properties.
* @return the database connection
*/
private Connection getConnection() throws SQLException
{
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");
return DriverManager.getConnection(url, username, password);
}
}
/**
* This panel displays the contents of a result set.
*/
class DataPanel extends JPanel
{
private java.util.List<JTextField> fields;
/**
* Constructs the data panel.
* @param rs the result set whose contents this panel displays
*/
public DataPanel(RowSet rs) throws SQLException
{
fields = new ArrayList<>();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++)
{
gbc.gridy = i - 1;
String columnName = rsmd.getColumnLabel(i);
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel(columnName), gbc);
int columnWidth = rsmd.getColumnDisplaySize(i);
JTextField tb = new JTextField(columnWidth);
if (!rsmd.getColumnClassName(i).equals("java.lang.String"))
tb.setEditable(false);
fields.add(tb);
gbc.gridx = 1;
gbc.anchor = GridBagConstraints.WEST;
add(tb, gbc);
}
}
/**
* Shows a database row by populating all text fields with the column values.
*/
public void showRow(ResultSet rs)
{
try
{
if (rs == null) return;
for (int i = 1; i <= fields.size(); i++)
{
String field = rs == null ? "" : rs.getString(i);
JTextField tb = fields.get(i - 1);
tb.setText(field);
}
}
catch (SQLException ex)
{
for (Throwable t : ex)
t.printStackTrace();
}
}
/**
* Updates changed data into the current row of the row set.
*/
public void setRow(RowSet rs) throws SQLException
{
for (int i = 1; i <= fields.size(); i++)
{
String field = rs.getString(i);
JTextField tb = fields.get(i - 1);
if (!field.equals(tb.getText()))
rs.updateString(i, tb.getText());
}
rs.updateRow();
}
}
java.sql.DatabaseMetaData:很多数据库的信息
java.sql.ResultSetNetaData:很多结果集的信息
5.9 事务
将多个语句组合成事务的主要原因是为了确保数据库完整性
5.9.1 用JDBC对事务编程
package Section5;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.sql.rowset.*;
import javax.swing.ImageIcon;
/**
* 连接测试
* @author Roy wang
*
*/
public class testDao extends BaseDao{
public testDao() throws IOException {
try {
Connection conn=getConn();
conn.setAutoCommit(false);
Statement stat = conn.createStatement();
stat.executeUpdate("update person set password='hello' where id=1");
stat.executeUpdate("update person set password='hello' where id=1");
stat.executeUpdate("update person set password='hello9' where id=1");
//conn.commit();//事务提交
conn.rollback(); // 事务回滚
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new testDao();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这样,程序将自动撤销自上次提交以来的所有语句。当事务被SQLException中断时,典型的方法就是发起回滚。
5.9.2 保存点
Connection conn=getConn();
conn.setAutoCommit(false);
Statement stat = conn.createStatement();
stat.executeUpdate("update person set password='h1' where id=1");
Savepoint svpt = conn.setSavepoint(); //设置保存点
stat.executeUpdate("update person set password='h2' where id=1");
if(true)
conn.rollback(svpt);
conn.releaseSavepoint(svpt);
conn.commit();//事务提交
//conn.rollback(); // 事务回滚
5.9.3 批量更新
在使用批量更新时,一个语句序列作为一批操作同时被提交和收集
Connection conn=getConn();
boolean autoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
Statement stat = conn.createStatement();
String command1="create table t1(id int)";
String command2="create table t2(id int)";
String command3="create table t3(id int)";
stat.addBatch(command1);
stat.addBatch(command2);
stat.addBatch(command3);
int[] counts= stat.executeBatch();
conn.commit();
conn.setAutoCommit(autoCommit);
interface java.sql.Savepoint:
-
-
Modifier and Type Method and Description int
getSavepointId()
检索此
Savepoint
对象所代表的保存点的生成ID。String
getSavepointName()
检索此
Savepoint
对象所代表的保存点的名称。
-
5.10 高级SQL类型
5.11 Web与企业应用中的链接管理