第七章对数据库的操作7.1数据源java应用程序与数据库的连接方式有四种,本书中采用JDBC-ODBC方式连接数据库.这种连接方式分三个步骤:首先,创建一个数据源,其次,加载JDBC-ODBC驱动程序,第三步,建立一个到数据库的连接。数据源是对数据库的一种映射。我们可以把数据源理解为数据库本身,一个数据源对应一个数据库。1)在管理工具中选择ODBC数据源2)双击ODBC数据源图标,选择SystemDSN选项卡,单击Add按钮,增加新的数据源,如图7-3所示。此对话框,为新增加的数据源选择驱动程序。3)因为要访问MicrosoftAccess数据库,选择MicosoftAccessDriver(*.mdb)选项,单击完成按钮(为数据源选择了驱动程序),出现了设置数据源具体项目的对话框,如图7-4所示。4)在数据源名(N)后的文本框中为数据源起一个名字,这里起的名字是grade(可以起别的名字),点击选择(S)…按钮,为数据源grade选择数据库,这里选择的数据库是E:\db.mdb。配置情况如图7-5所示。5)最后点击确定按钮,完成了数据源的配置,出现对话框如图7-6所示。在该对话框中,点击确定按钮,完成数据源grade的配置。7.2JDBC-ODBC桥接器JDBC-ODBC桥接器就是把应用程序与数据源连接起来的驱动程序。因此,创建了数据源以后,还要加载JDBC-ODBC桥接器,即加载驱动程序。下面是加载驱动程序的方式:try{Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);}chatch(ClassNotFoundExceptione){}通过Class类的静态方法forName(Stringdriver)加载JDBC-ODBC桥接器。7.3数据库连接创建了数据源,加载了驱动程序,应用程序还是不能连接到数据库。应用程序要访问数据库,还必须创建一个到数据库的连接。即创建一个连接对象。假设数据源名是“grade”,用户登录系统的帐号是user/password。下面是获得连接对象的方法:Connectionconn=DriverManager.getConnection(“jdbc:odbc:grade”,user,password);或者Connectionconn=DriverManager.getConnection(“jdbc:odbc:grade”);getConnection()方法是DriverManager类的一个静态方法。对于Access数据库连接,可以不要帐号参数就能建立连接对象。7.4数据库事务处理一般来说,数据库事务处理分两种:一种是数据查询,第二种是数据更新。数据更新包括数据插入、修改和删除。假设已经连接到某数据库,创建的连接对象是conn。则数据查询和数据更新步骤如下。1.数据查询通过以下两个步骤,获得查询结果集rs。(1)创建语句对象Statementstmt=conn.createStatement(inttype,intconcurrency);(2)获得查询结果集Stringsql=select*fromtablenamewhereexpression;//SQL查询字符串ResultSetrs=stmt.executeQuery(sql);//获得结果集rs2.数据更新通过以下两个步骤,实现数据更新。(1).创建语句对象Statementstmt=conn.createStatement(inttype,intconcurrency);(2).执行更新Stringsql=sqlStatement;//插入或修改或删除SQL字符串intnumber=stmt.executeUpdate(sql);//执行更新操作说明:在数据查询、数据更新事务中,一般采用无参的createStatement()方法创建语句对象。如果事务是随机查询、游动查询和用结果集更新数据库,则应采用createStatement(inttype,intconcurrency)方法创建语句对象。下面是对该方法参数的说明。type的取值决定滚动方式,即结果集中的游标是否能上下滚动。取值如下:ResultSet.TYPE_FORWORD_ONLY结果集的游标只能向下滚动。ResultSet.TYPE_SCROLL_INSENSITIVE结果集的游标可以上下移动,当数据库变化时,当前结果集不变。ResultSet.TYPE_SCROLL_SENSITIVE返回可滚动的结果集。当数据库变化时,当前结果集同步改变。concurrency的取值决定是否能用结果集更新数据库。concurrency取值:ResultSet.CONCUR_READ_ONLY不能用结果集更新数据库中的表。ResultSet.CONCUR_UPDATABLE能用结果集更新数据库中的表。我们可以使用同一个Statement对象来执行查询和更新操作(修改/添加/删除),但是,需要注意,用Statement对象获取结果集的操作,必须在用Statement对象执行更新的操作之前,否则,执行更新的操作会破坏Statement对象获取的结果集。7.5数据查询按照查询的方式不同,将查询分为顺序查询、游动查询、随机查询、参数查询、排序查询、使用通配符查询。7.5.1顺序查询这种查询中,获得的结果集(ResultSet对象)中的游标只能一行行地向下移动。既不能向上移动游标,也不能跳行移动游标。ResultSet对象由若干行组成。ResultSet对象一次只能看到一个数据行,使用next()方法,使游标移到下一行记录。ResultSet对象可以用字段索引(第一列是1,第二列是2等等)为参数,获得对应的字段值(记录中的数据项),如方法getXxx(intcolumnIndex);也可以用字段名为参数,获得对应的字段值(记录中的数据项),如方法getXxx(StringcolumnName)。ResultSet对象的常用方法如表7-1所示。[例子7.1]查询英语成绩及格的学生。学生成绩保存在表(students)中,表结构为sudents(number,name,math,english,phics)。在db.mdb库中创建表students。程序结构:程序名:ex7_1.jsp程序算法:1.分别声明连接类型,语句类型,结果集类型的变量:con/sql/rs。2.加载驱动程序sun.jdbc.odbc.JdbcOdbcDriver。3.获取连接对象:con4.获取语句对象:sql5.获取结果集对象:rs6.输出表头7.输出结果集(rs)中的所有记录7.5.2游动查询有时,我们需要在结果集中前后移动游标,以便获取某条记录。这时,我们必须返回一个可滚动的结果集。为了获取可滚动的结果集,我们必须使用下述方法先获得一个Statement对象:Statementstmt=conn.createStatement(inttype,intconcurrency);通过上述Statement对象获得的结果集是可滚动结果集。可滚动结果集(ResultSet)还可用到的方法如下:publicbooleanprevious()将游标向上移动,该方法返回boolean型数据,当移动结果集第一行之前时返回false。publicvoidbeforeFirst()将游标移到结果集的初始位置,即在第一行之前。publicvoidafterLast()将游标移到结果集最后一行之后publicvoidfirst()将游标移到结果集的第一行。publicvoidlast()将游标移到结果集的最后一行。publicbooleanisAfterLast()判断游标是否在最后一行之后。publicbooleanisBeforeFirst()判断游标是否在第一行之前。publicbooleanisFirst()判断游标是否指向结果集的第一行。publicbooleanisLast()判断游标是否指向结果集的最后一行。publicintgetRow()得到当前游标所指向的行号。行号从1开始,如果结果集没有行,返回0。publicbooleanabsolute(introw)将游标移到参数row指定的行号。说明:如果row取负值,就是倒数的行数。asolute(-1)表示移到最后一行,asolute(-2)表示移到倒数第二行。当移到第一行前面或最后一行的后面时,该方法返回false。[例子7.2]从表(students)的最后一行开始,以逆序方式输出记录。然后单独输出物理表中的第5条记录。问题分析:从题目要求可知,结果集中的游标必须能上下游动,因此,必须用带参数的createStatement(inttype,intconcurrency)方法创建Statement类型的对象。程序结构:程序名:ex7_2.jsp程序算法:1.分别声明连接类型,语句类型,结果集类型的变量:con/sql/rs。2.加载驱动程序sun.jdbc.odbc.JdbcOdbcDriver。3.获取连接对象:con4.获取语句对象:sql5.获取结果集对象:rs6.游标移到最后一行7.获取最后一行的行号8.输出记录数9.输出表头10.将游标移动到最后一行之后11.逆序输出输出结果集(rs)中的所有记录(从表的最后一行开始输出记录)12.将游标移到第5条记录13.输出第5条记录。7.5.3随机查询[例子7.3]从学生表(students)中随机抽取4条记录,并计算4条记录的数学成绩的平均值。问题分析:产生1到num之间的随机数计算公式如下:inti=(int)(Math.random()*num+1);i的值是1到num之间的随机数。在程序中,根据该随机数,把游标移到相应的行,并输出该行。程序结构:程序名:ex7_3.jsp程序算法:1.分别声明连接类型,语句类型,结果集类型的变量:con/sql/rs。2.加载驱动程序sun.jdbc.odbc.JdbcOdbcDriver。3.获取连接对象:con4.获取语句对象:sql5.获取结果集对象:rs6.游标移到最后一行7.获取表中记录总数:number8.向vector中添加number个Integer型对象(该对象保存了表的行号)。9.输出表头10.从vector中抽取四个数字对象,以每个数字对象为行号,输出该行号对应的记录。11.求出4条记录数学成绩的平均值,并输出平均值。7.5.4参数查询[例子7.4]对学生表(students)分别按姓名查询和按成绩查询。问题分析:由三个页面完成此功能。一个页面提供查询输入界面;一个页面按姓名查询数据;一个页面按成绩查询数据。程序结构:ex7_4.jsp页面提供查询条件输入窗口,按姓名查询时,其姓名参数被提交给byname.jsp页面,按成绩查询时,其成绩参数被提交给byscore.jsp页面。byname.jsp页面查询出指定姓名的学生;byscore.jsp页面查询出指定成绩的学生。三个页面的交互关系如图7-7所示。程序算法:ex7_4.jsp:1.创建一个表单,该表单包含一个文本框,文本框用于录入姓名。2.创建一个表单,该表单包含四个文本框,四个文本框用于录入英语成绩和3.数学成绩的查询范围。byname.jsp:1.获取表单中的姓名参数:name2.分别声明连接类型,语句类型,结果集类型的变量:con/sql/rs。3.加载驱动程序sun.jdbc.odbc.JdbcOdbcDriver。4.获取连接对象:con5.获取语句对象:sql6.构造SQL语句字符串:condition7.获取结果集对象:rs8.输出表头9.输出结果集(rs)中的所有记录byscore.jsp:1.获取表单中的英语和数学成绩范围:englishmax/englishmin;mathmax/mathmin2.分别声明连接类型,语句类型,结果集类型的变量:con/sql/rs。3.加载驱动程序s