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" οnsubmit="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"
οnsubmit="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"
οnsubmit="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>