JDBC操作数据库
1. 添加数据
通过JDBC向数据库添加数据,可以使用INSERT语句实现插入数据SQL语句,对于SQL语句中的参数可以使用占位符“?"代替,然后通过PreparedStatement对其赋值并执行SQL。
例1.1 创建Web项目,然后通过JDBC实现图书信息添加功能。
(1)在MySQL数据库中创建图书信息表books,其结构如下图所示。
(2)创建名称为Book的类,用于封装图书对象信息。关键代码如下:
package com.cn.database; 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; } }
(3)创建index.jsp页面,它是程序中的主页,用于放置添加图书信息所需要的表单,该表单提交到AddBook.jsp页面进行处理。关键代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </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> </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>
(4)创建AddBook.jsp页面,用于对添加图书信息请求进行处理,该页面通过JDBC将所提交的图书信息数据写入数据库中。关键代码如下:
<%@page import="java.sql.PreparedStatement"%> <%@page import="java.sql.DriverManager"%> <%@page import="java.sql.Connection"%> <%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'AddBook.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <%request.setCharacterEncoding("GBK"); %> <jsp:useBean id="book" class="com.cn.database.Book"></jsp:useBean> <jsp:setProperty property="*" name="book"/> <% try{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "1234"); String sql="insert into books(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(); //关闭PrepareStatement,释放资源 conn.close(); }catch(Exception e){ out.print("图书信息添加失败!"); e.printStackTrace(); } %> <br> <a href="index4.jsp">返回</a> </body> </html>
在AddBook.jsp页面中,首先通过<jsp:useBean>实例化JavaBean对象Book,并通过<jsp:setProperty>对Book对象中的属性赋值,在构建了图书对象后通过JDBC将图书信息写入到数据库中。
2. 查询数据
使用JDBC查询数据与添加数据的流程基本相同,但执行查询数据操作后需要通过一个对象来装载查询结果集,这个对象就是ResultSet对象。
例2.1 创建Web项目,通过JDBC查询图书信息表中的图书信息,并将其显示在JSP页面中。
(1)创建名称为Book的类,用于封装图书信息,代码同例1.1。
(2)创建名称为FindServlet的Servlet对象,用于查询所有图书信息。在此Servlet中, 编写doGet()方法,建立数据库连接,并将所查询的数据集合放置到HttpServletRequest对象中,将请求转发到JSP页面。关键代码如下:
package com.cn.gao; 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.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.cn.gao.Book; public class FindServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "1234"); String sql = "select* from books"; Statement sta = conn.createStatement(); ResultSet rs = sta.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); //将所查询的数据集合放置到HttpServletRequest对象中 rs.close(); sta.close(); conn.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } request.getRequestDispatcher("book_list.jsp").forward(request, response); //请求转发到book_list.jsp } }
(3)创建book_list.jsp页面,用于显示所有图书信息。关键代码如下:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GBK"%> <%@ page import="java.util.*" %> <%@ page import="com.cn.gao.*" %> <!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=GB18030"> <title>Insert title here</title> </head> <body> <form action="" method="post"> <table align="center" width="450" border="1"> <tr> <td align="center" colspan="5">所有图书信息</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> <% } } %> </table> </form> </body> </html>
由于FindServlet将查询的所有图书信息集合放置到了request中,所以在book_list.jsp中可以通过request的getAttribute()方法获取到这一集合对象。实例中在获得所有图书信息集合后,通过for循环遍历所有图书信息集合,并将其输出到页面中。
(4) 创建showbook.jsp页面,该页面为程序中的主页,在该页面中编写一个导航链接,用于请求查看所有图书信息。关键代码如下:
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
<title>Insert title here</title>
</head>
<body>
<table widht="450">
<tr>
<td align="center">
<h2><a href="FindServlet">查看所有图书</a></h2>
<td>
</tr>
</table>
</body>
</html>
部署并运行程序后,将打开showbook.jsp页面,单击“查看所有图书”链接后,可以查看到从数据库中查询的所有图书信息。
3. 修改数据
使用JDBC修改数据库中的数据,其操作方法与添加数据相似,只不过修改数据需要使用UPDATE语句实现。
在实际的开发中,通常情况下都是由程序传递SQL语句中的参数,所以修改数据也需要使用PreparedStatement对象进行操作。
例3.1 在查询所有图书信息的页面中,添加修改图书数量的表单,通过Servlet修改数据库中的图书数量。
(1)在book_list.jsp页面中增加修改图书数量的表单,将该表单的提交地址设置为UpdateServlet。关键代码如下:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GBK"%> <%@ page import="java.util.*" %> <%@ page import="com.cn.gao.*" %> <!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=GB18030"> <title>Insert title here</title> </head> <body> <form action="" method="post"> <table align="center" width="450" border="1"> <tr> <td align="center" colspan="6">所有图书信息</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> <% } } %> </table> </form> </body> </html>
在修改图书信息的表单中,主要包含两个属性信息,分别为图书id与图书数量bookCount,因为修改图书数量时需要明确指定图书的id作为修改的条件,否则,将会修改所有图书信息记录。
技巧:由于图书id属性并不需要显示在表单中,而在图书信息的修改过程中又需要获取这个值,所以,将id对应文本框<input>中的type属性设置为hidden,使之在表单中构成一个隐藏于,从而实现实际的业务需求。
(2)创建修改图书信息的Servlet对象,其名称为UpdateServlet。由于表单提交请求类型为post,所以在UpdateServlet中编写doPost()方法,对修改图书信息请求进行处理。关键代码如下:
package com.cn.gao; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UpdateServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id")); int bookCount = Integer.parseInt(request.getParameter("bookCount")); try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "1234"); String sql = "update books set bookCount=? where id=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, bookCount); ps.setInt(2, id); ps.executeUpdate(); ps.close(); conn.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } response.sendRedirect("FindServlet"); //重定向到FindServlet } }
4. 删除数据
例4.1 在查询所有图书信息的页面中,添加删除图书信息的超链接,通过Servlet实现对数据的删除操作。
(1)在book_list.jsp页面中,增加删除图书信息的超链接,将链接地址指向DeleteServlet。关键代码如下:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GBK"%> <%@ page import="java.util.*" %> <%@ page import="com.cn.gao.*" %> <!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=GB18030"> <title>Insert title here</title> </head> <body> <form action="" method="post"> <table align="center" width="600" border="1"> <tr> <td align="center" colspan="7">所有图书信息</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{ //遍历图书集合中的数据 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> <td> <form action="DeleteServlet" method="post" onsubmit="return check(this);"> <input type="hidden" name="id" value="<%=book.getId() %>"> <input type="submit" value="删 除"> </form> </td>
或者:
<td>
<a href="DeleteServerlet?id=<%book.getId()%>>删除</a>
</td>
</tr>
<%
}
}
%>
</table>
</form>
</body>
</html>
在删除数据信息操作中,需要传递所要删除的图书对象,因此,在删除图书信息的超链接中加入图书id值。
技巧:在Java Web开发中,JSP页面中的超链接可以带有参数,器操作方式通过在超链接后加入“?”实现。
(2)编写处理删除图书信息的Servlet,其名称为DeleteServlet。在doPost()(或doGet())方法中,编写删除图书信息的方法。关键代码如下:
package com.cn.gao; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DeleteServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id")); try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "1234"); String sql = "delete from books where id=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, id); ps.executeUpdate(); ps.close(); conn.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } response.sendRedirect("FindServlet"); } }