JDBC.ppt_第1页
JDBC.ppt_第2页
JDBC.ppt_第3页
JDBC.ppt_第4页
JDBC.ppt_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

jdbc 编程,目标,jdbc技术概述 通过jdbc技术 与数据库建立连接 了解数据库的信息 查询数据库 检索结果集 更新数据库 参数的输入和输出 总结,jdbc技术概述,jdbc是用于执行sql的java api,它将数据库存取的api与sql陈述分开,实现数据库无关的api接口,藉由jdbc统一的接口,开发人员只要专注于sql陈述,而可以不必理会底层的数据库驱动程序与相关接口。 使用jdbc,由厂商实作数据库的接口,而sql的操作部份由java程序设计人员负责,如果要更换驱动程序,则只要加载新的驱动程序来源即可,java 程序的部份则无需改变。 简单的说,jdbc让java程序设计人员在编写数据库程序的时候,可以写一个程序,适用所有的数据库。,jdbc的特点,在sql水平上的api 为java语言定义的一个sql调用级界面,其中心在于执行基 本的sql 声明和取回结果。在此基础上可以定义更高层次的 与sql的一致性 jdbc允许使用从属于dbms的系统的任何查询语句,一个应用程序可以尽可能的使用sql功能。 用户至少使用ansi sql 92 entry level标准 可在现有的数据库接口之上实现 比如可以在odbc之上实现,提供与其他java系统一致的java界面 简单易行,最大可能简单化 使用健壮、静态的通用数据类型。 使一般情形简单化 多种方法、多种功能,下图jdbc api、数据库驱动程序与数据库之间的关系:,jdbc数据库驱动程序依实作方式可以分为四个类型: type 1:jdbc-odbc bridge 使用者的计算机上必须事先安装好odbc驱动程序,type 1驱动程序利用bridge的方式将jdbc的调用方式转换为odbc的调用方式,用于microsoft access之类的数据库存取: application jdbc-odbc bridge odbc driver database,type 2:native-api bridge 驱动程序上层包装java程序以与java应用程序作沟通,将jdbc调用转为原生程序代码的调用,下层为原生语言(像是c、c+)来与数据库作沟通,下层的函式库是针对特定数据库设计的,不若type 1可以对odbc架构的数据库作存取: application native-api bridge native driver database,type 3:jdbc-middleware 通过中间件来存取数据库,使用者不必安装特定的驱动程序,而是由驱动程序调用中间件,由中间件来完成所有的数据库存取动作,然后将结果传回给驱动程序: application jdbc-middleware middleware database,type 4:pure java driver 使用纯java编写驱动程序与数据库作沟通,而不通过桥接或中间件来存取数据库: application pure java driver database mysql的jdbc驱动程序属于type 4,称之为connector/j,目前有支持jdbc 2.0与jdbc 3.0的版本,您可以在以下的网站取得: /products/connector-j/index.html,连接数据库,为了要联机mysql数据库,您必须要有mysql jdbc驱动程序,请将下载的mysql-connector-java-*.jar加入至classpath中,这边先以java class来示范如何联机mysql,java类别中与数据库操作相关的类别都位于java.sql套件中。 要联机mysql,必须经由几个动作:,加载与注册jdbc驱动程序 通过java.lang.class类别的forname()来加载并向drivermanager注册jdbc驱动程序(驱动程序会自动通过drivermanager.registerdriver()方法注册), mysql的驱动程序类别是com.mysql.jdbc.driver,您如下加载与注册jdbc驱动程序: try class.forname(“com.mysql.jdbc.driver“); catch(classnotfoundexception e) system.out.println(“找不到驱动程序类别“); 如果找不到com.mysql.jdbc.driver类别,就会抛出 classnotfoundexception,这时请确定您的classpath中是否包括了mysql-connector-java-*.jar的位置。,提供jdbc url jdbc url定义了连接数据库时的协议、子协议、数据来源: 协定:子协定:驱动类型 协议在jdbc中总是jdbc开始;子协议是桥接的驱动程序或是数据库管理系统名称,使用mysql的话是 mysql;数据来源识别标出找出数据库来源的地址;mysql的jdbc url编写方式如下: jdbc:mysql:/主机名称:连接端口/数据库名称?参数1=值1&参数2=值2,主机名称可以是本机localhost或是其它联机主机,连接端口为3306,假如我们要联机guestbook 数据库,并指明使用者名称与密码,可以如下指定: jdbc:mysql:/localhost:3306/guestbook?user=caterpillar&password=123456 如果要使用中文存取的话,还必须给定参数userunicode及characterencoding,表明是否使用unicode,并指定字符编码方式,例如: jdbc:mysql:/localhost:3306/guestbook?user=caterpillar&password=123456 &useunicode=true&characterencoding=gb2312,从drivermanager取得connection 要联机数据库,我们可以从drivermanager要求并取得connection对象,它代表数据库联机对象,您可以直接给它jdbc url作为参数并取回connection对象: try string url = “jdbc:mysql:/localhost:3306/guestbook?“ + “user=caterpillar catch(sqlexception e) ,取得connection对象之后,您可以测试与数据库的联机是否关闭,即使用isclosed(),在操作完数据库之后,必须使用close()来关闭与数据库的联机。 getconnection()方法也提供给定使用者名称与密码的方式来给定参数,例如: string url = “jdbc:mysql:/localhost:3306/guestbook“; string user = “caterpillar“; string password = “123456“; connection conn = drivermanager.getconnection(url, user, password);,statement、 resultset,connection对象是代表java与数据库的联机,接下来我们要执行sql的话,必须取得 statement对象,它代替您执行sql语句并取得执行之后的结果,您可以使用connection的createstatement()来建立statement对象: connection conn = drivermanager.getconnection( url, user, password); statement stmt = conn.createstatement();,取得statement对象之后,我们可以使用executeupdate()、executequery()等方法来执行 sql,executeupdate()主要是用来执行create table、insert、drop table、alter table等会改变数据库内容的sql,例如: stmt.executeupdate(“insert into message values(cstp, “ + “cstp, 留言吧, 2004-5-26,“ + “到此一游)“);,executequery()方法则是用于select等查询数据库的sql,executeupdate()与 executequery()都会传回resultset对象,代表变更或查询的结果,查询的结果会是一笔一笔的数据,您使用next()来移动至下一笔数据,它会传回 true 或 false表示是否有下一笔资料,接着可以使用getxxx()来取得资料,例如getstring()、getfloat()、getdouble()等方法,分别取得相对应的字段型态数据,getxxx()方法都提供有依字段名称取得数据,或是依字段顺序取得数据的方法,一个例子如下,您指定字段名称来取得数据: resultset result = stmt.executequery(“select * from message“); while(result.next() system.out.print(result.getstring(“name“) + “t“); system.out.print(result.getstring(“email“) + “t“); system.out.print(result.getstring(“subject“) + “t“); system.out.print(result.getstring(“time“) + “t“); system.out.println(result.getstring(“memo“) + “t“); ,使用查询到的结果之字段顺序来显示结果的方式如下: resultset result = stmt.executequery(“select * from message“); while(result.next() system.out.print(result.getstring(1) + “t“); system.out.print(result.getstring(2) + “t“); system.out.print(result.getstring(3) + “t“); system.out.print(result.getstring(4) + “t“); system.out.println(result.getstring(5) + “t“); ,statement的execute()可以用来执行sql,并可以测试所执行的sql是执行查询或是更新,传回 true的话表示sql执行将传回resultset表示查询结果,此时可以使用getresultset()取得resultset对象,如果 execute()传回false,表示sql执行会传回更新记录数或没有结果,此时可以使用getupdatecount()取得更新记录数。如果事先无法 得知是进行查询或是更新,就可以使用execute()。,最后注意到的是,connection对象预设为自动认可(commit),也就是statement执行sql语句完 后,马上对数据库进行操作变更,如果想要对statement要执行的sql进行除错,可以使用setautocommit(false)来将自动提交取消,在执行完sql之后,再调用connection的commit()方法认可变更,使用connection的getautocommit()可以测试是否设定为自动提交。 不过无论是否有无执行commit()方法,只要sql没有错,在关闭statement或connection前,都会执行提交动作,对数据库进行变更。,statement 批处理,statement的execute等方法一次只能执行一个sql语句,如果有多个sql语句要执行的话,可以使用executebatch()方法,在一次方法调用中执行多个sql语句,以增加执行的效能,我们先使用addbatch()方法将要执行的sql语句加入,然后执行 executebatch()即可:,conn.setautocommit(false); statement stmt = conn.createstatement(); stmt.addbatch(“insert into message values(cstp,” + “ cstp, 你好, ” + “2004-5-26, 到此一游)”); stmt.addbatch(“insert into message values(java,” + “ , 呵呵, “ + “2004-5-26, 啦啦啦)“); stmt.executebatch(); mit(); 在执行executebatch()时而sql有错误的情况下,会丢出batchupdateexception例外,您可以由这个例外对象的 getupdatecounts()方法取得正确的sql句数。,preparedstatement,statement主要用于执行静态的sql语句,也就是在执行 executequery()、executeupdate()等方法时,指定内容固定不变的sql语句字符串,每一句sql只适用于当时的执行,如果您有 些操作只是sql语句当中某些参数会有所不同,其余的sql子句皆相同,则您可以使用java.sql.preparedstatement。 您可以使用connection的preparedstatement()方法建立好一个预先编译(precompile)的sql语句,当中参数会变动的部份,先指定“?“这个占位字符,,例如: preparedstatement stmt = conn.preparestatement( “insert into message values(?, ?, ?, ?, ?)“);,要将参数指定给每一个字段,我们可以使用setint()、setstring()等等方法,例如: stmt.setstring(1, “cstp”); stmt.setstring(2, “cstp”); stmt.setstring(3, “你好“); stmt.setstring(4, “2004-5-26“); stmt.setstring(5, “到此一游“); stmt.executeupdate(); stmt.clearparameters();,setxxx()方法的第一个参数指定 ? 的位置,而第二个参数为要加入至数据表字段的值,要让sql执行生效,要执行executequery()或executeupdate()方法,使用 setxxx()来设定的参数会一直有效,可以于下一次使用,如果想要清除设定好的参数,可以执行clearparameters()方法。,使用preparedstatement也可以进行批处理,直接来看个例子就知道如何使用: preparedstatement stmt = conn.preparestatement( “insert into users values(?,?, ?)“); user users = .; for(int i=0; iusers.length; i+) stmt.setint(1, usersi.getid(); stmt.setstring(2, usersi.getname(); stmt.setstring(3, usersi.getpassword(); stmt.addbatch( ); stmt.executebatch();,将记录写入数据库,如果将要记录写入数据库,您可以在字段上使用blob或clob数据型态,blob全名binary large object,用于储存大量的二进制数据,clob全名character large object,用于储存大量的文字数据。 在jdbc中也提供了blob与clob两个类别分别代表blob与clob资料,您可以使用preparedstatement的setbinarystream()、 setobject()、setasciistream()、setunicodestream()等方法来代替,例如我们可以如下取得一个记录,并将之存入数据库中:,/ 取得内容 file file = new file(“./logo_phpbb.jpg“); int length = (int) file.length(); inputstream fin = new fileinputstream(file); / 填入数据库 preparedstatement pstmt = conn.preparestatement( “insert into files values(?, ?)“); pstmt.setstring(1, “cstpjpg“); pstmt.setbinarystream (2, fin, length); pstmt.executeupdate(); pstmt.clearparameters(); pstmt.close(); fin.close();,如果要从数据库中取得blob或clob资料,您可以如下进行: blob blob = result.getblob(2); / 取得blob clob clob = result.getclob(2) / 取得clob blob拥有getbinarystream()、getbytes()等方法,可以取得二进制串流或byte等数据,同样的,clob拥有getcharacterstream()、getsubstring()等方法,可以取得字符串流或子字符串等数据,您可以查看api文件来获得更详细的信息。,将记录存入数据库 - oracle,对于oracle 9i前,要储存数据至blob/clob字段前,jdbc必须先获得blob/clob结果,在实际存入数据前,我们必须先建立空的blob/clob字段,然后从空字段中取得blob/clob结果。,您可以使用oracle的empty_blob()与empty_clob()来存入空的blob/clob字段,例如: pstmt = conn.preparestatement( “insert into files(id, des, image) values(?, empty_clob(), empty_blob()“); pstmt.setint(1, 1); pstmt.executeupdate();,或者是使用oracle.sql.blob、oracle.sql.clob来存入blob/clob空字段,例如: pstmt = conn.preparestatement( “insert into files(id, des, image) values(?, ?, ?)“); pstmt.setint(1, 1); pstmt.setclob(2, clob.empty_lob(); pstmt.setblob(3, blob.empty_lob(); pstmt.executeupdate();,resultset 结果集,之前在建立statement或 preparedstatement,您所使用的是connection无参数的createstatement()与 preparedstatement(),这样取得的statement其执行sql后得到的resultset,将只能使用next()方法逐条取得查 询结果。 您可以在建立statement对象时指定resultsettype,可指定的参数有 resultset.type_forward_only、resultset.type_scroll_insensitive与 resultset.type_scroll_sensitive,在不指定的情况下,预设是第一个,也就是只能使用next()来逐条取得数据,指定第二个或第三个,则可以使用resultset的afterlast()、previous()、absolute()、relative()等方法。,resultset.type_scroll_insensitive与resultset.type_scroll_sensitive 的差别在于能否取得resultset改变值后的数据,另外您还必须指定resultsetconcurrency,有 resultset.concur_read_only与resultset.concur_updatable两个参数可以设定,前者表示只能读取 resultset的资料,后者表示可以直接使用resultset来操作数据库。 createstatement()不给定参数时,预设是resultset.type_forward_only、 resultset.concur_read_only。,先示范如何控制resultset的读取结果集,在建立statement时,您使用 resultset.type_scroll_insensitive及resultset.concur_read_only即可,下面这个例子从 查询到的数据最后一条开始往前读取: statement stmt = conn.createstatement( resultset.type_scroll_insensitive, resultset.concur_read_only); resultset result = stmt.executequery( “select * from message“); result.afterlast(); while(result.previous() system.out.print(result.getstring(“name“) + “t“); system.out.print(result.getstring(“email“) + “t“); system.out.print(result.getstring(“subject“) + “t“); system.out.print(result.getstring(“time“) + “t“); system.out.println(result.getstring(“memo“) + “t“); ,stmt.close(); conn.close(); afterlast()会将resultset的读取结果集移至最后一条数据之后,您使用previous()方法往前移动读取光标。,您也可以使用absolute()方法指定查询到的数据之位置,例如absolute(4)表示第四条记录,absoulte(10)则是第十条数据,如果指定负数,则从最后往前数,例如absolute(-1)则是最后一条数据,若有100条数据,absoulte(-4)则是第97条记录。 relative()方法则从目前光标处指定相对位置,例如若目前在第25条记录,则relative(-2)则表示第23条记录,而relative (4)则表示第29条记录。 另外还有beforefirst(),可以将光标移至数据的第一笔之前,first()可以将光标移至第一条数据,而last()可以将光标移至最后一条数据。,resultset 新增、更新、删除数据,之前要进行新增、更新或删除数据,都必须要编写sql,然后使用 executeupdate()来执sql,将sql写在executeupdate ()之中,其实是一件麻烦又容易出错的动作,如果您只是想要针对查询到的数据进行一些简单的新增、更新或删除资料,您可以藉由resultset的一些方法 来执行,而不一定要编写sql并执行。,想要使用resultset直接进行新增、更新或删除数据,在建立statement时必须在createstatement()上指定 resultset.type_scroll_sensitive(或resultset.type_scroll_insensitive,如果不想取 得更新后的数据的话)与resultset.concur_updatable,例如: statement stmt = conn.createstatement(resultset.type_scroll_sensitive, resultset.concur_updatable);,假如我们想要针对查询到的数据进行更新的动作,我们先移动光标至想要更新的数据位置,然后使用updatexxx()等对应的方法即可,最后记得使用 updaterow()让更新生效,例如: resultset result = stmt.executequery( “select * from message where name=caterpillar“); result.last(); result.updatestring(“name“, “justin“); result.updatestring(“email“, ““); result.updaterow();,使用updatexxx()等方法之后,并不会马上对数据库生效,而必须执行完updaterow()方法才会对数据库进行操作,如果在 updaterow()前想要取消之前的updatexxx()方法,则可以使用cancelrowupdates()方法取消。 如果想要新增数据,则先使用movetoinsertrow()移至新增数据处,执行相对的updatexxx()方法,然后再执行insertrow ()即可新增数据,例如: resultset result = stmt.executequery( “select * from message where name=caterpillar“);,result.movetoinsertrow(); result.updatestring(“name“, “caterpillar“); result.updatestring(“email“, ““); result.upda

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论