数据库程序常被称为CRUD程序,因为它包括数据的创建Create、读取查询Read、更新Upadate、删除Delete操作,取首字母缩写便是CRUD.CRUD概括了数据库程序结构,程序无论大小,归根到底都是这4种操作。下面通过一个对于人员信息的增删改查来说明:
查询数据库
查询数据库遵循固定的流程:注册MySQL驱动、获得Connection、创建Statement、查询数据库返回ResultSet对象、遍历ResultSet输出数据、关闭ResultSet、关闭Statement、关闭Connection.
插入人员信息
Java程序也可以执行INSERT语句往数据库插入数据,方法是使用Statement对象,执行INSERT语句时要使用executeUpdate(String sql)方法。executeUpdate()方法用于执行INSERT、UPDATE、DELETE等,返回数据库中影响的行数,返回int类型。而executeQuery()方法用于SELECT,返回查询到的结果集,返回ResultSet类型。
注册数据库驱动
代码中注册驱动使用的是显示的注册,直接调用DriverManager的方法注册:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
对于MySQL来说,还可以使用下面的任一种方式:
new com.mysql.jdbc.Driver();
Class.forName("com.mysql.jdbc.Driver").newInstance();
MySQL驱动的构造函数中灰调用DriverManager的注册方法。
删除人员信息
删除数据使用Statement的executeUpdate(String sql)方法执行DELETE语句。与INSERT不同的是,DELETE必须使用WHERE条件指定删除哪一行数据,否则将删除所有数据。对于有主键的表来说,可以使用主键来标识哪一行数据,因为主键值是唯一的,不可重复的。
修改人员数据
修改数据需要先把原来的数据呈现出来,客户做出修改后再保存数据。
使用PreparedStatement
除了使用Statement,还可以使用PreparedStatement.PreparedStatement接口继承自Statement接口,是Statement的子类,因此拥有Satement接口的所有方法。
PreparedStatement与Statement最大的区别是PreparedStatement可以使用参数,也就是(?)号。PreparedStatement允许使用不完整的SQL语句,空缺的部分使用问号(?)代替,直接执行前的时候设置进去.和C#中的String.format(“{0}”,属性)类似。
下面是程序的三个页面listPerson.jsp、operatePerson.jsp、addPerson.jsp代码:
listPerson.jsp:
<%@ page language="java" pageEncoding="UTF-8"
contentType="text/html;charset=UTF-8"%>
<%@ page import="java.sql.DriverManager"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.ResultSet"%>
<jsp:directive.page import="java.sql.Date" />
<jsp:directive.page import="java.sql.Timestamp" />
<jsp:directive.page import="java.sql.SQLException"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'listPerson.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">
<style type="text/css">body, td, th, input {font-size:12px; text-align:center; }</style>
</head>
<body>
<table align=right>
<tr>
<td>
<a href="addPerson.jsp">新建人员资料</a>
</td>
</tr>
</table>
<br />
<br />
<%
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 注册 MySQL 驱动. 也可以使用下面两种方式的任一种
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//new com.mysql.jdbc.Driver();
//Class.forName("com.mysql.jdbc.Driver").newInstance();
// 获取数据库连接。 三个参数分别为 连接URL,用户名,密码
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databaseWeb",
"root",
"admin");
// 获取 Statement。 Statement 对象用于执行 SQL。相当于控制台。
stmt = conn.createStatement();
// 使用 Statement 执行 SELECT 语句。返回结果集。
rs = stmt.executeQuery("select * from tb_person");
%>
<form action="operatePerson.jsp" method=get>
<table bgcolor="#CCCCCC" cellspacing=1 cellpadding=5 width=100%>
<tr bgcolor=#DDDDDD>
<th></th>
<th>
ID
</th>
<th>
姓名
</th>
<th>
英文名
</th>
<th>
性别
</th>
<th>
年龄
</th>
<th>
生日
</th>
<th>
备注
</th>
<th>
记录创建时间
</th>
<th>
操作
</th>
</tr>
<%
// 遍历结果集。rs.next() 返回结果集中是否还有下一条记录。如果有,自动滚动到下一条记录并返回 true
while (rs.next()) {
int id = rs.getInt("id"); // 整形类型
int age = rs.getInt("age");
String name = rs.getString("name"); // 字符串类型
String englishName = rs.getString("english_name");
String sex = rs.getString("sex");
String description = rs.getString("description");
Date birthday = rs.getDate("birthday"); // 日期类型,只有日期信息而没有时间信息
Timestamp createTime = rs.getTimestamp("create_time"); // 时间戳类型,既有日期又有时间。
out.println(" <tr bgcolor=#FFFFFF>");
out.println(" <td><input type=checkbox name=id value=" + id
+ "></td>");
out.println(" <td>" + id + "</td>");
out.println(" <td>" + name + "</td>");
out.println(" <td>" + englishName + "</td>");
out.println(" <td>" + sex + "</td>");
out.println(" <td>" + age + "</td>");
out.println(" <td>" + birthday + "</td>");
out.println(" <td>" + description + "</td>");
out.println(" <td>" + createTime + "</td>");
out.println(" <td>");
out.println(" <a href='operatePerson.jsp?action=del&id="
+ id + "' onclick='return confirm(\"确定删除该记录?\")'>删除</a>");
out.println(" <a href='operatePerson.jsp?action=edit&id="
+ id + "'>修改</a>");
out.println(" </td>");
out.println(" </tr>");
}
%>
</table>
<table align=left>
<tr>
<td>
<input type='hidden' value='del' name='action'>
<a href='#'
onclick="var array=document.getElementsByName('id');for(var i=0; i<array.length;
i++){array[i].checked=true;}">全选</a>
<a href='#'
onclick="var array=document.getElementsByName('id');for(var i=0; i<array.length;
i++){array[i].checked=false;}">取消全选</a>
<input type='submit'
onclick="return confirm('即将删除所选择的记录。是否删除?'); " value='删除'>
</td>
</tr>
</table>
</form>
<%
}catch(SQLException e){
out.println("发生了异常:" + e.getMessage());
e.printStackTrace();
}finally{
// 关闭
if(rs != null)
rs.close();
if(stmt != null)
stmt.close();
if(conn != null)
conn.close();
}
%>
</body>
</html>
operatePerson.jsp:
<%@ page language="java" pageEncoding="UTF-8"
contentType="text/html;charset=UTF-8"%>
<%@ page import="java.sql.DriverManager"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.Statement"%>
<jsp:directive.page import="java.sql.ResultSet" />
<jsp:directive.page import="java.sql.SQLException" />
<jsp:directive.page import="java.sql.PreparedStatement"/>
<jsp:directive.page import="java.text.SimpleDateFormat"/>
<jsp:directive.page import="java.sql.Timestamp"/>
<jsp:directive.page import="java.sql.Date"/>
<%!
/** SQL 值中的单引号(')需要转化为 \' */
public String forSQL(String sql){
return sql.replace("'", "\\'");
}
%>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String englishName = request.getParameter("englishName");
String age = request.getParameter("age");
String birthday = request.getParameter("birthday");
String sex = request.getParameter("sex");
String description = request.getParameter("description");
String action = request.getParameter("action");
if("add".equals(action)){
// INSERT SQL 语句
String sql = "INSERT INTO tb_person " +
" ( name, english_name, " +
" age, sex, birthday, " +
" description ) values " +
" ( '" + forSQL(name) + "', '" + forSQL(englishName) + "', " +
" '" + age + "', '" + sex + "', '" + birthday + "', " +
" '" + forSQL(description) + "' ) " ;
Connection conn = null;
Statement stmt = null;
int result = 0;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databaseWeb?characterEncoding=UTF-8",
"root",
"admin");
stmt = conn.createStatement();
// 使用 Statement 执行 SQL 语句
result = stmt.executeUpdate(sql);
}catch(SQLException e){
out.println("执行SQL\"" + sql + "\"时发生异常:" + e.getMessage());
return;
}finally{
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
out.println("<html><style>body{font-size:12px; line-height:25px; }</style><body>");
out.println(result + " 条记录被添加到数据库中。");
out.println("<a href='listPerson.jsp'>返回人员列表</a>");
// 将执行的 SQL 语句输出到客户端
out.println("<br/><br/>执行的 SQL 语句为:<br/>" + sql);
return;
}
else if("del".equals(action)){
// 取一个或者多个 ID 值
String[] id = request.getParameterValues("id");
if(id == null || id.length == 0){ out.println("没有选中任何行"); return; }
String condition = "";
for(int i=0; i<id.length; i++){
if(i == 0) condition = "" + id[i];
else condition += ", " + id[i];
}
String sql = "DELETE FROM tb_person WHERE id IN (" + condition + ") ";
Connection conn = null;
Statement stmt = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databaseWeb?characterEncoding=UTF-8",
"root",
"admin");
stmt = conn.createStatement();
// 使用 Statement 执行 SQL 语句
int result = stmt.executeUpdate(sql);
out.println("<html><style>body{font-size:12px; line-height:25px; }</style><body>");
out.println(result + " 条记录被删除。");
out.println("<a href='listPerson.jsp'>返回人员列表</a>");
// 将执行的 SQL 语句输出到客户端
out.println("<br/><br/>执行的 SQL 语句为:<br/>" + sql);
}catch(SQLException e){
out.println("执行SQL\"" + sql + "\"时发生异常:" + e.getMessage());
e.printStackTrace();
}finally{
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
}
else if("edit".equals(action)){
String id = request.getParameter("id");
String sql = "SELECT * FROM tb_person WHERE id = " + id;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databaseWeb?characterEncoding=UTF-8",
"root",
"admin");
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
if(rs.next()){
// 有记录 将响应字段从数据库中取出 保存到 request 中,显示到 修改页面
request.setAttribute("id", rs.getString("id"));
request.setAttribute("name", rs.getString("name"));
request.setAttribute("englishName", rs.getString("english_name"));
request.setAttribute("age", rs.getString("age"));
request.setAttribute("sex", rs.getString("sex"));
request.setAttribute("birthday", rs.getString("birthday"));
request.setAttribute("description", rs.getString("description"));
request.setAttribute("action", action);
// 转到修改页面
request.getRequestDispatcher("/addPerson.jsp").forward(request, response);
}
else{
// 没有数据
out.println("没有找到 id 为 " + id + " 的记录。");
}
}catch(SQLException e){
out.println("执行SQL\"" + sql + "\"时发生异常:" + e.getMessage());
e.printStackTrace();
}finally{
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
}
else if("save".equals(action)){
String id = request.getParameter("id");
String sql = "UPDATE tb_person SET " +
" name = '" + forSQL(name) + "', " +
" english_name = '" + forSQL(englishName) + "', " +
" sex = '" + sex + "', " +
" age = '" + age + "', " +
" birthday = '" + birthday + "', " +
" description = '" + forSQL(description) + "' " +
" WHERE id = " + id;
Connection conn = null;
Statement stmt = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databaseWeb?characterEncoding=UTF-8",
"root",
"admin");
stmt = conn.createStatement();
// 使用 Statement 执行 SQL 语句
int result = stmt.executeUpdate(sql);
out.println("<html><style>body{font-size:12px; line-height:25px; }</style><body>");
if(result == 0) out.println("影响数目为 0, 修改失败. ");
else out.println(result + " 条记录被修改。");
out.println("<a href='listPerson.jsp'>返回人员列表</a>");
// 将执行的 SQL 语句输出到客户端
out.println("<br/><br/>执行的 SQL 语句为:<br/>" + sql);
}catch(SQLException e){
out.println("执行SQL\"" + sql + "\"时发生异常:" + e.getMessage());
e.printStackTrace();
}finally{
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
}
else{
String id = request.getParameter("id");
String sql = "UPDATE tb_person SET name = ?, english_name = ?, sex = ?, age = ?, birthday = ?, description = ? WHERE id = ? ";
Connection conn = null;
PreparedStatement preStmt = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databaseWeb?characterEncoding=UTF-8",
"root",
"admin");
preStmt = conn.prepareStatement(sql);
preStmt.setString(1, name);
preStmt.setString(2, englishName);
preStmt.setString(3, sex);
preStmt.setInt(4, Integer.parseInt(age));
preStmt.setDate(5, new Date(new SimpleDateFormat("yyyy-MM-dd").parse(birthday).getTime()));
preStmt.setString(6, description);
preStmt.setInt(7, Integer.parseInt(id));
// 使用 preStmt 执行 SQL 语句
int result = preStmt.executeUpdate(sql);
out.println("<html><style>body{font-size:12px; line-height:25px; }</style><body>");
if(result == 0) out.println("影响数目为 0, 修改失败. ");
else out.println(result + " 条记录被修改。");
out.println("<a href='listPerson.jsp'>返回人员列表</a>");
// 将执行的 SQL 语句输出到客户端
out.println("<br/><br/>执行的 SQL 语句为:<br/>" + sql);
}catch(SQLException e){
out.println("执行SQL\"" + sql + "\"时发生异常:" + e.getMessage());
e.printStackTrace();
}finally{
if(preStmt != null) preStmt.close();
if(conn != null) conn.close();
}
}
%>
addPerson.jsp:
<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
// 注意是取 request 参数而不是地址栏参数,因此用 getAttribute 方法而不是 getParameter
String action = (String)request.getAttribute("action");
String id = (String)request.getAttribute("id");
String name = (String)request.getAttribute("name");
String englishName = (String)request.getAttribute("englishName");
String age = (String)request.getAttribute("age");
String sex = (String)request.getAttribute("sex");
String birthday = (String)request.getAttribute("birthday");
String description = (String)request.getAttribute("description");
// 是 添加页面 还是 修改页面,下文中根据此变量做相应的处理
boolean isEdit = "edit".equals(action);
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%= isEdit ? "修改人员资料" : "新建人员资料" %></title>
<style type="text/css">body, td{font-size:12px; }</style>
</head>
<body>
<script type="text/javascript" src="js/calendar.js"></script>
<form action="operatePerson.jsp" method="post">
<input type="hidden" name="action" value="<%= isEdit ? "save" : "add" %>">
<input type="hidden" name="id" value="<%= isEdit ? id : "" %>">
<fieldset>
<legend><%= isEdit ? "修改人员资料" : "新建人员资料" %></legend>
<table align=center>
<tr>
<td>姓名</td>
<td><input type="text" name="name" value="<%= isEdit ? name : "" %>"/></td>
</tr>
<tr>
<td>英文名</td>
<td><input type="text" name="englishName" value="<%= isEdit ? englishName : "" %>"/></td>
</tr>
<tr>
<td>性别</td>
<td>
<input type="radio" name="sex" value="男" id="sex_male" <%= isEdit&&"男".equals(sex) ? "checked" : "" %> /><label for="sex_male">男</label>
<input type="radio" name="sex" value="女" id="sex_female" <%= isEdit&&"女".equals(sex) ? "checked" : "" %>/><label for="sex_female">女</label>
</td>
</tr>
<tr>
<td>年龄</td>
<td><input type="text" name="age" value="<%= isEdit ? age : "" %>" /></td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" onfocus="setday(birthday)" value="<%= isEdit ? birthday : "" %>"/>
<img src="images/calendar.gif" onclick="setday(birthday);" />
</td>
</tr>
<tr>
<td>描述</td>
<td><textarea name="description" ><%= isEdit ? description : "" %></textarea></td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="<%= isEdit ? "保存" : "添加人员信息" %>"/>
<input type="button" value="返回" onclick="history.go(-1); " />
</td>
</tr>
</table>
</fieldset>
</form>
</body>
</html>