为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > 无论是一个小型的企业办公自动化系统,还是像中国移动那

无论是一个小型的企业办公自动化系统,还是像中国移动那

2018-03-04 50页 doc 350KB 16阅读

用户头像

is_589748

暂无简介

举报
无论是一个小型的企业办公自动化系统,还是像中国移动那无论是一个小型的企业办公自动化系统,还是像中国移动那 10 Java Web的数据库操作 11 , 视频讲解,48分钟, 数据库的应用在日常的生活和工作中可以说是无处不在,无论是一个小型的企 业办公自动化系统,还是像中国移动那样的大型运营系统,似乎都离不开数据库。 对于大多数应用程序来说,不管它们是Windows桌面应用程序,还是Web应用程 序,存储和检索数据都是其核心功能,所以针对数据库的开发已经成为软件开发的 一种必备技能。如果说过去是“学好数理化,走遍天下都不怕”,那么,对于今天 的软件开发者而言就是“...
无论是一个小型的企业办公自动化系统,还是像中国移动那
无论是一个小型的企业办公自动化系统,还是像中国移动那 10 Java Web的数据库操作 11 , 视频讲解,48分钟, 数据库的应用在日常的生活和工作中可以说是无处不在,无论是一个小型的企 业办公自动化系统,还是像中国移动那样的大型运营系统,似乎都离不开数据库。 对于大多数应用程序来说,不管它们是Windows桌面应用程序,还是Web应用程 序,存储和检索数据都是其核心功能,所以针对数据库的开发已经成为软件开发的 一种必备技能。如果说过去是“学好数理化,走遍天下都不怕”,那么,对于今天 的软件开发者而言就是“学好数据库,走到哪儿都不怵”。本章将向读者介绍如何 在Java Web中进行数据库应用开发。 通过阅读本章,您可以, , 了解JDBC的结构体系 , 掌握JDBC连接数据库的过程 , 熟悉JDBC的常用API 章导第, 掌握通过JDBC向数据库中添加数据 读 , 掌握通过JDBC查询数据 , 掌握通过JDBC修改数据库中的数据 , 掌握通过JDBC删除数据库中的数据 , 掌握进行批处理的方法 第10章 Java Web的数据库操作 , 掌握JDBC在Java Web中的应用 197 Java Web从入门到精通,第2版, 10.1 JDBC技术 视频讲解,光盘\TM\lx\10\JDBC技术.exe JDBC(Java Data Base Connectivity)是Java程序与数据库系统通信的API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库交互,JDBC在Java程序与数据库系统之间架起了一座桥梁。 Java程序10.1.1 JDBC简介 JDBC是Java程序操作数据库的API,也是Java程JDBC API序与数据库交互的一门技术。JDBC是Java操作数据库 的规范,由一组用Java语言编写的类和接口组成,它对 数据库的操作提供了基本方法,但对于数据库的细节操数据库驱动作由数据库厂商进行实现。使用JDBC操作数据库,需 要数据库厂商提供数据库的驱动程序。Java程序与数据 库交互的示意图如图10.1所示。 通过图10.1可以看出,JDBC在Java程序与数据库 数据库之间起到了一个桥梁的作用,有了JDBC就可以方便地 与各种数据库进行交互,不必为某一个特定的数据库制图10.1 Java程序与数据库交互 定专门的访问程序。例如,访问MySQL数据库可以使用 JDBC进行访问,访问SQL Server同样使用JDBC。因此,JDBC对Java程序员而言,是一套标准的操作数据库的API;而对数据库厂商而言,又是一套标准的模型接口。 目前~除访问数据库的方法外~程序也可以通过提供的来访问数JDBCJavaMicrosoftODBC 据库。通过语言实现~它使用的是语言中的接口~虽然的应用十分广泛~ODBCCAPICODBC 但通过语言来调用中的代码~在技术实现、安全性、跨平台等方面~仍存在一定的 JavaODBCC 缺点~并且也有一定的难度,而则是纯语言编写的~通过程序来调用~自然JDBCJavaJavaJDBC 也非常简单。所以~在领域中~几乎所有的程序员都是使用来操作数据库。JavaJavaJDBC 10.1.2 JDBC连接数据库的过程 在了解了JDBC与数据库后,本节介绍使用JDBC操作数据的开发流程,其关键步骤如下。 , 注册数据库驱动 198 第10章 Java Web的数据库操作 连接数据库前,需要将数据库厂商提供的数据库驱动类注册到JDBC的驱动管理器中。通常情况下,是通过将数据库驱动类加载到JVM来实现的。 【例10.1】 加载数据库驱动,注册到驱动管理器。代码如下: Class.forName("com.mysql.jdbc.Driver"); , 构建数据库连接URL 要建立数据库连接,就要构建数据库连接的URL,这个URL由数据库厂商制定,不同的数据库,它的URL也有所区别,但都符合一个基本的格式,即“JDBC协议+IP地址或域名+端口+数据库名称”。如MySQL的数据库连接URL的字符串为“jdbc:mysql://localhost:3306/test”。 , 获取Connection对象 在注册了数据库驱动及构建数据库URL后,就可以通过驱动管理器获取数据库的连接Connection。Connection对象是JDBC封装的数据库连接对象,只有创建此对象后,才可以对数据进行相关操作,它的获取方法如下: DriverManager.getConnection(url,username,password); Connection对象的获取需要用到DriverManager对象,DriverManager的getConnection()方法通过数据库连接URL、数据库用户名及数据库密码创建Connection对象。 【例10.2】 通过JDBC连接MySQL数据库。,实例位置,光盘\TM\sl\10\1, (1)创建名称为10.1的动态Web项目,将MySQL数据库的驱动包添加至项目的构建路径,构建开发环境。 在中~不包含数据库的驱动程序~使用操作数据库~需要事先下载数据库厂商提JDKJDBC 供的驱动包。例中使用的是数据库~所以实例添加的是官方提供的数据库驱10.2MySQLMySQL 动包~其名称为。mysql-connector-java-5.1.10-bin.jar (2)创建程序中的主页index.jsp,在该页面中加载数据库驱动并创建数据库连接。关键代码如下: <% try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/test"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 Connection conn = DriverManager.getConnection(url,username,password); //创建Connection连接 if(conn != null){ //判断数据库连接是否为空 out.println("数据库连接成功~"); //输出连接信息 conn.close(); //关闭数据库连接 }else{ out.println("数据库连接失败~"); //输出连接信息 } } catch (ClassNotFoundException e) { e.printStackTrace(); 199 Java Web从入门到精通,第2版, } catch (SQLException e) { e.printStackTrace(); } %> 的方法的作用是将指定字符串名的类加载到中~实例中调用该方法来加ClassforName()JVM 载数据库驱动~在加载后~数据库驱动程序将会把驱动类自动注册到驱动管理器中。 在index.jsp页面中,首先通过Class的forName()方法加载数 据库驱动,然后使用DriverManager对象的getConnection()方法获 取数据库连接Connection对象,最后将获取结果输出到页面中。 实例运行结果如图10.2所示。 如果数据库连接失败~请确认数据库服务是否开启~因为只 图10.2 与数据库建立连接 有数据库的服务处于开启状态~才能成功地与数据库建立连接。 10.2 JDBC API 视频讲解,光盘\TM\lx\10\JDBC API.exe JDBC是Java程序操作数据库的标准,它由一组用Java语言编写的类和接口组成,Java通过JDBC可以对多种关系数据库进行统一访问。所以,学习JDBC需要掌握JDBC中的类和接口,也就是JDBC API。 10.2.1 Connection接口 Connection接口位于java.sql包中,是与特定数据库的连接会话,只有获得特定数据库的连接对象,才能访问数据库,操作数据库中的数据表、视图和存储过程等。Connection接口的方法声明及说明如表10.1所示。 表10.1 Connection接口的方法声明及说明 方 法 声 明 说 明 立即释放Connection对象的数据库连接占用的JDBC资void close() throws SQLException 源,在操作数据库后,应立即调用此方法 提交事务,并释放Connection对象当前持有的所有数据 库锁。当事务被设置为手动提交模式时,需要调用该方void commit() throws SQLException 法提交事务 200 第10章 Java Web的数据库操作 创建一个Statement对象来将SQL语句发送到数据库,Statement createStatement() throws SQLException 该方法返回Statement对象 续表 方 法 声 明 说 明 用于判断Connection对象是否被设置为自动提交模式,boolean getAutoCommit() throws SQLException 该方法返回布尔值 获取Connection对象所连接的数据库的元数据 DatabaseMetaData对象,元数据包括关于数据库的表、DatabaseMetaData getMetaData() throws SQLException 受支持的SQL 语法、存储过程、此连接功能等信息 获取Connection对象的当前事务隔离级别 int getTransactionIsolation() throws SQLException 判断Connection对象是否与数据库断开连接,该方法返 回布尔值。需要注意的是,如果Connection对象与数据boolean isClosed() throws SQLException 库断开连接,则不能再通过Connection对象操作数据库 判断Connection对象是否为只读模式,该方法返回布尔值 boolean isReadOnly() throws SQLException 将参数化的SQL语句预编译并存储在PreparedStatementPreparedStatement prepareStatement(String sql) throws 对象中,并返回所创建的这个PreparedStatement对象 SQLException 从当前事务中移除指定的Savepoint和后续Savepoint对象 void releaseSavepoint(Savepoint savepoint) throws SQLException 回滚事务,并释放Connection对象当前持有的所有数据 库锁。注意,该方法需要应用于Connection对象的手动void rollback() throws SQLException 提交模式中 回滚事务,针对Savepoint对象之后的更改 void rollback(Savepoint savepoint) throws SQLException 设置Connection对象的提交模式,如果参数autoCommit 的值设置为true,Connection对象则为自动提交模式;void setAutoCommit(boolean autoCommit) throws SQLException 如果参数autoCommit的值设置为false,Connection对 象则为手动提交模式 将Connection对象的连接模式设置为只读,该方法用于void setReadOnly(boolean readOnly) throws SQLException 对数据库进行优化 在当前事务中创建一个未命名的保留点,并返回这个保Savepoint setSavepoint() throws SQLException 留点对象 在当前事务中创建一个指定名称的保留点,并返回这个Savepoint setSavepoint(String name) throws SQLException 保留点对象 设置Connection对象的事务隔离级别 void setTransactionIsolation(int level) throws SQLException 表中所列出的方法均为接口的常用方法~其更多方法的声明及说明请参照10.1ConnectionJ2SE 的。API 10.2.2 DriverManager类 201 Java Web从入门到精通,第2版, 使用JDBC操作数据库,需要使用数据库厂商提供的驱动程序,通过驱动程序可以与数据库进行交互。DriverManager类主要作用于用户及驱动程序之间,它是JDBC中的管理层,通过DriverManager类可以管理数据库厂商提供的驱动程序,并建立应用程序与数据库之间的连接,其方法声明及说明如表10.2所示。 表10.2 DriverManager类的方法声明及说明 方 法 声 明 说 明 从DriverManager的管理列表中删除一个驱动public static void deregisterDriver(Driver driver) throws SQLException 程序。参数driver为要删除的驱动对象 根据指定数据库连接URL,建立与数据库连接public static Connection getConnection(String url) throws SQLException Connection。参数url为数据库连接URL 根据指定数据库连接URL及数据库连接属性信public static Connection getConnection(String url,Properties info) throws 息建立数据库连接Connection。参数url为数据SQLException 库连接URL,参数info为数据库连接属性 根据指定数据库连接URL、用户名及密码建立 数据库连接Connection。参数url为数据库连接public static Connection getConnection(String url, String user, String URL,参数user为连接数据库的用户名,参数password) throws SQLException password为连接数据库的密码 获取当前DriverManager中已加载的所有驱动public static Enumeration getDrivers() 程序,它的返回值为Enumeration 向DriverManager注册一个驱动对象,参数driverpublic static void registerDriver(Driver driver) throws SQLException 为要注册的驱动 10.2.3 Statement接口 在创建了数据库连接之后,就可以通过程序来调用SQL语句对数据库进行操作,在JDBC中Statement接口封装了这些操作。Statement接口提供了执行语句和获取查询结果的基本方法,其方法声明及说明如表10.3所示。 表10.3 Statement接口的方法声明及说明 方 法 声 明 说 明 将SQL语句添加到Statement对象的当前命令列表void addBatch(String sql) throws SQLException 中,该方法用于SQL命令的批处理 清空Statement对象中的命令列表 void clearBatch() throws SQLException 立即释放Statement对象的数据库和JDBC资源,而void close() throws SQLException 不是等待该对象自动关闭时发生此操作 执行指定的SQL语句。如果SQL语句返回结果,该boolean execute(String sql) throws SQLException 方法返回true,否则返回false 将一批SQL命令提交给数据库执行,返回更新计数int[] executeBatch() throws SQLException 组成的数组 202 第10章 Java Web的数据库操作 执行查询类型(select)的SQL语句,该方法返回查ResultSet executeQuery(String sql) throws SQLException 询所获取的结果集ResultSet对象 续表 方 法 声 明 说 明 执行SQL语句中DML类型(insert、update、delete)executeUpdate int executeUpdate(String sql) throws SQLException 的SQL语句,返回更新所影响的行数 获取生成Statement对象的Connection对象 Connection getConnection() throws SQLException 判断Statement对象是否已被关闭,如果被关闭,则 不能再调用该Statement对象执行SQL语句,该方法boolean isClosed() throws SQLException 返回布尔值 10.2.4 PreparedStatement接口 Statement接口封装了JDBC执行SQL语句的方法,它可以完成Java程序执行SQL语句的操作,但在实际开发过程中,SQL语句往往需要将程序中的变量做查询条件参数等。使用Statement接口进行操作过于烦琐,而且存在安全方面的缺陷,针对这一问,JDBC API中封装了Statement的扩展PreparedStatement对象。 PreparedStatement接口继承于Statement接口,它拥有Statement接口中的方法,而且PreparedStatement接口针对带有参数SQL语句的执行操作进行了扩展。应用于PreparedStatement接口中的SQL语句,可以使用占位符“?”来代替SQL语句中的参数,然后再对其进行赋值。PreparedStatement 接口的方法声明及说明如表10.4所示。 表10.4 PreparedStatement接口的方法声明及说明 方 法 声 明 说 明 void setBinaryStream (int parameterIndex, 将输入流x作为SQL语句中的参数值,parameterIndex为参数位置的索引 InputStream x)throws SQLException void setBoolean(int parameterIndex,boolean x) 将布尔值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 throws SQLException void setByte(int parameterIndex, byte x)throws 将byte值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 SQLException 将java.sql.Date值x作为SQL语句中的参数值,parameterIndex为参数位置的void setDate (int parameterIndex, Date x) 索引 throws SQLException void setDouble(int parameterIndex, double x) 将double值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 throws SQLException void setFloat (int parameterIndex, float x) 将float值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 throws SQLException void setInt(int parameterIndex, int x)throws 将int值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 SQLException 203 Java Web从入门到精通,第2版, void setInt(int parameterIndex, long x)throws 将long值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 SQLException 续表 方 法 声 明 说 明 将Object对象x作为SQL语句中的参数值,parameterIndex为参数位置的void setObject(int parameterIndex, Object x) 索引 throws SQLException void setShort(int parameterIndex, short x) 将short值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 throws SQLException 将String值x作为SQL语句中的参数值,parameterIndex为参数位置的 void setString(int parameterIndex, String x) 索引 throws SQLException 将Timestamp值x作为SQL语句中的参数值,parameterIndex为参数位置void setTimestamp (int parameterIndex, 的索引 Timestamp x)throws SQLException 在实际的开发过程中,如果涉及向SQL语句传递参数,最好使用PreparedStatement接口实现。因为使用PreparedStatement接口,不仅可以提高SQL的执行效率,而且还可以避免SQL语句的注入式攻击。 10.2.5 ResultSet接口 执行SQL语句的查询语句会返回查询的结果集,在JDBC API中,使用ResultSet对象接收查询结果集。 ResultSet接口位于java.sql包中,封装了数据查询的结果集。ResultSet对象包含了符合SQL语句的所有行,针对Java中的数据类型提供了一套getXXX()方法,通过这些方法可以获取每一行中的数据。除此之外,ResultSet还提供了光标的功能,通过光标可以自由定位到某一行中的数据,其方法声明及说明如表10.5所示。 表10.5 ResultSet接口的方法声明及说明 方 法 声 明 说 明 将光标移动到ResultSet对象的给定行编号,参数row为行boolean absolute(int row) throws SQLException 编号 将光标移动到ResultSet对象的最后一行之后,如果结果集void afterLast() throws SQLException 中不包含任何行,则该方法无效 立即释放ResultSet对象的数据库和JDBC资源 void beforeFirst() throws SQLException 从ResultSet对象和底层数据库中删除当前行 void deleteRow() throws SQLException 将光标移动到ResultSet对象的第一行 boolean first() throws SQLException 以byte流的方式获取ResultSet对象当前行中指定列的值,InputStream getBinaryStream(String columnLabel) 参数columnLabel为列名称 throws SQLException 以java.sql.Date的方式获取ResultSet对象当前行中指定列Date getDate(String columnLabel)throws SQLException 的值,参数columnLabel为列名称 以double的方式获取ResultSet对象当前行中指定列的值,double getDouble(String columnLabel)throws SQLException 参数columnLabel为列名称 204 第10章 Java Web的数据库操作 以float的方式获取ResultSet对象当前行中指定列的值,参float getFloat(String columnLabel)throws SQLException 数columnLabel为列名称 续表 方 法 声 明 说 明 以int的方式获取ResultSet对象当前行中指定列的值,参int getInt(String columnLabel)throws SQLException 数columnLabel为列名称 以String的方式获取ResultSet对象当前行中指定列的值,String getString(String columnLabel)throws SQLException 参数columnLabel为列名称 判断当前ResultSet对象是否已关闭 boolean isClosed() throws SQLException 将光标移动到ResultSet对象的最后一行 boolean last() throws SQLException 将光标位置向后移动一行,如果移动的新行有效则返回boolean next() throws SQLException true,否则返回false 将光标位置向前移动一行,如果移动的新行有效则返回boolean previous() throws SQLException true,否则返回false 10.3 JDBC操作数据库 视频讲解,光盘\TM\lx\10\JDBC操作数据库.exe 在了解了JDBC API后,就可以通过JDBC API来操作数据库,实现对数据库的CRUD操作。 10.3.1 添加数据 通过JDBC向数据库添加数据,可以使用INSERT语句实现插入数据的SQL语句,对于SQL语句 中的参数可以用占位符“?”代替,然后通过PreparedStatement对其赋值并执行SQL。 【例10.3】 创建Web项目,通过JDBC实现图书信息添加功能。,实例位置,光盘\TM\sl\10\2, (1)在MySQL数据库中创建图书信息表tb_books,其结构如图10.3所示。 图10.3 tb_books表结构 (2)创建名称为Book的类,用于封装图书对象信息。关键代码如下: public class Book { private int id; //编号 private String name; //图书名称 private double price; //价格 205 Java Web从入门到精通,第2版, private int bookCount; //数量 private String author; //作者 public int getId() { return id; } public void setId(int id) { this.id = id; } //省略部分setXXX()与getXXX()方法 } (3)创建index.jsp页面,它是程序中的主页,用于放置添加图书信息所需要的表单,该表单提交 到AddBook.jsp页面进行处理。关键代码如下:

