Java程序
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
第15章访问数据库学习目标了解JDBC发展历史能够用不同的方式建立到数据库的连接利用Statement访问数据能够在对象和数据库的
记录
混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载
之间进行转换,了解ORM技术掌握批量更新能够调用存储过程了解连接池技术什么是JDBCJDBC(JavaDatabaseConnectivity)一种用于执行SQL语句,和数据库进行交互的技术,它由一组用Java编程语言编写的类和接口组成。JDBC的历史JDBC1.XAPI规范遵循的是SQL2/SQL92
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
,对它的支持的类都定义在包中。规范发布时,增加了对SQL3的支持,并且重点扩展了在应用服务器端访问数据库的功能,相关扩展的类包含在中。目前JDBC已经发布了的版本,其重要的变化集中在丰富的数据类型、元数据的支持、支持标注和应用服务器端编程的特性如数据源、连接池、分布式的事务等。15.1.2JDBC驱动程序类型JDBC-ODBC桥加ODBC驱动程序必须提供ODBC驱动程序本地API-部分用Java来编写的驱动程序一种用Java实现的,替代JDBC-ODBC桥产品的驱动程序JDBC网络纯Java驱动程序一种和具体数据库无关的驱动程序。本地协议纯Java驱动程序一种支持将JDBC调用直接转换为某个具体DBMS的驱动程序,通常由数据库厂家提供,实践中常用基本的数据库存取过程实现简单的数据库存取操作是一件很轻松的事情。实现基本的数据存取操作包括三个步骤:连接到数据库存取数据关闭连接。连接到数据库连接到数据库需要由驱动程序的支持,在保证已经将驱动程序文件复制到可被运行环境搜索到的位置后,开发对数据库进行存取操作的第一步是建立到指定数据库的连接,这一过程可以细分为两个操作:加载指定的驱动程序(可选)获得到指定数据库的连接publicclassSqlServerDemo{publicstaticvoidmain(String[]args){Stringurl="jdbc:sqlserver://localhost:1433;databaseName=bank;user=sa;password=123456;";Connectioncon=null;try{con=DriverManager.getConnection(url);//获得到数据库的连接//获得连接数据库的元数据对象metaDataDatabaseMetaDatametaData=con.getMetaData();//输出连接数据库的产品名称());//输出连接数据库的产品版本号());();//关闭到数据库的连接,释放资源}catch(SQLExceptione){();}}}1.加载驱动程序(可选)检查数据库厂商提供的JDBC驱动程序,可以在对应的位置发现其提供的驱动程序类。通过调用方法Class.forName(),将显式地加载驱动程序类。加载SQLServer驱动程序类Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");加载Oracle驱动程序类Class.forName("oracle.thin.Driver");Class.forName("oracle.jdbc.driver.OracleDriver");加载MySQL驱动程序类("org.gjt.mm.mysql.Driver");2建立连接加载Driver类之后,应用程序还需显式的获得到数据库的一个连接。当调用DriverManager.getConnection()方法发出连接请求时,DriverManager将检查每个驱动程序,查看它是否可以建立连接。该方法的返回值类型是Connection。
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
15-1DriverManager方法描述staticvoidderegisterDriver(Driverdriver)从DriverManager的列表中删除一个驱动程序staticConnectiongetConnection(Stringurl)试图建立到给定数据库URL的连接staticConnectiongetConnection(Stringurl,Propertiesinfo)试图建立到给定数据库URL的连接staticConnectiongetConnection(Stringurl,Stringuser,Stringpassword)试图建立到给定数据库URL的连接staticDrivergetDriver(Stringurl)试图查找能理解给定URL的驱动程序staticvoidsetLoginTimeout(intseconds)设置驱动程序试图连接到某一数据库时将等待的最长时间,以秒为单位连接所需的URL
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
jdbc:
:例如:url="jdbc:microsoft:sqlserver://localhost:1433;"+"databasename=score;User=sa;Password=123456";这里的subprotocol是microsoft,除此之外,根据情况还有odbc、oracle、mysql等。而subname则指定了数据源。Connection表示了与特定数据库的连接(会话),在连接上下文中执行SQL语句并返回结果。表15-2Connection方法描述voidclose()voidcommit()StatementcreateStatement()CallableStatementprepareCall(Stringsql)PreparedStatementprepareStatement(Stringsql)voidrollback()voidrollback(Savepointsavepoint)voidsetAutoCommit(booleanautoCommit)SavepointsetSavepoint()voidsetTransactionIsolation(intlevel)使用Statement访问数据库Statement对象用于将SQL语句发送到数据库系统中。实际上有三种Statement对象,它们都作为在给定连接上执行SQL语句的包容器:StatementPreparedStatement(继承Statement)CallableStatement(继承PreparedStatement)它们都专用于发送特定类型的SQL语句:Statement对象用于执行不带参数的简单SQL语句;PreparedStatement对象用于执行带或不带IN参数的预编译SQL语句;CallableStatement对象用于执行对数据库已存储过程的调用。表12-4Statement的主要方法voidaddBatch(Stringsql)将给定的SQL命令添加到此Statement对象的当前命令列表中。voidclearBatch()清空此Statement对象的当前SQL命令列表。voidclose()立即释放此Statement对象的数据库和JDBC资源,而不是等待该对象自动关闭时发生此操作。booleanexecute(Stringsql)执行给定的SQL语句,该语句可能返回多个结果。ResultSetexecuteQuery(Stringsql)执行给定的SQL语句,该语句返回单个ResultSet对象。int[]executeBatch()将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。intexecuteUpdate(Stringsql)行给定SQL语句,该语句可能为INSERT、UPDATE或DELETE语句,或者不返回任何内容的SQL语句(如SQLDDL语句)。ConnectiongetConnection()检索生成此Statement对象的Connection对象。ResultSetgetResultSet()以ResultSet对象的形式检索当前结果。voidsetMaxRows(intmax)将任何ResultSet对象都可以包含的最大行数限制设置为给定数。如果超过了该限制,则安静地撤消多出的行。1创建Statement对象建立了到特定数据库的连接之后,要想用该连接发送SQL语句,首先需要创建一个Statement对象,可用Connection的方法createStatement创建。Statementstmt=con.createStatement();2使用Statement对象执行语句ResultSetrs=stmt.executeQuery("selectsid,name,genderfromstudent");Statement接口提供了四种执行SQL语句的方法。方法addBatch和executeBatch结合起来使用,执行命令的顺序以添加到批中的顺序为主。 方法executeQuery用于产生单个结果集的语句,例如SELECT语句。方法executeUpdate用于执行INSERT、UPDATE或DELETE语句以及SQLDDL(数据定义语言)语句。方法execute用于执行返回多个结果集、多个更新计数或二者组合的语句。ResultSetrs=null;("selectsid,name,genderfromstudent");3语句完成当连接处于自动提交模式时,其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时,即认为已完成。对于返回一个结果集的executeQuery方法,在检索完ResultSet对象的所有行时该语句完成。对于方法executeUpdate,当它执行时语句即完成。但在少数调用方法execute的情况中,在检索所有结果集或它生成的更新计数之后语句才完成。有些DBMS将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用commit方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。4关闭Statement对象Statement对象将由Java垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要Statement对象时显式地关闭它们。这将立即释放DBMS资源,有助于避免潜在的内存问题。如上述程序中的finally代码块中的语句:stmt.close();con.close();ResultSet包含数据库中存储的符合SQL语句中条件的所有记录,并且它通过一套get方法(这些get方法可以访问当前行中的不同列)提供了对这些记录中数据的访问。定位记录获得此记录对应属性的值表15-4ResultSet主要方法booleanabsolute(introw)将指针移动到此ResultSet对象的给定行编号voidafterLast()将指针移动到此ResultSet对象的末尾,正好位于最后一行之后voidbeforeFirst()将指针移动到此ResultSet对象的开头,正好位于第一行之前voidcancelRowUpdates()取消对ResultSet对象中的当前行所作的更新voidclose()立即释放此ResultSet对象的数据库和JDBC资源,而不是等待该对象自动关闭时发生此操作voiddeleteRow()从此ResultSet对象和底层数据库中删除当前行booleanfirst()将指针移动到此ResultSet对象的第一行XXXgetXXX(StringcolumnName)XXX指boolean、byte、int、double、float、Date、long等类型,既获得对应属性值voidmoveToCurrentRow()将指针移动到记住的指针位置,通常为当前行voidmoveToInsertRow()将指针移动到插入行booleannext() 将指针从当前位置下移一行booleanprevious()将指针移动到此ResultSet对象的上一行booleanrelative(introws)按相对行数(或正或负)移动指针行和光标行和光标ResultSet对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next方法将指针移动到下一行,因为该方法在ResultSet对象中没有下一行时返回false,所以可以在while循环中使用它来迭代结果集。默认的ResultSet对象不可更新,仅有一个向前移动的指针。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。可更新结果集Statementstmt=con.createStatement(int resultSetType,int resultSetConcurrency);参数resultSetType表示结果集类型。它是、ResultSet.TYPE_SCROLL_INSENSITIVE或ResultSet.TYPE_SCROLL_SENSITIVE之一参数resultSetConcurrency表示并发类型。它是ResultSet.CONCUR_READ_ONLY或ResultSet.CONCUR_UPDATABLE之一获取列的值2访问列方法getXXX提供了获取当前行中某列值的途径。在每一行内,可按任何次序获取列值。但为了保证可移植性,应该从左至右获取列值,并且一次性地读取列值。列名或列号可用于标识要从中获取数据的列。通过下标获得当前记录指定列的列值通过字段名获得当前记录指定列的列值通过字段名或下标获得当前记录未知类型的指定列的列值Stringsql="selectid,name,balancefromtb_account";ResultSetrs=stmt.executeQuery(sql);while(rs.next()){Stringid=rs.getString(1);Stringname=rs.getString(2);intbalance=rs.getInt(3);System.out.printf("id:%s,name:%s,balance:%d\r\n",id,name,balance);}rs.close();Stringsql="selectid,name,balancefromtb_account";ResultSetrs=stmt.executeQuery(sql);while(rs.next()){("id");Stringname=rs.getString("name");intbalance=rs.getInt("balance");("id:%s,name:%s,balance:%d\r\n",id,name,balance);}rs.close();Objectid=rs.getObject("id");Objectname=rs.getObject("name");Objectbalance=rs.getObject("balance");插入新行插入新行直接利用Statement执行insert语句。当Statement对象的结果集类型是可更新的时候,ResultSet对象具有一个与其关联的特殊行,该行用作构建要插入的行的暂存区域(stagingarea),利用它可以完成向数据表的插入操作。rs.moveToInsertRow();//定位插入行位置,然后更新每个字段的值("id",uuid.toString());("name",name);("balance",balance);();//将插入行的内容插入到此ResultSet对象和数据库更新列值更新列值同样地批量的修改可以用Statement执行SQL来确定ResultSet提供了针对一条记录某个字段进行修改的方法updateXXX;ResultSetrs=stmt.executeQuery("selectid,name,balance"+"fromtb_accountwherename='张华'");if(rs.next()){//假如找到这样符合条件的记录rs.updateInt("balance",100);rs.updateRow();}删除记录行删除记录同样地批量的删除可以用Statement执行SQL来确定ResultSet提供了删除一条记录的方法deleteRow();ResultSetrs=stmt.executeQuery("select*fromtb_accountwherebalance=0");while(rs.next()){//逐个删除每条记录rs.deleteRow();}rs.close();6数据类型和转换对于getXXX方法,JDBC驱动程序试图将基本数据转换成指定Java类型,然后返回适合的Java值。例如,如果getXXX方法为getString,而基本数据库中数据类型为VARCHAR,则JDBC驱动程序将把VARCHAR转换成JavaString。getString的返回值将为JavaString对象。7对非常大的行值使用I/O流JDBCAPI具有三个获取流的方法,分别具有不同的返回值:getBinaryStream返回只提供数据库原字节而不进行任何转换的流。getAsciiStream返回提供单字节ASCII字符的流。getCharacterStream(返回提Reader类型字符的流。8NULL结果值在读取字段值时,一般而言要对一些不明确值是否存在的字段值进行空值判断。要确定给定结果值是否是JDBCNULL,必须先读取该列,然后使用ResultSet.wasNull方法检查该次读取是否返回JDBCNULL。15.5PreparedStatementPreparedStatement继承于Statement,它允许使用可替代的参数修改最终执行的SQL语句,PreparedStatementpstmt=con.prepareStatement("insertintotb_account(id,name,balance)values(?,?,?)");UUIDuuid=UUID.randomUUID();pstmt.setString(1,uuid.toString());//设置id字段的值pstmt.setString(2,"王军");//设置name字段的值pstmt.setInt(3,1000);//设置balance字段的值pstmt.executeUpdate();//用前面的实参值,替代原来的参数,执行SQL语句("selectid,name,balancefromtb_accountwherename=?",,);pstmt.setString(1,"张华");ResultSetrs=pstmt.executeQuery();15.6CallableStatementCallableStatementJDBC中提供了CallableStatement对象为所有的DBMS实现了一种以标准形式调用储存过程的方法。对储存过程的调用是CallableStatement对象所含的主要内容。CREATEproceduresumBalance@lowint,@highintasbegindeclare@totalintselect@total=sum(balance)fromtb_accountwherebalance>=@lowandbalance<=@highreturn@totalend;CallableStatementcstmt=con.prepareCall("{?=callsumBalance(?,?)}");Connectioncon=null;try{(01)con=DriverManager.getConnection(url);(02)StringprocName="{?=callsumBalance(?,?)}";(03)CallableStatementcstmt=con.prepareCall(procName);(04)cstmt.setInt(2,1000);(05)cstmt.setInt(3,10000);(06)cstmt.registerOutParameter(1,Types.INTEGER);(07)cstmt.execute();(08)System.out.println(cstmt.getInt(1));(09)cstmt.close();(10)con.close();}catch(SQLExceptione){e.printStackTrace();}15.7JDBC事务事务数据库的事务就是对现实生活中事务的模拟,它由一组在业务逻辑上相互依赖的SQL语句组成。为了保证事务的完整性,JDBC提供了相应的事务控制机制。事务提交模式在JDBC编程模型中,一个数据库连接建立时,就处于一个自动提交模式,每一个SQL语句被执行完成后就会被自动提交,反映至数据库中。当需要把几条逻辑上相关的SQL组成一个事务执行时,就需要关闭事务自动提交模式。如下面的语句所示:con.setAutoCommit(false);//关闭自动提交模式一旦关闭了事务自动提交模式,不会有任何SQL语句被提交至数据库系统执行,除非显式的调用提交方法。publicvoidtransfer(Accounta,Accountb,intamount)throwsSQLException{PreparedStatementpstmt=null;Stringsql="updatetb_accountsetbalance=?whereid=?";try{pstmt=con.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);//关闭自动提交模式,以下语句直到commit()前都作为一个完整的事务执行con.setAutoCommit(false);//开始处理转账,将账户a上减少amount元pstmt.setInt(1,a.getBalance()-amount);pstmt.setString(2,a.getId());();//将账户b上增加amount元()+amount);pstmt.setString(2,b.getId());();();//提交上面的两次操作}catch(SQLExceptione){();//回滚操作,取消本次事务中的所有已执行SQL语句throwe;//继续抛出异常,告诉调用者转账没有成功}}数据源和连接池通过数据源对象也可以获得到数据库的连接。连接池技术是一项能够极大提升数据库访问性能的技术,其本质是将实现建立好的若干连接存放于集合中,利用代理技术提供连接的获取和释放。SQLServerDataSourceds=newSQLServerDataSource();ds.setUser("sa");ds.setPassword("123456");ds.setServerName("localhost");ds.setPortNumber(1433);ds.setDatabaseName("bank");con=ds.getConnection();SQLServerConnectionPoolDataSource ds = newSQLServerConnectionPoolDataSource();();ds.setUser("sa");ds.setPassword("123456");ds.setServerName("localhost");ds.setPortNumber(1433);ds.setDatabaseName("bank");con=pool.getConnection();//通过连接池获得对象表15-5主要的SQL类型及其Java对应类型SQL类型Java类型SQL类型Java类型ARRAYjava.sql.ArrayBIGINTlongBINARYbyte[]bitbooleanBLOBjava.sql.BlobCHARStringCLOBjava.sql.ClobDATALINKjava.net.URLDATEjava.sql.DateDOUBLEdoubleFLOATdoubleINTEGERintNULLnullNUMERICjava.math.BigDecimalREALfloatREFjava.sql.REFSMALLINTshortSTRUCTjava.sql.StructTIMEjava.sql.TimeTIMESTAMPjava.sql.TimestampTINYINTbyteVARBINARYbyte[]VARCHARStringNVARCHARString