JDBC
JDBC
制作人:全心全意
JDBC简介
JDBC是Java程序操作数据库的API,也是Java程序与数据库相交互的一门技术。JDBC是Java操作数据库的规范,由一组用Java语言编写的类和接口组成,它对数据库的操作提供基本方法,但对于数据库的操作细节由数据库厂商进行实现,使用JDBC操作数据库,需要数据库厂商提供数据库的驱动程序,关于Java程序与数据相交互的示意图如下图所示。
通过上图可以看出,JDBC在Java程序与数据库之间起到了一个桥梁的作用,有了JDBC就可以方便地与各种数据库进行交互,不必为某一特定的数据库制定专门的访问程序。
JDBC连接数据库的过程
JDBC操作数据库的开发流程,其关键步骤如下
- 注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
- 构建数据库连接URL
要建立数据库连接,就要构建数据库连接的URL,这个URL由数据库厂商制定,不同的数据库,它的URL也有所区别,但都符合一个基本的格式,即“JDBC协议+IP地址或域名+端口+数据库名称”。如MySQL的数据库连接URL的字符串为“jdbc:mysql://localhost:3306/test”
- 获取Connection对象
在注册了数据库驱动及构建数据库URL后,就可以通过驱动管理器获取数据库的连接Connection。Connection对象是JDBC封装的数据库连接对象,只有创建此对象后,才可以对数据库进行相关操作,它的获取方法如下:
Connection conn = DriverManager.getConnection(url,username,password);
Connection对象的获取需要用到DriverManager对象,DriverManager的getConnection()方法通过数据库连接URL、数据库用户名及数据库密码创建Connection对象。
实例1:通过JDBC连接MySQL数据库实例
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@page import="java.sql.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>通过JDBC连接MySQL数据库</title> </head> <body> <% try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/tjj"; String username = "root"; String password = ""; Connection conn = DriverManager.getConnection(url, username, password); if (conn != null) { out.println("数据库连接成功!"); conn.close(); } else { out.println("数据库连接失败!"); } } catch (ClassNotFoundException e) { out.println("数据库连接失败!"); e.printStackTrace(); } catch (SQLException e) { out.println("数据库连接失败!"); e.printStackTrace(); } %> </body> </html>
小技巧:Class的forName()方法的作用是将指定字符串名的类加载到JVM中,实例中调用该方法来加载数据库驱动,在加载后,数据库驱动程序将会把驱动类自动注册到驱动管理器中
JDBC API
- Connection接口
Connection接口位于java.sql包中,是与特定数据库的连接会话,只有获得特定数据库的连接对象,才能访问数据库,操作数据库中的数据表、视图和存储过程等,Connection接口的方法声明及说明如下表所示。
方 法 声 明 | 说 明 |
void close() throws SQLException | 立即释放Connection对象的数据库连接占用的JDBC资源,在操作数据库后,应立即调用此方法 |
void commit() throws SQLException | 提交事务,并释放Connection对象当前持有的所有数据库锁。当事务被设置为手动提交模式时,需要调用该方法提交事务 |
Statement createStatement() throws SQLException | 创建一个Statement对象来将SQL语句发送到数据库,该方法返回Statement对象 |
boolean getAutoCommit() throws SQLException | 用于判断Connection对象是否被设置为自动提交模式,该方法返回布尔值 |
DatabaseMetaData getMetaData() throws SQLException | 获取Connection对象所连接的数据库的元数据DatabaseMetaData对象,元数据包括关于数据库的表、受支持的SQL语法、存储过程、此连接功能等信息 |
int getTransactionIsolation() throws SQLException | 获取Connection对象的当前事务隔离级别 |
boolean isClosed() throws SQLException | 判断Connection对象是否与数据库断开连接,该方法返回布尔值。需要注意的是,如果Connection对象与数据库断开连接,则不能再通过Connection对象操作数据库 |
boolean isReadOnly() throws SQLException | 判断Connection对象是否为只读模式,该方法返回布尔值 |
PreparedStatement prepareStatement(String sql) throws Exception | 将参数化的SQL语句预编译并存储在PreparedStatement对象中,并返回所创建的这个PreparedStatement对象 |
void releaseSavepoint(Savepoint savepoint) throws SQLException | 从当前事务中移除指定的Savepoint和后续Savepoint对象 |
void rollback() throws SQLException | 回滚事务,并释放Connection对象当前持有的所有数据库锁。注意该方法需要应用于Connection对象的手动提交模式中 |
void rollback(Savepoint savepoint) throws SQLException | 回滚事务,针对Savepoint对象之后的更改 |
void setAutoCommit(boolean autoCommit) throws SQLException |
设置Connection对象的提交模式,如果参数autoCommit的值设置为true,Connection对象则为自动提交模式;如果参数autoCommit的值设置为false,Connection对象则为手动提交模式 |
void setReadOnly(boolean readOnly) throws SQLException | 将Connection对象的连接模式设置为只读,该方法用于对数据库进行优化 |
Savepoint setSavepoint() throws SQLException | 在当前事务中创建一个未命名的保留点,并返回这个保留点对象 |
Savepoint setSavepoint(String name) throws SQLException | 在当前事务中创建一个指定名称的保留点,并返回这个保留点对象 |
void setTransactionIsolation(int level) throws SQLException | 设置Connection对象的事务隔离级别 |
- DriverManager类
使用JDBC操作数据库,需要使用数据库厂商提供的驱动程序,通过驱动程序可以与数据库进行交互。DriverManager类主要作用于用户及驱动程序之间,它是JDBC中的管理层,通过DriverManager类可以管理数据库厂商提供的驱动程序,并建立应用程序与数据库之间的连接,其方法声明及说明如下表所示。
方 法 声 明 | 说 明 |
public static void deregisterDriver(Driver driver) throws SQLException | 从DriverManager的管理列表中删除一个驱动程序。参数driver为要删除的驱动对象 |
public static Connection getConnection(String url) throws SQLException | 根据指定数据库连接URL,建立与数据库连接Connection。参数url为数据库连接URL |
public static Connection getConnection(String url,Properties info) throws SQLException | 根据指定数据库连接URL及数据库连接属性信息建立数据库连接Connection。参数url为数据库连接URL,参数info为数据库连接属性 |
public static Connection getConnection(String url,String user,String password) throws SQLException | 根据指定数据库连接URL、用户名及密码建立数据库连接Connection,参数url为数据库连接URL,参数user为连接数据库的用户名,参数password为连接数据库的密码 |
public static Enumeration<Driver driver> getDrivers() | 获取当前DriverManager中已加载的所有驱动程序,它的返回值为Enumeration |
public static void registerDriver(Driver driver) throws SQLException | 向DriverManager注册一个驱动对象,参数driver为要注册的驱动 |
- Statement接口
在创建了数据库连接之后,就可以通过程序来调用SQL语句对数据库进行操作,在JDBC中Statement接口封装了这些操作。Statement接口提供了执行语句和获取查询结果的基本方法,其方法声明及说明如下表所示。
方 法 声 明 | 说 明 |
void addBatch(String sql) throws SQLException | 将SQL语句添加到Statement对象的当前命令列表中,该方法用于SQL命令的批处理 |
void clearBatch() throws SQLException | 清空Statement对象中的命令列表 |
void close() throws SQLException | 立即释放Statement对象的数据库和JDBC资源,而不是等待该对象自动关闭时发生此操作 |
boolean execute(String sql) throws SQLException | 执行指定的SQL语句。如果SQL语句返回结果,该方法返回true,否则返回false |
int[] executeBatch() throws SQLException | 将一批SQL命令提交给数据库执行,返回更新计数组成的数组 |
ResultSet executeQuery(String sql) throws SQLException | 执行查询类型(select)的SQL语句,该方法返回查询所获取的结果集ResultSet对象 |
executeUpdate int executeUpdate(String sql) throws SQLException | 执行SQL语句中DML类型(insert、update、delete)的SQL语句,返回更新所影响的行数 |
Connection getConnection() throws SQLException | 获取生成Statement对象的Connection对象 |
boolean isClosed() throws SQLException | 判断Statement对象是否已被关闭,如果被关闭,则不能再调用该Statement对象执行SQL语句,该方法返回布尔值 |
- PreparedStatement接口
Statement接口封装了JDBC执行SQL语句的方法,它可以完成Java程序执行SQL语句的操作,但在实际开发过程中,SQL语句往往需要将程序中的变量做查询条件参数等。使用Statement接口进行操作过于繁琐,而且存在安全方面的缺陷,针对这一问题,JDBC API中封装了Statement的扩展PreparedStatement对象。
PreparedStatement接口继承于Statement接口,它拥有Statement接口中的方法,而且PreparedStatement接口针对带有参数SQL语句的执行操作进行了扩展。应用于PreparedStatement接口中的SQL语句,可以使用占位符“?”来代替SQL语句中的参数,然后再对其进行赋值。PreparedStatement接口的方法声明及说明如下表所示。
方 法 声 明 | 说 明 |
void setBinaryStream(int parameterIndex,InputStream x) throws SQLException | 将输入流x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setBoolean(int parameterIndex,boolean x) throws SQLException | 将布尔值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setByte(int parameterIndex,byte x) throws SQLException | 将byte值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setDate(int parameterIndex,Date x) throws SQLException | 将java.sql.Date值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setDouble(int parameterIndex,double x) throws SQLException | 将double值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setFloat(int parameterIndex,float x) throws SQLException | 将float值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setInt(int parameterIndex,int x) throws SQLException | 将int值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setInt(int parameterIndex,long x) throws SQLException | 将long值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setObject(int parameterIndex,Object x) throws SQLException | 将Object对象x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setShort(int parameterIndex,short x) throws SQLException | 将short值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setString(int parameterIndex,String x) throws SQLException | 将String值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
void setTimestamp(int parameterIndex,Timestamp x) throws SQLException | 将Timestamp值x作为SQL语句中的参数值,parameterIndex为参数位置的索引 |
在示例开发过程中,如果涉及向SQL语句传递参数,最好使用PreparedStatement接口实现。因为使用PreparedStatement接口,不仅可以提高SQL的执行效率,而且还可以避免SQL语句的注入式攻击。
- ResultSet接口
执行SQL语句的查询语句会返回查询的结果集,在JDBC API中,使用ResultSet对象接收查询结果集。
ResultSet接口位于java.sql包中,封装了数据查询的结果集。ResultSet对象包含了符合SQL语句的所有行,针对Java中的数据类型提供了一套getXXX()方法,通过这些方法可以获取每一行中的数据。除此之外,ResultSet还提供了光标的功能,通过光标可以自由定位到某一行中的数据,其方法声明及说明如下表所示。
方 法 声 明 | 说 明 |
boolean absolute(int row) throws SQLException | 将光标移动到ResultSet对象的给定行编号,参数row为行编号 |
void afterLast() throws SQLException | 将光标移动到ResultSet对象的最后一行之后,如果结果集中不包含任何行,则该方法无效 |
void beforeFirst() throws SQLException | 立即释放ResultSet对象的数据库和JDBC资源 |
void deleteRow() throws SQLException | 从ResultSet对象和底层数据库中删除当前行 |
boolean first() throws SQLException | 将光标移动到ResultSet对象的第一行 |
InputStream getBinaryStream(String columnLabel) throws SQLEception | 以byte流的方式获取ResultSet对象当前行中指定列的值,参数columnLabel为列名称 |
Date getDate(String columnLabel) throws SQLException | 以java.sql.Date的方式获取ResultSet对象当前行中指定列的值,参数columnLabel为列名称 |
double getDouble(String columnLabel) throws SQLException | 以double的方式获取ResultSet对象当前行中指定列的值,参数columnLabel为列名称 |
float getFloat(String columnLabel) throws SQLException | 以float的方式获取ResultSet对象当前行中指定列的值,参数columnLabel为列名称 |
int getInt(String columnLabel) throws SQLException | 以int的方式获取ResultSet对象当前行中指定列的值,参数columnLabel为列名称 |
String getString(String columnLabel) throws SQLException | 以String的方式获取ResultSet对象当前行中指定列的值,参数columnLabel为列名称 |
boolean isClosed() throws SQLException | 判断当前ResultSet对象是否已关闭 |
boolean last() throws SQLException | 将光标移动到ResultSet对象的最后一行 |
boolean next() throws SQLException | 将光标位置向后移动一行,如移动的新行有效返回true,否则返回false |
boolean previous() throws SQLException | 将光标位置向前移动一行,如移动的新行有效返回true,否则返回false |
示例一
示例一建表语句
CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `price` double DEFAULT NULL, `bookCount` int(11) DEFAULT NULL, `author` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `tt` (`name`) ) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
添加数据
示例:通过JDBC实现图书添加功能
Book类:封装图书信息
package com.zq; 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; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getBookCount() { return bookCount; } public void setBookCount(int bookCount) { this.bookCount = bookCount; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }
add.jsp页面:放置添加图书信息所需要的表单
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>添加图书信息</title> <script type="text/javascript"> function check(form) { with (form) { if (name.value == "") { alert("图书名称不能为空"); return false; } if (price.value == "") { alert("价格不能为空"); return false; } if (author.value == "") { alert("作者不能为空"); return false; } return true; } } </script> </head> <body> <form action="AddBook.jsp" method="post" onsubmit="return check(this);"> <table align="center" width="450"> <tr> <td align="center" colspan="2"><h2>添加图书信息</h2> <hr></td> </tr> <tr> <td align="right">图书名称:</td> <td><input type="text" name="name"></td> </tr> <tr> <td align="right">价格:</td> <td><input type="text" name="price"></td> </tr> <tr> <td align="right">数量:</td> <td><input type="text" name="bookCount"></td> </tr> <tr> <td align="right">作者:</td> <td><input type="text" name="author"></td> </tr> <tr> <td align="center" colspan="2"><input type="submit" value="添 加"></td> </tr> </table> </form> </body> </html>
AddBook.jsp页面:对添加图书信息请求进行处理,该页面通过JDBC将所提交的信息数据写入到数据库中
<%@page import="java.sql.PreparedStatement"%> <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.Connection"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <% request.setCharacterEncoding("UTF-8"); %> <jsp:useBean id="book" class="com.zq.Book"></jsp:useBean> <jsp:setProperty property="*" name="book" /> <% try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = ""; Connection conn = DriverManager.getConnection(url, username, password); String sql = "insert into test(name,price,bookCount,author) values(?,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, book.getName()); ps.setDouble(2, book.getPrice()); ps.setInt(3, book.getBookCount()); ps.setString(4, book.getAuthor()); int row = ps.executeUpdate(); if (row > 0) { out.print("成功添加了" + row + "条数据!"); } ps.close(); conn.close(); } catch (Exception e) { out.print("图书信息添加失败!"); e.printStackTrace(); } %> <br> <a href="FindServlet">返回</a> </body> </html>
查询数据
使用JDBC查询数据与添加数据的流程基本相同,但执行查询数据操作后需要通过一个对象来装载查询结果集,这个对象就是ResultSet对象。
ResultSet对象是JDBC API中封装的结果集对象,从数据表中所查询到的数据都放置在这个集合中,其结构如下图所示。
从上图中可以看出,在ResultSet集合中,通过移动“光标”来获取所查询到的数据,ResultSet对象中的“光标”可以进行上下移动,如获取ResultSet集合中的一条数据,只需要把“光标”定位到当前数据光标行即可。
注意:ResultSet集合所查询的数据位于集合的中间位置,在第一条数据之前与最后一条数据之后都有一个位置,默认情况下,ResultSet的光标位置在第一行数据之前,所以,在第一次获取数据时就需要移动光标位置。
示例:查询数据示例(列出所有图书信息):
FindServlet类:Servlet对象,用于查询所有图书信息
package com.zq; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/FindServlet") public class FindServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = ""; Connection conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); String sql = "select * from test"; ResultSet rs = stmt.executeQuery(sql); List<Book> list = new ArrayList<Book>(); while (rs.next()) { Book book = new Book(); book.setId(rs.getInt("id")); book.setName(rs.getString("name")); book.setPrice(rs.getDouble("price")); book.setBookCount(rs.getInt("bookCount")); book.setAuthor(rs.getString("author")); list.add(book); } request.setAttribute("list", list); rs.close(); stmt.close(); conn.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } request.getRequestDispatcher("book_list.jsp").forward(request, response); } }
book_list.jsp页面:用于显示所有图书信息
<%@page import="java.util.List"%> <%@page import="com.zq.Book"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>所有图书信息</title> </head> <body> <table align="center" width="450" border="1"> <tr> <td align="center" colspan="5"><h2>所有图书信息</h2></td> </tr> <tr align="center"> <td><b>ID</b></td> <td><b>图书名称</b></td> <td><b>价格</b></td> <td><b>数量</b></td> <td><b>作者</b></td> </tr> <% List<Book> list = (List<Book>) request.getAttribute("list"); if (list == null || list.size() < 1) { out.print("没有数据!"); } else { for (Book book : list) { %> <tr align="center"> <td><%=book.getId()%></td> <td><%=book.getName()%></td> <td><%=book.getPrice()%></td> <td><%=book.getBookCount()%></td> <td><%=book.getAuthor()%></td> </tr> <% } } %> <tr align="center"> <td colspan="4">共计<%=list.size()%>本图书 </td> <td><a href="add.jsp">添加图书</a></td> </tr> </table> </body> </html>
index.jsp页面:程序的主页,存放一个导航链接
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>所有图书信息</title> </head> <body> <a href="FindServlet">查看所有图书</a> </body> </html>
修改数据
示例:通过Servlet修改数据库中的图书数量
book_list.jsp页面:增加修改图书数量的表单
<%@page import="java.util.List"%> <%@page import="com.zq.Book"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>所有图书信息</title> <script type="text/javascript"> function check(form) { with (form) { if (bookCount.value == "") { alert("请输入更新数量!"); return false; } if (isNaN(bookCount.value)) { alert("格式错误!"); return false; } return true; ; } } </script> </head> <body> <table align="center" width="450" border="1"> <tr> <td align="center" colspan="6"><h2>所有图书信息</h2></td> </tr> <tr align="center"> <td><b>ID</b></td> <td><b>图书名称</b></td> <td><b>价格</b></td> <td><b>数量</b></td> <td><b>作者</b></td> <td><b>修改数量</b></td> </tr> <% List<Book> list = (List<Book>) request.getAttribute("list"); if (list == null || list.size() < 1) { out.print("没有数据!"); } else { for (Book book : list) { %> <tr align="center"> <td><%=book.getId()%></td> <td><%=book.getName()%></td> <td><%=book.getPrice()%></td> <td><%=book.getBookCount()%></td> <td><%=book.getAuthor()%></td> <td><form action="UpdateServlet" method="post" onsubmit="return check(this);"> <input type="hidden" name="id" value="<%=book.getId()%>"> <input type="text" name="bookCount" size="3"> <input type="submit" value="修 改"> </form></td> </tr> <% } } %> <tr align="center"> <td colspan="5">共计<%=list.size()%>本图书 </td> <td><a href="add.jsp">添加图书</a></td> </tr> </table> </body> </html>
技巧:由于图书id属性并不需要显示在表单中,而在图书信息的修改过程中有需要获取这个值,所以,将id对象文本框<input>中的type属性设置为hidden,使之在表单中构成一个隐藏域,从而实现实际的业务需求。
UpdateServlet类:Servlet类,修改图书信息请求的Servlet对象。
package com.zq; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/UpdateServlet") public class UpdateServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getParameter("id")); System.out.println(request.getParameter("bookCount")); int id = Integer.valueOf(request.getParameter("id")); int bookCount = Integer.valueOf(request.getParameter("bookCount")); try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = ""; Connection conn = DriverManager.getConnection(url, username, password); String sql = "update test set bookCount = ? where id = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, bookCount); ps.setInt(2, id); ps.executeUpdate(); ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } response.sendRedirect("FindServlet"); } }
技巧:HttpServletRequest所接受的参数值为String类型,而图书id与图书数量为int类型,所以需要对其进行转型操作,示例中通过Integer()类的valueOf()方法进行实现。
删除数据
示例:通过Servlet删除数据库表中的数据
book_list.jsp页面:增加删除操作的超链接
<%@page import="java.util.List"%> <%@page import="com.zq.Book"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>所有图书信息</title> <script type="text/javascript"> function check(form) { with (form) { if (bookCount.value == "") { alert("请输入更新数量!"); return false; } if (isNaN(bookCount.value)) { alert("格式错误!"); return false; } return true; ; } } </script> </head> <body> <table align="center" width="450" border="1"> <tr> <td align="center" colspan="7"><h2>所有图书信息</h2></td> </tr> <tr align="center"> <td><b>ID</b></td> <td><b>图书名称</b></td> <td><b>价格</b></td> <td><b>数量</b></td> <td><b>作者</b></td> <td><b>修改数量</b></td> <td><b>操作</b></td> </tr> <% List<Book> list = (List<Book>) request.getAttribute("list"); if (list == null || list.size() < 1) { out.print("没有数据!"); } else { int i = 0; for (Book book : list) { %> <tr align="center"> <td><%=i + 1%><%i++; %></td> <td><%=book.getName()%></td> <td><%=book.getPrice()%></td> <td><%=book.getBookCount()%></td> <td><%=book.getAuthor()%></td> <td><form action="UpdateServlet" method="post" onsubmit="return check(this);"> <input type="hidden" name="id" value="<%=book.getId()%>"> <input type="text" name="bookCount" size="3"> <input type="submit" value="修 改"> </form></td> <td><a href="DeleteServlet?id=<%=book.getId() %>">删除</a></td> </tr> <% } } %> <tr align="center"> <td colspan="6">共计<%=list.size()%>本图书 </td> <td><a href="add.jsp">添加图书</a></td> </tr> </table> </body> </html>
DeleteServlet类:处理删除图书信息的请求
package com.zq; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/DeleteServlet") public class DeleteServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("删除id为" + request.getParameter("id") + "的" + request.getParameter("name") + "书籍"); int id = Integer.valueOf(request.getParameter("id")); try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = ""; Connection conn = DriverManager.getConnection(url, username, password); String sql = "delete from test where id = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, id); ps.executeUpdate(); ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } response.sendRedirect("FindServlet"); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
示例二
示例二建表语句
CREATE TABLE `tb_student_batch` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, `sex` tinyint(1) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
批处理
Batch类:实现对学生信息的批量添加操作
package com.zq; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Random; public class Batch { public Connection getConnection() { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8"; String username = "root"; String password = ""; conn = DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } public int saveBatch() { int row = 0; Connection conn = getConnection(); try { String sql = "insert into tb_student_batch(id,name,sex,age) values(?,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); Random random = new Random(); // 生成随机数 for (int i = 0; i < 10; i++) { ps.setInt(1, i + 1); ps.setString(2, "学生" + i); ps.setBoolean(3, i % 2 == 0 ? true : false); ps.setInt(4, random.nextInt(5) + 10); ps.addBatch();// 添加批处理命令 } int[] rows = ps.executeBatch(); row = rows.length; ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } return row; } }
index.jsp页面:实例化Batch对象,执行批量添加数据操作
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>首页</title> </head> <body> <jsp:useBean id="batch" class="com.zq.Batch"></jsp:useBean> <% int row = batch.saveBatch(); out.print("批量插入了【" + row + "】条数据!"); %> </body> </html>