添加图书信息


图书名称:
价 格:
数 量:
作 者:
(4)创建AddBook.jsp页面,用于对添加图书信息请求进行处理,该页面通过JDBC所提交的图 书信息数据写入数据库中。关键代码如下: 206 第10章 Java Web的数据库操作 <%request.setCharacterEncoding("UTF-8); %> <% try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/db_database10"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 Connection conn = DriverManager.getConnection(url,username,password); //创建Connection连接 //添加图书信息的SQL语句 String sql = "insert into tb_books(name,price,bookCount,author) values(?,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); //获取PreparedStatement ps.setString(1, book.getName()); //对SQL语句中的第1个参数赋值 ps.setDouble(2, book.getPrice()); //对SQL语句中的第2个参数赋值 ps.setInt(3,book.getBookCount()); //对SQL语句中的第3个参数赋值 ps.setString(4, book.getAuthor()); //对SQL语句中的第4个参数赋值 int row = ps.executeUpdate(); //执行更新操作,返回所影响的行数 if(row > 0){ //判断是否更新成功 out.print("成功添加了 " + row + "条数据~"); //更新成功输出信息 } ps.close(); //关闭PreparedStatement,释放资源 conn.close(); //关闭Connection,释放资源 } catch (Exception e) { out.print("图书信息添加失败~"); e.printStackTrace(); } %>
返回 在AddBook.jsp页面中,首先通过实例化JavaBean对象Book,并通过 对Book对象中的属性赋值,在构建了图书对象后通过JDBC将图书信息写入到数据中。 标签的属性的值可以设置为“”~它的作用是将与表单中同名称property* 的属性值赋给对象中的同名属性。使用这种方式~就不必对中的属性一一进JavaBeanJavaBean 行赋值~从而减少程序中的代码量。 向数据库插入图书信息的过程中,主要通过PreparedStatement对象进行操作。使用PreparedStatement 对象,其SQL语句中的参数可以使用占位符“?”代替,再通过PreparedStatement对象对SQL语句中 的参数逐一赋值,将图书信息传递到SQL语句中。 使用对象对语句的占位符参数赋值~其参数的下标值不是~而是~PreparedStatementSQL01 它与数组的下标有所区别。 207 Java Web从入门到精通,第2版, 通过PreparedStatement对象对SQL语句中的参数进行赋值后,还不能将图书信息写入到数据库中,需要调用它的executeUpdate()方法执行更新操作,此时才能将图书信息写入到数据库中。该方法被执行后返回int型数据,其含义是所影响的行数,实例中将其获取并输出到页面中。 在执行数据操作之后~应该立即调用对象、对象、对ResultSetPreparedStatementConnection 象的方法~从而及时释放所占用的数据库资源。close() 编写完成AddBook.jsp页面后,部署并运行程序,将进入到添加图书信息页面,其效果如图10.4所示。 正确填写图书信息后,单击“添加”按钮,图书信息数据将被写入到数据库中,此时页面输出提示信息,其效果如图10.5所示。 图10.4 添加图书信息 图10.5 图书信息添加成功 图书信息添加成功后,可通过查看数据库中的数据来验证插入结果。 由于值设置了自动编号~所以添加的图书信息中的为自动生成~数据表中显示ididtb_books 最后一条数据为添加的数据。 10.3.2 查询数据 使用JDBC查询数据与添加数据的流程基本相同,光标但执行查询数据操作后需要通过一个对象来装载查询结 第一条数据光标果集,这个对象就是ResultSet对象。 第二条数据光标ResultSet对象是JDBC API中封装的结果集对象, 光标„从数据表中所查询到的数据都放置在这个集合中,其结 构如图10.6所示。 最后一条数据光标 光标 208 图10.6 ResultSet结构图 第10章 Java Web的数据库操作 从图10.6中可以看出,在ResultSet集合中,通过移动“光标”来获取所查询到的数据,ResultSet 对象中的“光标”可以进行上下移动,如获取ResultSet集合中的一条数据,只需要把“光标”定位到当前 数据光标行即可。 从图中可以看出~集合所查询的数据位于集合的中间位置~在第一条数据之前10.6ResultSet 与最后一条数据之后都有一个位置~默认情况下~的光标位置在第一行数据之前~所以~ResultSet 在第一次获取数据时就需要移动光标位置。 【例10.4】 创建Web项目,通过JDBC查询图书信息表中的图书信息数据,并将其显示在JSP 页面中。,实例位置,光盘\TM\sl\10\3, (1)创建名称为Book的类,用于封装图书信息。关键代码如下: public class Book { private int id; //编号 private String name; //图书名称 private double price; //价格 private int bookCount; //数量 private String author; //作者 public int getId() { return id; } public void setId(int id) { this.id = id; } //省略部分setXXX()与getXXX()方法 } (2)创建名称为FindServlet的Servlet对象,用于查询所有图书信息。在此Servlet中,编写doGet() 方法,建立数据库连接,并将所查询的数据集合放置到HttpServletRequest对象中,将请求转发到JSP 页面。关键代码如下: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/db_database11"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 Connection conn = DriverManager.getConnection(url,username,password); //创建Connection连接 Statement stmt = conn.createStatement(); //获取Statement对象 String sql = "select * from tb_book"; //添加图书信息的SQL语句 ResultSet rs = stmt.executeQuery(sql); //执行查询 List list = new ArrayList(); //实例化List对象 while(rs.next()){ //光标向后移动,并判断是否有效 209 Java Web从入门到精通,第2版, Book book = new Book(); //实例化Book对象 book.setId(rs.getInt("id")); //对id属性赋值 book.setName(rs.getString("name")); //对name属性赋值 book.setPrice(rs.getDouble("price")); //对price属性赋值 book.setBookCount(rs.getInt("bookCount")); //对bookCount属性赋值 book.setAuthor(rs.getString("author")); //对author属性赋值 list.add(book); //将图书对象添加到集合中 } request.setAttribute("list", list); //将图书集合放置到request中 rs.close(); //关闭ResultSet stmt.close(); //关闭Statement conn.close(); //关闭Connection } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } request.getRequestDispatcher("book_list.jsp").forward(request, response); //请求转发到book_list.jsp } 在doGet()方法中,首先获取了数据库的连接Connection;然后通过Statement对象执行查询图书信 息的SELECT语句,并获取ResultSet结果集;最后遍历ResultSet中的数据来封装图书对象Book,将 其添加到List集合中,转发到显示页面进行显示。 集合中第一行数据之前与最后一行数据之后都存在一个位置~而默认情况下光标位ResultSet 于第一行数据之前~使用中的循环、循环等都不能很好地对其遍历。所以~实Javafordo…while 例中使用条件循环遍历对象~在第一次循环时~就会执行条件~将光标whileResultSetrs.next()移动到第一条数据的位置。 获取到ResultSet对象后,就可以通过移动光标定位到查询结果中的指定行,然后通过ResultSet 对象提供的一系列getXXX()方法来获取当前行的数据。 使用对象提供的方法获取数据~其数据类型要与数据表中的字段类型相对ResultSetgetXXX() 应~否则~将抛出异常。java.sql.SQLException (3)创建book_list.jsp页面,用于显示所有图书信息。关键代码如下: 210 第10章 Java Web的数据库操作 <% //获取图书信息集合 List list = (List)request.getAttribute("list"); //判断集合是否有效 if(list == null || list.size() < 1){ out.print("没有数据~"); }else{ //遍历图书集合中的数据 for(Book book : list){ %> <% } } %>

所有图书信息

ID 图书名称 价格 数量 作者
<%=book.getId()%> <%=book.getName()%> <%=book.getPrice()%> <%=book.getBookCount()%> <%=book.getAuthor()%>
由于FindServlet将查询的所有图书信息集合放置到了request中,所以在book_list.jsp页面中,可 以通过request的getAttribute()方法获取到这一集合对象。实例中在获取所有图书信息集合后,通过for 循环遍历了所有图书信息集合,并将其输出到页面中。 在页面中~实例使用循环遍历所有图书信息~这种方式可以简化程序的代码。book_list.jspfor/in (4)创建index.jsp页面,该页面是程序中的主页,在该页面中编写一个导航链接,用于请求查看 所有图书信息。关键代码如下: 查看所有图书 211 Java Web从入门到精通,第2版, 部署并运行程序后,将打开index.jsp页面,单击“查看所有图书”超链接后,可以查看到从数据库中查询的所有图书信息,其运行结果如图10.7所示。 图10.7 查询所有图书信息 10.3.3 修改数据 使用JDBC修改数据库中的数据,其操作方法与添加数据相似,只不过修改数据需要使用UPDATE语句实现,如把图书id为1的图书数量修改成100,其SQL语句如下: update tb_book set bookcount=100 where id=1 在实际开发中,通常情况下都是由程序传递SQL语句中的参数,所以修改数据也需要使用PreparedStatement对象进行操作。 【例10.5】 在查询所有图书信息的页面中,添加修改图书数量表单,通过Servlet修改数据库中的图书数量。,实例位置,光盘\TM\sl\10\4, (1)在book_list.jsp页面中增加修改图书数量的表单,将该表单的提交地址设置为UpdateServlet。关键代码如下: 212 第10章 Java Web的数据库操作 <% //获取图书信息集合 List list = (List)request.getAttribute("list"); //判断集合是否有效 if(list == null || list.size() < 1){ out.print("没有数据~"); }else{ //遍历图书集合中的数据 for(Book book : list){ %> <% } } %>

所有图书信息

ID 图书名称 价格 数量 作者 修改数量
<%=book.getId()%> <%=book.getName()%> <%=book.getPrice()%> <%=book.getBookCount()%> <%=book.getAuthor()%>
在修改图书信息的表单中主要包含了两个属性信息,分别为图书id与图书数量bookCount,因为 修改图书数量时需要明确指定图书的id作为修改的条件,否则,将会修改所有图书信息记录。 由于图书属性并不需要显示在表单中~而在图书信息的修改过程中又需要获取这个值~所id 以~将对应文本框中的属性设置为~使之在表单中构成一个隐藏域~从而idtypehidden 实现实际的业务需求。 (2)创建修改图书信息请求的Servlet对象,其名称为UpdateServlet。由于表单提交的请求类型 为post,所以在UpdateServlet中编写doPost()方法,对修改图书信息请求进行处理。关键代码如下: protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.valueOf(request.getParameter("id")); int bookCount = Integer.valueOf(request.getParameter("bookCount")); try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 213 Java Web从入门到精通,第2版, String url = "jdbc:mysql://localhost:3306/db_database11"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 Connection conn = DriverManager.getConnection(url,username,password); //创建Connection连接 String sql = "update tb_book set bookcount=? where id=?"; //更新SQL语句 PreparedStatement ps = conn.prepareStatement(sql); //获取PreparedStatement ps.setInt(1, bookCount); //对SQL语句中的第1个参数赋值 ps.setInt(2, id); //对SQL语句中的第2个参数赋值 ps.executeUpdate(); //执行更新操作 ps.close(); //关闭PreparedStatement conn.close(); //关闭Connection } catch (Exception e) { e.printStackTrace(); } response.sendRedirect("FindServlet"); //重定向到FindServlet } 所接受的参数值为类型~而图书与图书数量为类型~所以需HttpServletRequestStringidint 要对其进行转型操作~实例中通过类的方法进行实现。IntegervalueOf() 在UpdateServlet的doPost()方法中,首先通过HttpServletRequest获取图书的id与修改的图书数量,然后建立数据库连接Connection,通过PreparedStatement对SQL语句进行预处理并对SQL语句参数赋值,最后执行更新操作。 一定要关闭数据库连接~从而及时释放所占用的数据库资源。 在执行了图书数量的更新操作后,实例中通过HttpServletRequest对象将请求重定向到FindServlet,进行查看更新后的结果。 实例运行后,进入程序中的首页页面,单击 “查看所有图书”超链接后,进入到图书信息列 表页面,在该页面中可以对图书数量进行修改, 如图10.8所示。 在正确填写了图书数量后,单击“修改”按 钮即可将图书数量更新到数据中。 10.3.4 删除数据 图10.8 修改图书数量 删除数据使用的SQL语句为DELETE语 句,如删除图书id为1的图书信息,其SQL语句如下: delete from tb_book where id=1 214 第10章 Java Web的数据库操作 在实际开发中,通常情况下都是由程序传递SQL语句中的参数,所以修改数据也需要使用 PreparedStatement对象进行操作。 【例10.6】 在查询所有图书信息的页面中,添加删除图书信息的超链接,通过Servlet实现对数 据的删除操作。,实例位置,光盘\TM\sl\10\5, (1)在book_list.jsp页面中,增加删除图书信息的超链接,将链接的地址指向DeleteServlet。关 键代码如下: <% //获取图书信息集合 List list = (List)request.getAttribute("list"); //判断集合是否有效 if(list == null || list.size() < 1){ out.print("没有数据~"); }else{ //遍历图书集合中的数据 for(Book book : list){ %> <% } } %>

所有图书信息

ID 图书名称 价格 数量 作者 删 除
<%=book.getId()%> <%=book.getName()%> <%=book.getPrice()%> <%=book.getBookCount()%> <%=book.getAuthor()%> 删除
215 Java Web从入门到精通,第2版, 在删除数据信息操作中,需要传递所要删除的图书对象,因此,在删除图书信息的超链接中加入图书id值。 在开发中~页面中的超链接可以带有参数~其操作方式通过在超链接后加入“”Java WebJSP? 实现。 (2)编写处理删除图书信息的Servlet,其名称为DeleteServlet。在doGet()方法中,编写删除图书信息的方法。关键代码如下: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.valueOf(request.getParameter("id")); //获取图书id try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/db_database10"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 Connection conn = DriverManager.getConnection(url,username,password); //创建Connection连接 String sql = "delete from tb_book where id=?"; //删除图书信息的SQL语句 PreparedStatement ps = conn.prepareStatement(sql); //获取PreparedStatement ps.setInt(1, id); //对SQL语句中的第一个占位符赋值 ps.executeUpdate(); //执行更新操作 ps.close(); //关闭PreparedStatement conn.close(); //关闭Connection } catch (Exception e) { e.printStackTrace(); } response.sendRedirect("FindServlet"); //重定向到FindServlet } 在DeleteServlet类的doGet()方法中,首先获取要删除的图书id值,然后创建数据库连接Connection,通过PreparedStatement对SQL语句进行预处理并对SQL语句参数赋值,最后执行删除操作。 在完成删除数据操作后~通过对象将请求重定向到~DeleteServletHttpServletResponseFindServlet 再次执行查询所有图书信息操作~从而实现查看删除后的结果。 实例运行后,进入程序中的首页,单击“查看所有 图书”超链接后,进入到图书信息列表页面,在该页面 中可以看到每一条图书信息的超链接,如图10.9所示。 单击每一条图书信息对应的“删除”超链接后,此 条图书信息将从数据库中删除。 216 图10.9 删除图书数量 第10章 Java Web的数据库操作 10.3.5 批处理 在JDBC开发中,操作数据库需要与数据库建立连接,然后将要执行的SQL语句传送到数据库服务器,最后关闭数据库连接,都是按照这样一个流程进行操作的。如果按照该流程执行多条SQL语句,那么就需要建立多个数据库连接,这样会将时间浪费在数据库连接上。针对这一问题,JDBC的批处理提供了很好的解决。 JDBC中批处理的原理是将批量的SQL语句一次性发送到数据库中进行执行,从而解决多次与数据库连接所产生的速度瓶颈。 【例10.7】 创建学生信息表,通过JDBC的批处理操作,一次性将多个学生信息写入到数据库中。,实例位置,光盘\TM\sl\10\6, (1)创建学生信息表tb_student_batch,其结构如图10.10所示。 图10.10 学生信息表tb_student_batch (2)创建名称为Batch的类,该类用于实现对学生信息的批量添加操作。首先在Batch类中编写getConnection()方法,用于获取数据库连接Connection对象,其关键代码如下: /** * 获取数据库连接 * @return Connection对象 */ public Connection getConnection(){ Connection conn = null; //数据库连接 try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/db_database10"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 conn = DriverManager.getConnection(url,username,password); //创建Connection连接 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; //返回数据库连接 } 然后编写saveBatch()方法,实现批量添加学生信息功能,实例中主要通过PreparedStatement对象批量添加学生信息。关键代码如下: /** * 批量添加数据 217 Java Web从入门到精通,第2版, * @return 所影响的行数 */ public int saveBatch(){ int row = 0 ; //行数 Connection conn = getConnection(); //获取数据库连接 try { String sql = "insert into tb_student_batch(id,name,sex,age) values(?,?,?,?)";//插入数据的SQL语句 PreparedStatement ps = conn.prepareStatement(sql); //创建PreparedStatement Random random = new Random(); //实例化Random for (int i = 0; i < 10; i++) { //循环添加数据 ps.setInt(1, i+1); //对SQL语句中的第1个参数赋值 ps.setString(2, "学生" + i); //对SQL语句中的第2个参数赋值 ps.setBoolean(3, i % 2 == 0 ? true : false); //对SQL语句中的第3个参数赋值 ps.setInt(4, random.nextInt(5) + 10); //对SQL语句中的第4个参数赋值 ps.addBatch(); //添加批处理命令 } int[] rows = ps.executeBatch(); //执行批处理操作并返回计数组成的数组 row = rows.length; //对行数赋值 ps.close(); //关闭PreparedStatement conn.close(); //关闭Connection } catch (Exception e) { e.printStackTrace(); } return row; //返回添加的行数 } 本实例在创建了PreparedStatement对象后,通过for循环向PreparedStatement批量添加SQL命令, 其中学生信息数据通过程序模拟生成。 对于学生性别字段~实例中对其赋值为布尔类型~如果变量整除则为~否则为。i2truefalse 此操作通过“”的语句进行实现~它相当于语句~使用此种代码编写方式~可以简化程?:if…else 序中的代码。 执行批处理操作后,实例中获取返回计数组成的数组,将数组的长度赋值给row变量,来计算数 据库操作所影响到的行数。 对象的批处理操作调用的是方法~而不是方法或PreparedStatementexecuteBatch()execute() 方法。executeUpdate() (3)创建程序中的首页index.jsp,在该页面中通过实例化Batch对象,并执行批量 添加数据操作。关键代码如下: <% //执行批量插入操作 218 第10章 Java Web的数据库操作 int row = batch.saveBatch(); out.print("批量插入了【" + row + "】条数据~"); %> 实例运行后,程序向数据库批量添加了10条学生信息数据,其运行结果如图10.11所示。 运行成功后,可以打开数据表tb_student_batch进行查看,其效果如图10.12所示。 图10.11 实例运行结果 图10.12 表tb_student_batch中的数据 10.3.6 调用存储过程 在JDBC API中提供了调用存储过程的方法,通过CallableStatement对象进行操作。CallableStatement 对象位于java.sql包中,它继承于Statement对象,主要用于执行数据库中定义的存储过程,其调用方法如下: {call [(,, ...)]} 其中,arg1、arg2为存储过程中的参数,如果存储过程中需要传递参数,可以对其进行赋值操作。 存储过程是一个语句和可选控制流语句的预编译集合。编译完成后存放在数据库中~这SQL 样就省去了执行语句时对语句进行编译所花费的时间。在执行存储过程时只需要将参数SQLSQL 传递到数据库中~而不需要将整条语句都提交给数据库~从而减少了网络传输的流量~从另SQL 一方面提高了程序的运行速度。 【例10.8】 创建查询所有图书信息的存储过程,通过JDBC API对其调用获取所有图书信息,并将其输出到JSP页面中。,实例位置,光盘\TM\sl\10\7, (1)在数据库db_database10中创建名称为findAllBook的存储过程,用于查询所有图书信息。关键代码如下: DELIMITER $$ CREATE PROCEDURE findAllBook() BEGIN SELECT * FROM tb_books order by id desc; END $$ DELIMITER ; 219 Java Web从入门到精通,第2版, 各种数据库创建存储过程的方法并非一致~本实例使用的是数据库~如使用其他数据MySQL 库创建存储过程请参阅数据库提供的帮助文档。 (2)创建名称为Book的类,该类用于封装图书信息的JavaBean对象。关键代码如下: public class Book { private int id; //编号 private String name; //图书名称 private double price; //价格 private int bookCount; //数量 private String author; //作者 public int getId() { return id; } public void setId(int id) { this.id = id; } //省略部分setXXX()与getXXX()方法 } (3)创建名称为FindBook的类,用于执行查询图书信息的存储过程。首先在该类中编写 getConnection()方法,获取数据库连接对象Connection,其关键代码如下: /** * 获取数据库连接 * @return Connection对象 */ public Connection getConnection(){ Connection conn = null; //数据库连接 try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/db_database10"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 conn = DriverManager.getConnection(url,username,password);//创建Connection连接 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; //返回数据库连接 } 然后编写findAll()方法,调用数据库中定义的存储过程findAllBook,查询所有图书信息,并将查 询到图书的信息放置到List集合中。关键代码如下: /** 220 第10章 Java Web的数据库操作 * 通过存储过程查询数据 * @return List */ public List findAll(){ List list = new ArrayList(); //实例化List对象 Connection conn = getConnection(); //创建数据库连接 try { CallableStatement cs = conn.prepareCall("{call findAllBook()}"); //调用存储过程 ResultSet rs = cs.executeQuery(); //执行查询操作,并获取结果集 while(rs.next()){ //判断光标向后移动,并判断是否有效 Book book = new Book(); //实例化Book对象 book.setId(rs.getInt("id")); //id属性赋值 book.setName(rs.getString("name")); //对name属性赋值 book.setPrice(rs.getDouble("price")); //对price属性赋值 book.setBookCount(rs.getInt("bookCount")); //对bookCount属性赋值 book.setAuthor(rs.getString("author")); //对author属性赋值 list.add(book); //将图书对象添加到集合中 } } catch (Exception e) { e.printStackTrace(); } return list; //返回list } 由于存储过程findAllBook中没有定义参数,所以实例中通过调用“{call findAllBook()}”来调用 存储过程。 通过创建对象后~还需要通过对象的ConnectionCallableStatementCallableStatementexecuteQuery() 方法来执行存储过程~在调用该方法后就可以获取对象和查询结果集。ResultSet (4)创建程序中的主页index.jsp,在该页面中实例化FindBook对象,并调用它的find()方法获取 所有图书信息,将图书信息数据显示在页面中。关键代码如下: 221 Java Web从入门到精通,第2版, <% List list = findBook.findAll(); //获取图书信息集合 if(list == null || list.size() < 1){ //判断集合是否有效 out.print("没有数据~"); }else{ for(Book book : list){ //遍历图书集合中的数据 %> <% } } %>

所有图书信息

ID 图书名称 价格 数量 作者
<%=book.getId()%> <%=book.getName()%> <%=book.getPrice()%> <%=book.getBookCount()%> <%=book.getAuthor()%>
实例运行后,进入到index.jsp页面,程序将执行数据库中定义的存储过程findAllBook查询图书信 息,其运行结果如图10.13所示。 图10.13 调用存储过程查询数据 10.4 JDBC在Java Web中的应用 视频讲解,光盘\TM\lx\10\JDBC在Java Web中的应用.exe 在Java Web开发中,JDBC的应用十分广泛。通常情况下,Web程序操作数据库都是通过JDBC 实现,即使目前数据库方面的开源框架层出不穷,但其底层实现也离不开JDBC API。 222 第10章 Java Web的数据库操作 10.4.1 开发模式 在Java Web开发中使用JDBC,应遵循MVC(Model-View-Controller)的思想,从而使Web程序拥有一定的健壮性、可扩展性。 MVC是一种程序设计理念,该理念将软件分成3层结构,分别为模型层、视图层和控制层。其中,模型层泛指程序中的业务逻辑,用于处理真正的业务操作;视图层是指程序与用户相交互的界面,对用户呈现出视图,但不包含业务逻辑;控制层是对用户各种请求的分发处理,将指定的请求分配给指定的业务逻辑进行处理。 在古老的开发模式中~程序开发并没有分层的概念~其业务逻辑代码、视图代码均写在一起~ 这样的开发方式不利于软件的维护及扩展~也不能达到代码的重用。可以想象一下~将、、HTMLJSP 编写到一起的效果~如何对这样的程序进行调试。设计思想则改变了这一缺点~模型层、JDBCMVC 视图层与控制层各自独立~降低了程序中的耦合~如果业务逻辑及业务发生了改变~则只需要 更改模型层代码即可~而不需要去操作视图层与控制层~因为模型层与视图层、控制层相隔离。所 以~在程序开发中~应该遵循思想。 MVC JDBC应用于Java Web开发中,处于MVC中的模型层位置,如图10.14所示。 JSP页面 (视图层) JavaBean (模型层) 数据库 客 户 端Servlet (控制层) 图10.14 Java Web中的MVC 客户端通过JSP页面与程序进行交互,对于数据的增、删、改、查请求由Servlet对其进行分发处理,如Servlet接收到添加数据请求,就会分发给增加数据的JavaBean对象,而真正的数据库操作是通过JDBC封装的JavaBean进行实现。 10.4.2 分页查询 分页查询是Java Web开发中常用的技术。在数据库量非常大的情况下,不适合将所有数据显示到一个页面中,既给查看带来方便,又占用了程序及数据库的资源,此时就需要对数据进行分页查询。 通过JDBC实现分页查询的方法有很多种,而且不同的数据库机制也提供了不同的分页方式,在 223 Java Web从入门到精通,第2版, 这里介绍两种非常典型的分页方法。 , 通过ResultSet的光标实现分页 ResultSet是JDBC API中封装的查询结果集对象,通过该对象可以实现数据的分页显示。在ResultSet对象中,有一个“光标”的概念,光标通过上下移动定位查询结果集中的行,从而获取数据。所以通过ResultSet的移动“光标”,可以设置ResultSet对象中记录的起始位置和结束位置来实现数据的分页显示。 通过ResultSet的光标实现分页,优点是在各种数据库上通用,缺点是占用大量资源,不适合数据量大的情况。 , 通过数据库机制进行分页 很多数据库自身都提供了分页机制,如SQL Server中提供的top关键字,MySQL数据库中提供的limit关键字,它们都可以设置数据返回的记录数。 通过各种数据库提供的分页机制实现分页查询,其优点是减少数据库资源的开销,提高程序的性能;缺点是只针对某一种数据库通用。 由于通过的光标实现数据分页存在性能方面的缺陷~所以~在实际开发中~很多情ResultSet 况下都是采用数据库提供的分页机制来实现分页查询功能。 【例10.9】 通过MySQL数据库提供的分页机制,实现商品信息的分页查询功能,将分页数据显示在JSP页面中。,实例位置,光盘\TM\sl\10\8, (1)创建名称为Product的类,用于封装商品信息,该类是商品信息的JavaBean。关键代码如下: public class Product { public static final int PAGE_SIZE = 2; //每页记录数 private int id; //编号 private String name; //名称 private double price; //价格 private int num; //数量 private String unit; //单位 public int getId() { return id; } public void setId(int id) { this.id = id; } //省略部分setXXX()与getXXX()方法 } 在Product类中,主要封装了商品对象的基本信息。除此之外,Product类还定义了分页中的每页记录数,它是一个静态变量,可以直接对其进行引用。同时,由于每页记录数并不会被经常修改,所以实例将其定义为final类型。 224 第10章 Java Web的数据库操作 在语言中~如果定义了静态的类型变量~通常情况下将这个变量大写。该种编写方Javafinal 式是一种规范~能够很容易地与其他类型的变量进行区分。 (2)创建名称为ProductDao的类,主要用于封装商品对象的数据库相关操作。在ProductDao类 中,首先编写getConnection()方法,用于创建数据库连接Connection对象,其关键代码如下: public class ProductDao { /** * 获取数据库连接 * @return Connection对象 */ public Connection getConnection(){ Connection conn = null; //数据库连接 try { Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动,注册到驱动管理器 String url = "jdbc:mysql://localhost:3306/db_database10"; //数据库连接字符串 String username = "root"; //数据库用户名 String password = "111"; //数据库密码 conn = DriverManager.getConnection(url,username,password); //创建Connection连接 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; //返回数据库连接 } 对象是每一个数据操作方法都要用到的对象~所以实例中封装方法ConnectiongetConnection() 创建对象~实现代码的重用。Connection 然后创建商品信息的分页查询方法find(),该方法包含一个page参数,用于传递要查询的页码。 关键代码如下: /** * 分页查询所有商品信息 * @param page 页数 * @return List */ public List find(int page){ List list = new ArrayList(); //创建List Connection conn = getConnection(); //获取数据库连接 String sql = "select * from tb_product order by id desc limit ?,?"; //分页查询的SQL语句 try { PreparedStatement ps = conn.prepareStatement(sql); //获取PreparedStatement ps.setInt(1, (page - 1) * Product.PAGE_SIZE); //对SQL语句中的第1个参数赋值 ps.setInt(2, Product.PAGE_SIZE); //对SQL语句中的第2个参数赋值 225 Java Web从入门到精通,第2版, ResultSet rs = ps.executeQuery(); //执行查询操作 while(rs.next()){ //光标向后移动,并判断是否有效 Product p = new Product(); //实例化Product p.setId(rs.getInt("id")); //对id属性赋值 p.setName(rs.getString("name")); //对name属性赋值 p.setNum(rs.getInt("num")); //对num属性赋值 p.setPrice(rs.getDouble("price")); //对price属性赋值 p.setUnit(rs.getString("unit")); //对unit属性赋值 list.add(p); //将Product添加到List集合中 } rs.close(); //关闭ResultSet ps.close(); //关闭PreparedStatement conn.close(); //关闭Connection } catch (SQLException e) { e.printStackTrace(); } return list; } find()方法用于实现分页查询功能,该方法根据入口参数page传递的页码,查询指定页码中的记录,主要通过limit关键字实现。 MySQL数据库提供的limit关键字能够控制查询数据结果集起始位置及返回记录的数量~它的 使用方式如下: limit arg1,arg2 参数说明: , arg1:用于指定查询记录的起始位置。 , arg2:用于指定查询数据所返回的记录数。 find()方法主要应用limit关键字编写分页查询的SQL语句,其中limit关键字的两个参数通过PreparedStatement对其进行赋值,第1个参数为查询记录的起始位置,根据find()方法中的页码参数page可以对其进行计算,其算法为(page - 1) * Product.PAGE_SIZE;第2个参数为返回的记录数,也就是每一页所显示的记录数量,其值为Product.PAGE_SIZE。 在对SQL语句传递了这两个参数后,执行PreparedStatement对象的executeQuery()方法,就可以获取到指定页码中的结果集,实例中将所查询的商品信息封装为Product对象,放置到List集合中,最后将其返回。 ProductDao类主要用于封装商品信息的数据库操作,所以对于商品信息数据库操作相关方法应定义在该类中。在分页查询过程中,还需要获取商品信息的总记录数,用于计算商品信息的总页数,该操作编写在findCount()方法中。关键代码如下: /** * 查询总记录数 226 第10章 Java Web的数据库操作 * @return 总记录数 */ public int findCount(){ int count = 0; //总记录数 Connection conn = getConnection(); //获取数据库连接 String sql = "select count(*) from tb_product"; //查询总记录数SQL语句 try { Statement stmt = conn.createStatement(); //创建Statement ResultSet rs = stmt.executeQuery(sql); //查询并获取ResultSet if(rs.next()){ //光标向后移动,并判断是否有效 count = rs.getInt(1); //对总记录数赋值 } rs.close(); //关闭ResultSet conn.close(); //关闭Connection } catch (SQLException e) { e.printStackTrace(); } return count; //返回总记录数 } } 查询商品信息总记录数的SQL语句为“select count(*) from tb_product”,findCount()方法主要通过 执行这条SQL语句获取总记录数的值。 获取查询结果需要调用对象的方法向下移动光标~由于所获取的数据只是单一ResultSetnext() 的一个数值~所以实例中通过进行调用~而没有使用调用。if(rs.next())while (3)创建名称为FindServlet的类,该类是分页查询商品信息的Servlet对象。在FindServlet类中 重写doGet()方法,对分页请求进行处理,其关键代码如下: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int currPage = 1; //当前页码 if(request.getParameter("page") != null){ //判断传递页码是否有效 currPage = Integer.parseInt(request.getParameter("page")); //对当前页码赋值 } ProductDao dao = new ProductDao(); //实例化ProductDao List list = dao.find(currPage); //查询所有商品信息 request.setAttribute("list", list); //将list放置到request中 int pages ; //总页数 int count = dao.findCount(); //查询总记录数 if(count % Product.PAGE_SIZE == 0){ //计算总页数 pages = count / Product.PAGE_SIZE; //对总页数赋值 }else{ pages = count / Product.PAGE_SIZE + 1; //对总页数赋值 } StringBuffer sb = new StringBuffer(); //实例化StringBuffer 227 Java Web从入门到精通,第2版, for(int i=1; i <= pages; i++){ //通过循环构建分页条 if(i == currPage){ //判断是否为当前页 sb.append("『" + i + "』"); //构建分页条 }else{ sb.append("" + i + ""); //构建分页条 } sb.append(" "); //构建分页条 } request.setAttribute("bar", sb.toString()); //将分页条的字符串放置到request之中 request.getRequestDispatcher("product_list.jsp").forward(request, response);//转发到product_list.jsp页面 } FindServlet类的doGet()方法主要做了两件事,分别为获取分页查询结果集及构造分页条对象。其中获取分页查询结果非常简单,通过调用ProductDao类的find()方法,并传递所要查询的页码就可以获取;分页条对象是JSP页面中的分页条,用于显示商品信息的页码,程序中主要通过创建页码的超链接,然后组合字符串进行构造。 分页条在页面中是动态内容~每次查看新页面都要重新构造~所以~实例中将分页的构造JSP 放置到中~以简化页面的代码。ServletJSP 在构建分页条时,需要计算商品信息的总页码,它的值通过总记录数与每页记录数计算得出,计算得出总页码后,实例中通过StringBuffer组合字符串构建分页条。 如果一个字符串经常发生变化~应该使用对字符进行操作。因为在中~每次StringBufferJVM创建一个新的字符串~都需要分配一个字符串空间~而 则是字符串的缓冲区~所以在StringBuffer经常修改字符串的情况下~ 性能更高。StringBuffer 在获取查询结果集List与分页条后,FindServlet分别将这两个对象放置到request中,将请求转发到product_list.jsp页面做出显示。 (4)创建product_list.jsp页面,该页面通过获取查询结果集List与分页条来分页显示商品信息数据。关键代码如下: 228 第10章 Java Web的数据库操作 <% List list = (List)request.getAttribute("list"); for(Product p : list){ %> <% } %>

所有商品信息

ID 商品名称 价格 数量单位
<%=p.getId()%> <%=p.getName()%> <%=p.getPrice()%> <%=p.getNum()%> <%=p.getUnit()%>
<%=request.getAttribute("bar")%>
查询结果集List与分页条均从request对象中进行获取,其中结果集List通过for循环遍历并将每 一条商品信息输出到页面中,分页条输出到商品信息下方。 (5)编写程序中的主页面index.jsp,在该页面中编写分页查询商品信息的超链接,指向FindServlet。 关键代码如下: 查看所有商品信息 编写完成该页面后,部署运行项目,此时打开index.jsp页面, 其效果如图10.15所示。 单击页面中的“查看所有商品信息”超链接后,将看到商品 信息的分页显示结果,如图10.16所示。 从图10.16可以看到商品信息的分页条,所有商品信息分3 页进行显示,单击分页条中的超链接可以查看指定页面的商品信图10.15 index.jsp页面 息数据,如查看第2页数据,其运行结果如图10.17所示。 229 Java Web从入门到精通,第2版, 图10.16 分页显示商品信息(1) 图10.17 分页显示商品信息(2) 230 第10章 Java Web的数据库操作 10.5 小 结 本章首先对JDBC技术及JDBC连接数据的过程作了介绍;然后对JDBC API中的常用对象进行了介绍,这些常用对象需要读者重点了解,掌握各对象的主要功能及作用;之后又介绍了JDBC操作数据库的方法,在这一部分内容中,需要重点掌握通过JDBC API实现数据的增、删、改、查方法;最后介绍了JDBC在Java Web中的应用,该部分需要理解MVC设计思想,掌握JDBC在Java Web中的开发模式,以及掌握如何实现数据的分页查询。 10.6 实践与练习 1(向数据库中添加学生信息。,答案位置,光盘\TM\sl\10\9, 2(查询所有学生信息,并将查询结果输出到JSP页面中。,答案位置,光盘\TM\sl\10\10, 3(通过JDBC的批处理功能,批量删除学生信息数据。,答案位置,光盘\TM\sl\10\11, 231
/
本文档为【无论是一个小型的企业办公自动化系统,还是像中国移动那】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索