JavaJDBC访问数据库.docx
《JavaJDBC访问数据库.docx》由会员分享,可在线阅读,更多相关《JavaJDBC访问数据库.docx(33页珍藏版)》请在冰点文库上搜索。
JavaJDBC访问数据库
数据库和JDBC
一.概述:
当今的程序设计离不开数据库编程,几乎所有的Java项目都是用到数据库.JDBC是Java语言操作数据库的一种技术,其实质是封装了对数据库操作的一组类.JDBC和数据库技术密切相关.常用的Sql语句(Select,Insertupdate,delete等)都会使用.
二.JDBC驱动程序的类型
JDBC是JavaDatabaseConnectivity的缩写,由一些Java类和接口组成。
事实上,JDBC已经成为Java开发人员访问数据库的标准API.
JDBC主要完成三件事:
连接数据库,发出Sql语句,处理DBMS返回的结果集。
(一).JDBC驱动程序类型
共有4种类型jDBC驱动程序。
选择何种类型取决于程序的应用范围。
正确选择合适的驱动程序,使之符合数据库程序的设计,是提高程序性能必须考虑的一个方面。
1.类型1驱动程序(JDBC-ODBC桥)
又称为JDBC_ODBC桥驱动。
它是把JDBC操作翻译为对应的ODBC调用,其优点是可以访问ODBC能访问的所有数据库,缺点是执行效率比较低。
2.类型2驱动程序(本地API半Java驱动程序)
它是一部分API用Java来编写的驱动程序,这种类型的驱动程序把客户机上的
JDBC调用转换为Oracle,Sybase,Db2等主流数据库API的本机调用。
就是说,这种
方式需要在Java程序执行的机器上安装本地的针对特定数据库的驱动程序,通过这
个程序把对数据库的JDBC调用转换为数据库的API调用,其性能比JDBC-ODBC方式
好一些。
缺点是需要安装驱动程序。
也就是说,它直接将应用程序与网络库连接,所以必须要在使用此驱动程序的
计算机上安装网络库。
3.类型3驱动程序(JDBC-NET纯Java驱动程序)
将应用程序与中间件连接,进而允许客户与后端多个数据库连接。
就是说,中间件
服务器将应用程序的JDBC调用映射到适当的数据库驱动程序。
这些数据库驱动程序安装在中间件服务器上。
而不是安装在客户机上。
其优点是:
客户机上不需要安装网络库;便于利用中间件服务器的poor(池)驱动程序
4.类型4驱动程序(本地协议纯java驱动程序)
把JDBC操作直接转换成不使用ODBC或本机API的本机协议。
这种驱动程序完全是用java实现的,不需要其它驱动程序或网络库。
此类数据库驱动程序是数据库厂商提供的,能够提供对于本公司数据库系统的最优化访问。
简言之:
这种类型不需要数据库客户端网络驱动程序,通过数据库驱动程序包直接访问数据库即可,故该方式又称”直连方式”。
Sun公司建议最好使用第3,4,型驱动程序。
(二).数据库连接的种类:
分为两种:
直接连接,池连接。
1.直接连接
直接连接是直接在客户端java代码中打开并维护的。
对应于类型1,2,4驱动
程序。
2.池连接
池连接是由J2EE服务器打开和维护的。
J2EE服务器启动时会建立一定数量的池连接。
并一直维持不少于此数目的池连接。
客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其标记为忙。
如果当前没有空闲的连接,池驱动程序就新建一定数量的连接,新建连接的数量由配置参数决定。
当使用池连接的调用完成后,池驱动程序将此连接标记为空闲,这样其它调用又可以使用这个连接。
(三)。
JDBC体系结构
三.JDBC操作数据库涉及到的包和类
1.必需的包:
java..sql.(核心API)。
javax..sql.(扩展API)
2.涉及到的类和接口:
2.1.Class类:
该类方法主要用来加载驱动程序
2.2.DriverManager类:
用于获得Connection对象
2.3.Connection接口:
用于创建Statement及其子类对象
2.4.Statement类:
用于执行一个Sql语句
2.5.PreparedStatement类:
用于执行一个带有参数的Sql语句,,可提高Sql执行性能.
2.6.CallableStatement类:
用于执行存储过程,
2.7.ResultSet接口:
该类方法用于操作结果集。
四.Class类
在JDBC中该类用于加载数据库驱动程序
1.静态方法:
forName(StringdriverName)//加载驱动程序
例如:
forName(“sun.jdbd.odbc.JdbcOdbcDriver”);//加载JDBC-ODBC桥驱动程序
2.。
说明:
sun建议:
对于后台数据库为sqlserver,oraclem,db2,sybase等,使用下列形式
加载驱动程序:
Class.forName(“oracle.jdbc.driver.OracleDriver”).newInstance();
五.DriverManager类
该类的静态方法可以获得连接对象.
1.静态方法:
1.1.返回Connection对象
ConnectiongetConnection(StringUrl,StringUserName,StringPassword);
ConnectiongetConnection(StringUrl,);
ConnectiongetConnection(StringUrl,Propertiesinfo);
参数Url连接数据库的JDBCUrl。
由三部分组成:
协议标识:
总是”jdbc”;
驱动程序名或数据库连接机制:
如oracle:
thin
数据库标识:
如10.80.1.2:
1512:
RkDB
info表示user-password对
1.2.设置数据库连接时的最长等待时间
voidsetLoginTimeout(intsecond)
六.Connection接口
用来获得各种语句对象
1.实例方法:
1.1.StatementcreateStatement()//创建语句
1.2.StatementcreateStatement(ResultSet.Type_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY)//创建语句
第一个参数可以是下列常数:
ResultSet.TYPE_FORWORD_ONLY//只向前
ResultSet.Type_SCROLL_INSENSITIVE//对外界作的修改不敏感
ResultSet.TYPE_SCROLL_SENSITIVE//对外界作的修改敏感
第二个参数可以是下列常数:
ResultSet.CONCUR_READ_ONLY//只读记录
ResultSet.CONCUR_UPDATEBLE//允许对结果集修改,如果要通过结集
修改(包括插入、删除)记录,必须如此设置。
1.3.PreparedStatementprepareStatement(StringSql);//创建带参数Sql语句,
参数用?
号代替。
然后用SetXXX(intFieldNo)为某个?
号赋值(第一个?
号的索因为1),注意顺序!
1.4.CallableStatementprepareCall(StringSql);//创建存储过程Sql语句,
Sql格式为:
“{call<存储过程名称>}”
1.5.close()关闭连接对象
七.Statement,PreparedStatement,CallableStatement接口
1.实例方法:
1.1.setXXX(intparaNo,objectval)//设置参数类型和值
例setString(1,”Hello”);
1.2.setBinaryStream(2,FileInputStreamfis,intLength)//设置大对象的值,
1.3.ResultSetexecuteQuery(Stringsql)该类用于返回一个Result对象
1.4.booleanexecute(Stringsql)
返回true,表示执行了一个查询语句;返回false表示执行一个非查询语句
通常用来处理多结果集的语句。
1.5.执行一个非查询语句
intResultSetexecuteUpdate(StringnoQuery)
intResultSetexecuteUpdate(StringnoQuery,intop)
用于执行一个非查询语句,并返回该语句影响的记录数.
参数noQuery表示非查询语句,op为常数。
例如,获得新插入记录的主键值,可以取Statement.RETURN_GENERATED_KEYS
1.6.int[]executeBatch()throwsSQLException;
用于执行多个没有结果集返回的Sql语句,其返回值为各个语句执行后影响的
记录数。
下面的两个方法用于向语句中添加要更新的Sql语句和删除所有更
新的Sql语句。
addBatch(StringsqlUpdate)
clearBatch()
例如:
Connectionconn;
……
Statementst=conn.createStatement();
st.addBatch(“Insertintostudent(sid,xbbm,xm)values('880077','2','王红')”);
st.addBatch(“deletefromstudent”);
int[]affactCount=st.executeBatch();
1.7.ResultSetgetResultSet()获得用execute语句执行后的有结果集返回的结果集
1.8.intgetUpdateCount()获得用execute语句执行后的无结果集返回的语句影
响的记录数
1.9.booleangetMoreResultSets()获得更多的结果集,如果有,返回true
1.10.setMaxRows(intmaxRows)//设置结果集返回的最大行数。
说明:
1.7,1.9通常用于执行返回多个结果集的情况
1.11.获得新插入记录的主键值
ResultSetgetGeneratedKeys();
当一个数据表有一个自动产生值的主键字段(如sqlserver,mySql),如果
要获得刚插入记录的新的主键之值,可以在执行插入操作之后,接着调用这个
方法,从而获得需要的主键的值。
记住,在执行插入语句时,要带常数
Statement.RETURN_GENERATED_KEYS,见下例。
例如:
test表由三个字段,其中id为自动产生值的主键字段
Stringsql=”insertintotest(name,age)values(‘王红’,13)”;
Statementst=conn.createStatement();
st.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);//添加新记录
ResultSetrs=st.getGeneratedKeys()//获得包含主键的ResultSet对象
//输出查询结果
if(rs.next()){
System.out.println(“id”+rs.geTInt
(1);
}
1.12.获得Sqlserver数据库新插入记录的自动编号
Stringsql=”insertintotest(name,age)values(‘王红’,13)”;
Sql+="Select@@IDENTITYasid";//拼接Sqlserver专用语句
//Sql+="Selectmax(id)fromtest";//拼接select语句
st=conn.createStatement();
ResultSetrs=st.executeQuery(insertSql);
if(rs.next()){
retPrimaryKey=rs.getInt
(1);
System.out.println("插入记录的id==>"+retPrimaryKey);
System.out.println("插入成功!
");
}
1.1.3.执行多个查询语句的基本操作
A.构造一个由多个查询语句组成的字符串,每两个查询语句之间用分号”;”分隔。
B.执行语句对象的execute方法,并获得返回值。
C.检查上一步的返回值,如果为true,可以用调用语句对象的方法getResultSet
获得一个结果集。
然后处理这个结果集;处理完结果集后,再次调用语句对象的
getMoreResults()获得下一个结果集,如果返回true,则可以继续处理这个结
果集。
例:
一次执行两个Select语句
sql="select*fromcityInfo;selectcount(*)fromcityInfo";
Statementps=conn.createStatement();
booleanbSuccess=ps.execute(sql);//执行Sql语句
if(bSuccess){//至少有一个结果集
rs=ps.getResultSet();//获得一个结果集
//处理结果集
rs.close(); //关闭结果集
bSuccess=ps.getMoreResults();//获得下一个结果集
if(bSuccess){//有下一个结果集
rs=ps.getResultSet();//获得结果集
//处理结果集
}
……
}
ps.close();
说明:
如果多个结果集结构相同,则可以用循环统一处理这些结果集
八.ResultSet接口
1.获得ResultSet实例
ResultSet.executeQuery(Stringsql)
2.实例方法:
2.1.移动记录指针
2.1.1.通用方法
booleannext()
移动记录集指针到下一记录,未到达结果集末尾,则返回true,否则,返回false;
注意:
首次获得一个记录集时,记录集指针位于第一条记录之前的
位置,因此,应当首先调用一次next()函数,才能读取记录。
用于滚动查询的方法
booleanprevious()
记录集指针向上移动,到达第一条记录之前时,返回false,否则返回true
booleanisBeforFirst()
记录集指针到达第一条记录之前时,返回true,否则返回false
booleanisAfterLast()
记录集指针到达最后一条记录之后时,返回true,否则返回false
booleanisFirst()
记录集指针到达第一条记录位置时,返回true,否则返回false
booleanisLast()
记录集指针到达最后一条记录位置时,返回true,否则返回false
voidbeforeFirst()
移动记录集指针到达第一条记录之前
voidafterLast()
移动记录集指针到达最后一条记录之后
voidfirst()
移动记录集指针到达第一条记录
voidlast()
移动记录集指针到达最后一条记录.与getRow()配合使用,
常用来获得结果集的总行数.例:
rs.last();
inttotalRow=rs.getRow();//获得总行数
intgetRow()获得当前行的行号。
记录集的第一行行号为1,第二行行号为2…
booleanabsolute(introw)
移动记录集指针到第row行记录。
Row=1,2,…正向移动;
Row=-1,-2,…反向移动,-1表示最后一行记录
2.2.获得字段的值
2.2.1获得子字符串类型字段的值
StringgetString(intFieldNo)获得当前记录索引为fieldNo的字段的值
StringgetString(StringFieldName)获得当前记录字段名称为FieldName的值
2.2.2.获得整数类型字段的值
intgetInt(intFieldNo),getInt(StringFieldName),
longgetLong(intFieldNo),longgetLong(StringFieldName)
2.2.3.获得上精度类型字段的值
doublegetDouble(intFieldNo),doublegetDouble(StringFieldName)
2.2.4.获得日期类型字段的值
DategetDate(intFieldNo),DategetDate(StringFieldName)
2.2.5.获得布尔类型字段的值
booleangetBoolean(intFieldNo),booleangetBoolean(StringFieldName)
2.2.6.获得二进制类型字段或大文本类型字段的值
BlobgetBlob(intFieldNo),getBlob(StringFieldName)
获得字段类型为Blob的当前值,返回值为一个Blob对象,可以将
这个对象与流关联起来,进而对其实际内容进行操作。
ClobgetClob(intFieldNo),getClob(StringFieldName)
获得字段类型为Clob的当前值
2.2.7.获得任意类型字段的值
ObjectgetObject(intFieldNo),getObject(StringFieldName),
说明:
getXXX(StringColumnName)//获得当前记录字段的值,
如getString(“dm”)将获得当前记录”dm”字段的值,比返回一个字符串。
2.3.获得数据库对象元数据
ResultSetMetaDatagetMetaData()获得数据库对象的元数据
2.4.删除当前记录
deleteRow()
2.5.修改当前记录
updateString(StringFieldName,Stringvalue)//更新当前记录的字符串字段
rs.updateBinaryStream(StringFieldName,InputStreamin,intlength)
updateInt(“<字段名>”,”新值”)
updateXXX(“<字段名>”,”新值”)//XXX表示字段类型,如updateDouble()
updateRow()更新当前行//需要利用事务才能有效(物理更改,而不是缓冲区)
例:
conn.setAutoCommit(false);
rs.updateString(“tele”,”9978”)//修改当前记录字段tele
rs.updateRow();
…
mit()
…
conn.setAutoCommit(true);
2.4.插入记录
moveToInsertRow()
//移动记录指针到插入缓冲区(这个缓冲区与结果集结构完全相同)。
updateXXX(“<字段名>”,”新值”)//为新的记录各个字段赋予新的值
insertRow()//将新记录插入到数据表中。
九.使用JDBC元数据
元数据就是用于描述数据的数据。
JDBC提供了三个元数据接口:
DatabaseMetaData.,ResultSetMetaData,ParameterMetaData.
其中DatabaseMetaData提供了数据库以及DBMS的相关信息。
ResultSetMetaData提供了结果集对象中的列的相关信息。
ParameterMetaData.提供了PreparedStatement或CallableStatement对象中的参数
的相关信息
1.DatabaseMetadata接口
主要用于在需要动态获取数据库以及DBMS的信息时使用,通过连接对象可以
1.1.获得一个DatabaseMetadata对象
DatabaseMetadata.getMetaData()
1.2.方法:
大约有150个方法。
常用的方法如下:
getDriverName()
getURL()
getUserName()
getDatabaseProductName()
2.ResultSetMetaData接口
通过本接口可以获得一个未知记录集的所有字段名称。
2.1.获得ResultSetMetaData实例
ResultSetMetaData<.ResultSet对象>.getMetaData()
2.2.方法:
StringgetColumnLabel(intFieldNo)//获得索引为FieldNo的字段描述
StringgetColumnName(intFieldNo)//获得索引为FieldNo的字段名
intgetColumnCount()获得结果集的总列数
十.存储过程调用的基本方法及其步骤
1.获得CallableStatement对象
CallableStatementcst=conn.prepareCall(“{CallprocedureName(?
?
?
)}”);
2.为存储过程提供参数值
cst.setXXX(intindex,Objectv);cst.setXXX(StrngfieldName,Objectv);
如果参数是输出参数(包括输入输出参数),则为了获得它的值,需要调用方法
registerOutParameter(intfieldIndex,类型)为输出参数注册数据类型
3.执行存储过程
boolean.execute()
int.executeUpdate()
例:
执行存储过程storeName
存储过程storeName最后一个参数为输入输出参数
StringstrSql=”{callstor