DatabaseMetaData
接口
:
通过这个接口中的方法可以查看数据库的整体综合信息
,
DatabaseMetaData
给出的信息描述
DBMS
所提供的事务支持水平
比如
:
查看驱动程序
(
数据库
)
的版本号等
boolean supportsTransactionIsolationLevel (int level):
检索此数据库是否支持给定事务隔离级别
事务
:
什么是事务
?
什么是事物隔离级别
?
事务是一组操作
,
这些操作要么都执行成功
,
要么就都失败
,
例如
:
银行转帐
,
要成功都成功
,
有个失败就都失败
,
这种事务操作是并发执行的
,
同时进行操作
,
当调用方法
commit
或
rollback
时,当前事务即告结束,另一个事务随即开始
什么是并发访问
(
执行
,
操作
)?
多用户访问同一资源
(
表
,
记录
,
数据
)
并发操作可能带来的一些问题
:
脏读
:
包含未提交数据的读取
,
比如说
:
一个用户产生了一个事务
,
修改了一个表的数据
,
另一个用户这时候读取了这个表数据
,
并根据这个表数据做一些操作或分析
,
然而
,
那个用户做了事务的回滚
,
就是取消了一些列操作
,
另一个用户做的操作和分析就没有意义了
,
这个就是脏读
不可重复的读取
:
一个用户读取同一数据好几次
,
在他读的期间有另一个用户修改了该数据
,
这样就会产生读取到的数据不一致
幻觉读
:
是指当事务不是独立执行时发生的一种现象。例如事务
A
对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,事务
B
也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,操作事务
A
的用户就会发现表中还有未修改的数据行,就好象发生了幻觉一样
这些情况发生的根本原因是因为在并发访问的时候,没有一个机制避免交叉存取所造成的
我们可以通过隔离级别设置解决这些问题
事务隔离级别
:
脏读
不可重复读
幻觉读
未提交读
yes yes yes
提交读
no yes yes
可重复读
no no yes
可串行读
no no no
/**
*
知识点
:
*DatabaseMetaData
接口
:
得到数据库驱动程序的全局信息
*
程序目标
:
*JdbcUtil.java:
工具类
*DBMetadata.java:
判断这个数据库都支持哪些事务隔离级别
*
*
*/
package moudule1.data;
import moudule1.com.*;
import java.sql.*;
public class DBMetadata{
public static void main(String[] args)throws Exception{
Connection con=JdbcUtil.getConnection();
DatabaseMetaData dbmd=con.getMetaData();
System.out.println(dbmd.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE));
System.out.println(dbmd.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));
System.out.println(dbmd.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED));
System.out.println(dbmd.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ ));
System.out.println(dbmd.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE));
con.close();
}
}
Java
中的事务的处理
:
/**
*
知识点
:
* java
中事务的处理
* Java
文件
:
* AccountBiz.java:
事务处理的一个方法
* Bank.java:man
方法
*/
package moudule1.sqlException;
import java.sql.*;
import moudule1.sqlException.*;
import moudule1.com.*;
public class Bank{
public static void main(String[] args){
try{
AccountBiz.fangfa(1,2,Integer.parseInt(args[0]));
System.out.println("
成功
");
}catch(Exception e){
System.out.println("
全部失败
");
}
}
}
package moudule1.sqlException;
import java.sql.*;
import moudule1.com.*;
public class AccountBiz{
public static void fangfa(int a,int b,int price)throws Exception{
String sql1 = "update allan_account set balance = balance + " + price + " where id = " + a;
String sql2="update allan_account set balance = balance - " + price + " where id = " + b;
System.out.println(sql1);
System.out.println(sql2);
Connection con=null;
Statement st=null;
try{
con=JdbcUtil.getConnection();
con.setAutoCommit(false);
st=con.createStatement();
st.executeUpdate(sql1);
int row=st.executeUpdate(sql2);
if(row==0){
throw new SQLException();
}
con.commit();
}catch(SQLException e){
try{
con.rollback();
}catch(SQLException es){
}
throw new Exception("
继续抛个异常
,
这是抛给调用此方法的地方
");
}finally{
JdbcUtil.close(con,st);
}
}
}
在
java
中得到结果集的字段信息
:
ResutlSetMetaData
接口可以实现这个目标
Rs.getMetaData()
可以得到
ResutlSetMetaData
接口对象
/**
*
知识点
:
*
得到表中列的信息
*java
文件
:
*ResultSetUtil.java
*testResultSetUtil.java
*/
package moudule1.testResultSetUtil;
import java.sql.*;
import moudule1.com.*;
public class testResultSetUtil{
public static void main(String[] args){
String sql="select * from yuchen_user";
Connection con=null;
Statement st=null;
ResultSet rs=null;
try{
con=JdbcUtil.getConnection();
st=con.createStatement();
rs=st.executeQuery(sql);
ResultSetUtil.print(rs);
}catch(Exception e){
System.out.println("
出错
");
}finally{
JdbcUtil.close(con,st,rs);
}
}
}
package moudule1.com;
import java.sql.*;
public class ResultSetUtil{
public static void print(ResultSet rs)throws SQLException{
ResultSetMetaData rsmd=rs.getMetaData();
int count=rsmd.getColumnCount();
while(rs.next()){
for(int i=1;i<=count;i++){
if(i!=1){
System.out.print(",");
}
String colName=rsmd.getColumnName(i);
String value=rs.getString(colName);
// String value=rs.getString(colName);
System.out.print(colName+"="+value);
}
System.out.println();
}
}
}
项目中关于代码复用的知识
:
1.
采取复用
2.
继承复用
3.
聚合复用
4.
static
工具方法复用
JDBC2.0
特性
:
结果集的特性
:
1.
滚动特性
2.
更新特性
什么是滚动特性
?
在
1.0
中游标只能前进活动
,
但是在
2.0
中游标更加灵活了
,
可向前可向后
绝对定位
,
相对定位
,
向前向后
Scrollabilty
游标控制
向前和向后滚动
绝对和相对游标指定
ResultSet rs=stat.createStatement();
rs.absolute(int a);
rs.afterLast();
rs.beforeFirst();
rs.first();
rs.last();
rs.next();
rs.previous();
rs.relative(int);
rs.isAfterLast();
rs.isBeforeFirst();
rs.isFirst();
rs.isLast();
/**
*
知识点
:
* JDBC2.0
特性
:ResultSet
特性
:
滚动特性
*
程序目标
:
*
测试
ResultSet
滚动特性
* ConnectionFactory.java:
数据库连接对象工厂
* JdbcUtil.java:
关闭资源
* ResultSetScroll.java:
测试类
,
向下读取
,
向上读取
,
绝对读取
,
相对读取
*/
package moudule1.resultset20.youbiao;
import java.sql.*;
import moudule1.com.*;
public class ResultSetScroll {
/**
* @param args
* @throws Exception
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Connection con=null;
Statement st=null;
ResultSet rs=null;
try {
con=ConnectionFactory.getConnection();
st=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs=st.executeQuery("select * from yuchen_user");
xiangxia(rs);
xiangshang(rs);
juedui(rs);
xiangdui(rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(con,st,rs);
}
}
public static void xiangxia(ResultSet rs) throws SQLException{
if(!rs.isBeforeFirst()){
rs.beforeFirst();
}
while(rs.next()){
System.out.print(rs.getInt(1));
System.out.println(rs.getString(2));
}
}
public static void xiangshang(ResultSet rs) throws SQLException{
if(!rs.isAfterLast()){
rs.afterLast();
}
while(rs.previous()){
System.out.print(rs.getInt(1));
System.out.println(rs.getString(2));
}
}
public static void juedui(ResultSet rs) throws SQLException{
rs.absolute(2);
System.out.print(rs.getInt(1));
System.out.println(rs.getString(2));
}
public static void xiangdui(ResultSet rs) throws SQLException{
if(rs.getRow()==0||!rs.last()){
rs.last();
}
while(!rs.isBeforeFirst()){
System.out.print(rs.getInt(1));
System.out.println(rs.getString(2));
rs.relative(-1);
}
}
}
package moudule1.com;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionFactory {
public static Connection getConnection() throws Exception{
Class.forName("oracle.jdbc.driver.OracleDriver");
return DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:name","scott","tiger");
}
}
什么是更新特性
?
第一
,
可修改结果集中的数据
,
并影响数据库的数据
第二
,
可以插入行记录
,
并影响数据库数据
/**
*
知识点
:
* jdbc2.0
特性
:ResultSet
特性
:
数据记录更新特性
:
修改一条记录
*
程序目标
:
* 1.
读取一个表的数据
* 2.
得到结果集后
,
修改结果集中的一条数据
* ConnectionFactory.java
* JdbcUtil.java
* UpdataResultSet.java
*
注意点
:
* 1.sql
语句必须指明要查询的表字段名
* 2.
必须是单表查询
*/
package moudule1.resultset20.updata;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import moudule1.com.ConnectionFactory;
import moudule1.com.JdbcUtil;
public class UpdataResultSet {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String sql="select id,name from laji";
System.out.println(sql);
Connection con=null;
Statement st=null;
ResultSet rs=null;
try {
con=ConnectionFactory.getConnection();
st=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs=st.executeQuery(sql);
while(rs.next()){
System.out.print(rs.getInt(1));
System.out.println(rs.getString(2));
}
rs.absolute(1);
// rs.updateInt(1,10);
rs.updateString(2,"laoda");
rs.updateRow();
System.out.print(rs.getInt(1));
System.out.println(rs.getString(2));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(con,st,rs);
}
}
}
/**
*
知识点
:
* ResultSet
特性
:
更新数据
:
插入一行记录
*
程序目标
:
* 1.
打开一个结果集
* 2.
插入一行数据
* InsertResultSet.java
* ConnectionFactory.java
* JdbcUtil.java
*
注意
:
* 1.
必须有主键字段
* 2.
只能是单表查询出来的结果集
*/
package moudule1.resultset20.updata;
import java.sql.*;
import moudule1.com.*;
public class InsertResultSet {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection con=null;
Statement st=null;
ResultSet rs=null;
try {
con=ConnectionFactory.getConnection();
st=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs=st.executeQuery("select empno,ename from emp");
// rs.absolute(2);
rs.moveToInsertRow();
rs.updateInt(1,3);
rs.updateString(2,"kongming");
rs.insertRow();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(con,st,rs);
}
}
}
Statement
批量更新
(
批处理
):
什么是批处理
?
将一组
sql
语句进行处理
要想执行批处理
,
前提是数据库驱动要支持这个功能
statement
结构
:
PreparedStatement:
动态
sql
CallabeStatement:
存储过程
/**
*
知识点
:
* Statement
批处理
* API:
* Statement
接口
:1.addBatch():
添加
sql
语句
2.executeBatch():
执行一组
* sql
语句
*
程序目标
:
*
批量执行一组
sql
语句
* AcconuntService.java
* ConnectionFactory.java
* JdbcUtil.java
*
*/
package moudule1.Statement20;
import java.sql.*;
import moudule1.com.*;
public class AccountService {
public void addByStatement() throws Exception{
Connection con=null;
Statement st=null;
try {
con=ConnectionFactory.getConnection();
st=con.createStatement();
st.addBatch("insert into yuchen_user (id,name) values (7,'zhu')");
st.addBatch("insert into yuchen_user (id,name) values (8,'liu')");
st.executeBatch();
con.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
con.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
throw e;
}
}
public void addByPreparedStatement() throws Exception{
Connection con=null;
PreparedStatement pst=null;
try {
con=ConnectionFactory.getConnection();
pst=con.prepareStatement("insert into yuchen_user (id,name) values (?,?)");
pst.setInt(1,9);
pst.setString(2,"hello");
pst.addBatch();
pst.setInt(1,11);
pst.setString(2,"world");
pst.addBatch();
pst.executeBatch();
con.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
con.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
throw e;
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
AccountService as=new AccountService();
if(args.length>0){
as.addByStatement();
}else
as.addByPreparedStatement();
}
}
高级数据类型
:sql3
类型
Blob: SQLBlob
Clob: SQLClob
Array:SQL (create type as varray)
Struct:Structure (create type as object )
Ref: SQLref
什么是
Blob
类型
?
可以存储大型二进制对象,如图形、视频剪辑和声音文件等
CREATE TABLE ImageLibrary
(
id number(9) not null,
name varchar2(30) not null,
image blob,
constraint PK_ImageLibrary primary key(id)
)
/**
*
知识点
:
* blob
类型
*
问题
:
* 1.
什么是
blob
类型
,
有什么用
?
*
用来存储大型二进制对象
,
如存储图片
,
图象
,
音频等
* 2.
如何存储在数据库中
,
怎么读
,
怎么存
?
原理是什么
?
*
将一个图片存到数据库
:blob
字段里存放着图片
,
因为是文件
,
使用流
*
从数据库的
blob
字段中得到图片并显示图片
,
因为是文件
,
使用流
* 3.empty_blob()
是什么意思
?
*
这是
oracle
中的函数
,
表达是
:
空
blob
对象
,
可以理解为相当
java
中的
null;
* 4.for update
是什么意思
?
* 5.java
中的
Blob
是什么
,
有什么用
?
* java
和各个数据库中的数据类型都有对应的关系
:
如
java
中的
String
*
对应数据库中的
varchar,varchar2
等
,int
对应
number
等等
,
那么
java
*
中的
Blob
是个数据类型
,
它对应的是数据库中的
blob
类型
* API:
* Blob
接口
:setBinaryStream(long pos):
得到一个输出流
,
这个输出流是将图片等
*
流向数据库中的
blob
类型的字段的
,
可以帮助完成将一个图片写入到数据库
*
参数
pos
表示写入的开头位置
,
从
0
开始
* BufferedInputStream
接口
:int read():
表示以字节为单位进行输入
*
如果返回
-1,
表示到了末尾了也就是读取完毕了
*/
package moudule1.blob;
import java.sql.*;
import moudule1.com.*;
import java.io.*;
public class ImageLibraryService {
public void addImage(long id,String name,String path){
Connection con=null;
// Statement st=null;
PreparedStatement pst=null;
ResultSet rs=null;
try {
con=ConnectionFactory.getConnection();
con.setAutoCommit(false);
pst=con.prepareStatement("insert into ImageLibrary (id,name,image) values (?,?,empty_blob())");
pst.setLong(1,id);
pst.setString(2,name);
pst.executeUpdate();
JdbcUtil.close(pst);
pst=con.prepareStatement("select image from ImageLibrary where id=? for update");
pst.setLong(1,id);
rs=pst.executeQuery();
if(rs.next()){
Blob blob=rs.getBlob(1);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(path));
OutputStream os=blob.setBinaryStream(0);
BufferedOutputStream bos=new BufferedOutputStream(os);
int c;
while((c=bis.read())!=-1){
bos.write(c);
}
bis.close();
bos.close();
}
con.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
con.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
JdbcUtil.close(con,pst,rs);
}
}
public void restoreImage(long id,String filename){
Connection con=null;
PreparedStatement pst=null;
ResultSet rs=null;
try {
con=ConnectionFactory.getConnection();
pst=con.prepareStatement("select image from ImageLibrary where id=?");
pst.setLong(1,id);
rs=pst.executeQuery();
if(rs.next()){
Blob blob=rs.getBlob(1);
InputStream is=blob.getBinaryStream();
BufferedInputStream bis=new BufferedInputStream(is);
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(filename));
int c;
while((c=bis.read())!=-1){
bos.write(c);
}
bis.close();
bos.close();
}
con.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
con.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
JdbcUtil.close(con,pst,rs);
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ImageLibraryService is=new ImageLibraryService();
if(args.length==3){
is.addImage(Long.parseLong(args[0]),args[1],args[2]);
}else
is.restoreImage(Long.parseLong(args[0]),args[1]);
}
}
什么是
Clob?
相当与
long
型
,
但是比它性能还要好
,
用于字符型的存储
,
使用字符流处理读取对象
一、
CLOB
对象的存取
1 、往数据库中插入一个新的 CLOB 对象
public static void clobInsert(String infile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 插入一个空的 CLOB 对象 */
stmt.executeUpdate("INSERT INTO TEST_CLOB VALUES ( ’ 111 ’ , EMPTY_CLOB())");
/* 查询此 CLOB 对象并锁定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID= ’ 111 ’ FOR UPDATE");
while (rs.next()) {
/* 取出此 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 向 CLOB 对象中写入数据 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
2 、修改 CLOB 对象(是在原 CLOB 对象基础上进行覆盖式的修改)
public static void clobModify(String infile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询 CLOB 对象并锁定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID= ’ 111 ’ FOR UPDATE");
while (rs.next()) {
/* 获取此 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 进行覆盖式修改 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
3 、替换 CLOB 对象(将原 CLOB 对象清除,换成一个全新的 CLOB 对象)
public static void clobReplace(String infile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 清空原 CLOB 对象 */
stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID= ’ 111 ’ ");
/* 查询 CLOB 对象并锁定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID= ’ 111 ’ FOR UPDATE");
while (rs.next()) {
/* 获取此 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 更新数据 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
4 、 CLOB 对象读取
public static void clobRead(String outfile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询 CLOB 对象 */
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID= ’ 111 ’ ");
while (rs.next()) {
/* 获取 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 以字符形式输出 */
BufferedReader in = new BufferedReader(clob.getCharacterStream());
BufferedWriter out = new BufferedWriter(new FileWriter(outfile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
out.close();
in.close();
}
} catch (Exception ex) {
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
1 、往数据库中插入一个新的 CLOB 对象
public static void clobInsert(String infile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 插入一个空的 CLOB 对象 */
stmt.executeUpdate("INSERT INTO TEST_CLOB VALUES ( ’ 111 ’ , EMPTY_CLOB())");
/* 查询此 CLOB 对象并锁定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID= ’ 111 ’ FOR UPDATE");
while (rs.next()) {
/* 取出此 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 向 CLOB 对象中写入数据 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
2 、修改 CLOB 对象(是在原 CLOB 对象基础上进行覆盖式的修改)
public static void clobModify(String infile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询 CLOB 对象并锁定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID= ’ 111 ’ FOR UPDATE");
while (rs.next()) {
/* 获取此 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 进行覆盖式修改 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
3 、替换 CLOB 对象(将原 CLOB 对象清除,换成一个全新的 CLOB 对象)
public static void clobReplace(String infile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 清空原 CLOB 对象 */
stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID= ’ 111 ’ ");
/* 查询 CLOB 对象并锁定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID= ’ 111 ’ FOR UPDATE");
while (rs.next()) {
/* 获取此 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 更新数据 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
4 、 CLOB 对象读取
public static void clobRead(String outfile) throws Exception
{
/* 设定不自动提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询 CLOB 对象 */
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID= ’ 111 ’ ");
while (rs.next()) {
/* 获取 CLOB 对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 以字符形式输出 */
BufferedReader in = new BufferedReader(clob.getCharacterStream());
BufferedWriter out = new BufferedWriter(new FileWriter(outfile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
out.close();
in.close();
}
} catch (Exception ex) {
conn.rollback();
throw ex;
}
/* 恢复原提交状态 */
conn.setAutoCommit(defaultCommit);
}
Array
类型
:
对应的是
sql
中的自定义类型
/**
*
知识点
:
* Array--sql varray(
自定义类型
)
*
问题
:
* 1.
什么是
array
类型
?
有什么用的
?
*
在数据库中自定义类型可以存放一组值
,
这组值是什么类型自己可以设置
*
例如
:
可以用来存放用户的注册信息等等
* API:
* ResultSet
接口
:Array getArray(
列的位置号
):
从指定的表列中读取该列的
*
值
,
这个值是
java Array
对象
,Array
接口相当于指针
,
指向这个值
* Array
接口
:Object getArray():
得到
Array
对象中的元素值
,
一般把它强制
*
转换为
String[]
类型
,
然后可以打印出来
*
程序目标
:
* JdbcUtil.java
* ConnectionFactory.java
* UserService.java
*
读取带有自定义类型的表中的数据
*/
package moudule1.sql3.array;
import java.sql.*;
import moudule1.com.*;
public class UserService {
public static void addArray(){
Connection con=null;
Statement st=null;
try {
String sql = "insert into User_Array(id, username, password, hobbies) values ";
sql += "(1, 'alan', '123', HOBBIES('swim', 'walking', 'reading', 'skating', 'shooting'))";
con=ConnectionFactory.getConnection();
st=con.createStatement();
st.executeUpdate(sql);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(con,st);
}
}
public static void readArray(){
Connection con=null;
Statement st=null;
ResultSet rs=null;
try {
con=ConnectionFactory.getConnection();
st=con.createStatement();
rs=st.executeQuery("select id,username,password,hobbies from User_Array");
while(rs.next()){
System.out.print(rs.getInt(1));
System.out.print(","+rs.getString(2));
System.out.print(","+rs.getString(3));
Array array=rs.getArray(4);
String[] arr=(String[])array.getArray();
System.out.print(", hobbies {");
for(int i=0;i<arr.length;i++){
if(i!=0){
System.out.print(",");
}
System.out.print(arr[i]);
}
System.out.println("}");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(con,st,rs);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
if(args.length==1){
UserService.addArray();
}else
UserService.readArray();
}
}
Struct:Structure (create type as object )
把
sql
中的
Structure
看成是一个对象类型
,
里面包含属性值
,java
中的
Struct
接口就是指向这个对象类型中的属性值的
CREATE TYPE CourseStruct AS object
(
no varchar2(10),
name varchar2(60),
fee number(5)
)
/
CREATE TABLE Student_Struct
(
id number(9),
name varchar2(20),
attendcourse CourseStruct,
constraint PK_Student primary key(id)
)
/
/**
*
知识点
:
* Struct---Structure(create type
名字
as Object)
*
问题
:
* API:
* StringBuffer
类
:StringBuffer delete(int s,int end):
删除
StringBuffer
中
*
的字符
,
参数
:
可以指定删除哪一段
*
程序目标
:
*
写入并读取含有
Structure
类型的字段的表中的值
*/
package moudule1.sql3.struct;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Struct;
import moudule1.com.ConnectionFactory;
import moudule1.com.JdbcUtil;
public class StudentService
{
public void addStudents()
{
Connection con = null;
Statement st = null;
try
{
con = ConnectionFactory.getConnection();
st = con.createStatement();
StringBuffer sql = new StringBuffer();
sql.append("insert into Student_Struct(id, name, attendcourse) ");
sql.append("values(1, 'Alan', CourseStruct('c001', 'Object Orient Programming With Java', 13800))");
System.out.println(sql.toString());
st.executeUpdate(sql.toString());
sql.delete(0, sql.length());
sql.append("insert into Student_Struct(id, name, attendcourse) ");
sql.append("values(2, 'elen', CourseStruct('c002', 'Mastering asp.net Using C#', 10000))");
System.out.println(sql.toString());
st.executeUpdate(sql.toString());
} catch (Exception e)
{
e.printStackTrace();
} finally
{
JdbcUtil.close(con, st);
}
}
public void showStudents()
{
Connection con = null;
Statement st = null;
ResultSet rs = null;
try
{
con = ConnectionFactory.getConnection();
st = con.createStatement();
rs = st.executeQuery("select id, name, attendcourse from Student_Struct order by id");
while (rs.next())
{
System.out.print("id = " + rs.getLong(1));
System.out.print(",name = " + rs.getString(2));
System.out.println(",attendcourse = {");
Struct course = (Struct) rs.getObject("attendcourse");
Object[] attributes = course.getAttributes();
System.out.print("no = " + attributes[0]);
System.out.print(",name = " + attributes[1]);
System.out.println(", fee = " + attributes[2]);
System.out.println("}");
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
JdbcUtil.close(con, st, rs);
}
}
public static void main(String[] args)
{
StudentService service = new StudentService();
if (args.length == 0)
{
service.showStudents();
} else
{
service.addStudents();
}
}
}
ref:
CREATE TABLE Course_Tbl of CourseStruct
INSERT INTO Course_Tbl VALUES ('c001', 'java', 13800)
INSERT INTO Course_Tbl VALUES ('c002', 'c++', 3000)
INSERT INTO Course_Tbl VALUES ('c002', 'dot net', 8000)
说明
:CourseStruct
为
struct
类型
,
上个例子已经创建了该类型
/**
*
知识点
:
* ref
*/
package linshi.allanlxf.jdbc.sql3;
import java.sql.Connection;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Struct;
import moudule1.com.ConnectionFactory;
import moudule1.com.JdbcUtil;
/**
* @author alan
* @version 1.0
*/
public class CourseService
{
public void showCourses()
{
Connection con = null;
Statement st = null;
ResultSet rs = null;
try
{
con = ConnectionFactory.getConnection();
st = con.createStatement();
rs = st.executeQuery("select ref (x) from Course_Tbl x");
while (rs.next())
{
Ref courseRef = (Ref) rs.getObject(1);
Struct course = (Struct) courseRef.getObject();
Object[] courseAttributes = course.getAttributes();
System.out.print("x[no = " + courseAttributes[0]);
System.out.print(",name = " + courseAttributes[1]);
System.out.print(",fee = " + courseAttributes[2]);
System.out.println("]");
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
JdbcUtil.close(con, st, rs);
}
}
public static void main(String args[]) throws Exception
{
CourseService service = new CourseService();
service.showCourses();
}
}
综合例子
:
package moudule1.com;
import java.sql.*;
public class JdbcUtil{
public static Connection getConnection() throws Exception{
Class.forName("oracle.jdbc.driver.OracleDriver");
return DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:name", "scott","tiger");
}
public static void close(Connection con,Statement st){
close(con);
close(st);
}
public static void close(Connection con,Statement st,ResultSet rs){
close(con,st);
close(rs);
}
public static void close(Connection con){
try{
con.close();
}catch(Exception e){
}
}
public static void close(Statement st){
try{
st.close();
}catch(Exception e){
}
}
public static void close(ResultSet rs){
try{
rs.close();
}catch(Exception e){
}
}
public static void close(ResultSet rs,Statement st){
close(st);
close(rs);
}
public static Timestamp gettime(Connection con){
PreparedStatement pst=null;
ResultSet rs = null;
Timestamp time = null;
try {
pst=con.prepareStatement("select sysdate from dual");
rs=pst.executeQuery();
rs.next();
time=rs.getTimestamp(1);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
JdbcUtil.close(rs, pst);
}
return time;
}
}
/**
*
知识点
:
* Oracle
数据库的综合访问
* API:
* 1.Date
类
:static Date valueOf(String date):
将输入的字符串时间转化为
* Date
的值
* 2.ResultSet:getTimestamp():
得到表中的时间值
*/
package moudule1.sql3.zonghe;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import moudule1.com.*;
public class UserAction
{
public void addUser(int id, String name, Date birthday) throws Exception
{
Connection con = null;
PreparedStatement ps = null;
try
{
con = ConnectionFactory.getConnection();
ps = con.prepareStatement("insert into sys_user(id, name, birthday, cretime) values(?, ?, ?, ?)");
ps.setInt(1, id);
ps.setString(2, name);
ps.setDate(3, birthday);
ps.setTimestamp(4, JdbcUtil.gettime(con));
ps.executeUpdate();
}catch(Exception e)
{
e.printStackTrace();
}finally
{
JdbcUtil.close(con, ps);
}
}
public void showUsers() throws Exception
{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
con = ConnectionFactory.getConnection();
ps = con.prepareStatement("select * from sys_user");
rs = ps.executeQuery();
while(rs.next())
{
System.out.println(rs.getInt("id"));
System.out.println(rs.getString("name"));
System.out.println(rs.getDate("birthday"));
System.out.println(rs.getTimestamp("cretime"));
}
}catch(Exception e)
{
e.printStackTrace();
}finally
{
JdbcUtil.close(con, ps);
}
}
public static void main(String[] args) throws Exception
{
UserAction action = new UserAction();
if(args.length > 0)
{
action.addUser(2, "guest", Date.valueOf("1985-09-09"));
}else
{
action.showUsers();
}
}
}