一:1.最终的实现效果图:
2.案例的目录结构:
3.案例中使用到的jar包:
二:案例的链接数据库的层次结构关系:数据库是:mysql ,数据库名字:dsm,表格名字:customers
数据库表格的样子是:
数据库实现中用到的各个类的层次关系:
上述java类中的源代码:
Dao.java:
package com.guodiantong.mvc.dao;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.guodiantong.mvc.db.JdbcUtils;
public class Dao<T> {
private QueryRunner queryRunner=new QueryRunner();
private Class<T> clazz;
public Dao(){
Type superClass=getClass().getGenericSuperclass();
if(superClass instanceof ParameterizedType){
ParameterizedType parameterizedType= (ParameterizedType) superClass;
Type[] typeArgs=parameterizedType.getActualTypeArguments();
if(typeArgs!=null&&typeArgs.length>0){
if(typeArgs[0] instanceof Class){
clazz=(Class<T>) typeArgs[0];
}
}
}
}
/*
* 这个方法是只获取,表格中的某一行属性中的某一个属性值,就是返回某一个字段的值,例如返回某一条记录的customerName,或者返回数据表中有多少条记录等。
*/
public <E> E getForValue(String sql,Object ... args){
Connection connection=null;
try {connection=JdbcUtils.getConnection();
return (E) queryRunner.query(connection, sql, new ScalarHandler(), args);
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.releaseConnection(connection);
}
return null;
}
/*
* 该方法是返回一组数据对象实体类,返回T所对应的List,其实质就是查询
*/
public List<T> getForList(String sql,Object ... agrs ){
Connection connection=null;
try {connection=JdbcUtils.getConnection();
return queryRunner.query(connection, sql, new BeanListHandler<T>(clazz), agrs);
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.releaseConnection(connection);
}
return null;
}
/*
* 执行查询的语句,结果是返回数据表中的一个对象(一条记录)其实质就是查询!
*/
public T get(String sql,Object ... agrs){
Connection connection=null;
try {connection=JdbcUtils.getConnection();
return queryRunner.query(connection, sql, new BeanHandler<T>(clazz), agrs);
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.releaseConnection(connection);
}
return null;
}
/*
* 该方法封装了INSERT、UPDATE、DELETE操作
* sql是sql语句
* args是占位符
*/
public void update(String sql,Object ... args){
Connection connection=null;
try {connection=JdbcUtils.getConnection();
queryRunner.update(connection, sql, args);
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.releaseConnection(connection);
}
}
}
JdbcUtils.java
package com.guodiantong.mvc.db;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils {
/*
*释放数据库的连接
*
*/
public static void releaseConnection(Connection connection){
try {
if(connection !=null){
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static DataSource dataSource=null;
static {
/*
* 数据源只能被创建一次
*/
dataSource=new ComboPooledDataSource("mvcapp");
}
public static Connection getConnection() throws SQLException{
//dataSource=new ComboPooledDataSource("mvcapp");若要是放在这里就说明,获得一次就创建一下,比较耗费内存
return dataSource.getConnection();
}
}
说明一下这里的 “mvcapp”参数,这个参数是在c3p0-config.xml文件中的一项配置(<named-config name="mvcapp">)
Customer.java:
package com.guodiantong.mvc.domain;
public class Customer {
private Integer id;
private String name;
private String address;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Customer(Integer id, String name, String address, String phone) {
super();
this.id = id;
this.name = name;
this.address = address;
this.phone = phone;
}
public Customer() {
super();
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", address=" + address
+ ", phone=" + phone + "]";
}
}
CustomerDao.java:
package com.guodiantong.mvc.dao;
import java.util.List;
import com.guodiantong.mvc.domain.CriteriaCustomer;
import com.guodiantong.mvc.domain.Customer;
public interface CustomerDao {
public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc);
public List<Customer> getAll();
public void save(Customer customer);
public Customer get(Integer id);
public void delete(Integer id);
/*
* 根据查询的名字,返回使用该名字的数据条数
*/
public long getCountWithName(String name);
public void update(Customer customer);
}
CustomerDaoJdbcImpl.java:
package com.guodiantong.mvc.impl;
import java.util.List;
import com.guodiantong.mvc.dao.CustomerDao;
import com.guodiantong.mvc.dao.Dao;
import com.guodiantong.mvc.domain.CriteriaCustomer;
import com.guodiantong.mvc.domain.Customer;
public class CustomerDaoJdbcImpl extends Dao<Customer>implements CustomerDao {
public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc){
String sql="SELECT id ,name,address,phone FROM customers WHERE "+
"name LIKE ? AND address LIKE ? AND phone LIKE ?";
return getForList(sql, cc.getName(),cc.getAddress(),cc.getPhone());
}
@Override
public List<Customer> getAll() {
String sql="SELECT id,name,address,phone FROM customers";
return getForList(sql);
}
@Override
public void save(Customer customer) {
String sql="INSERT INTO customers(name,address,phone) VALUES(?,?,?)";
update(sql, customer.getName(),customer.getAddress(),customer.getPhone());;
}
@Override
public Customer get(Integer id) {
String sql="SELECT id,name,address,phone FROM customers WHERE id=?";
return get(sql, id);
}
@Override
public void delete(Integer id) {
String sql="DELETE FROM customers WHERE id=?";
update(sql, id);
}
@Override
public long getCountWithName(String name) {
String sql="SELECT count(id) FROM customers WHERE name=?";
return getForValue(sql, name);
}
@Override
public void update(Customer customer) {
String sql="UPDATE customers SET name=?, address=?, phone=? WHERE id=?";
update(sql, customer.getName(),customer.getAddress(),customer.getPhone(),customer.getId());
}
}
说明:Dao.java 和JdbcUtils.java具有可移植性,在哪个工程项目中都能用,CustomerDao.java和CustomerDaoImpl.java 是根据具体的项目抽象出可能用到的方法,然后让底层Dao.java最基础的增删改查等功能来拼凑出项目中页面中抽象的方法
三:项目中jsp文件的编写(jsp实质上就是一个servlet)
案例中用到最多的无非是HttpServletRequest request,HttpServletResponse response这两个参数结合页面中的表单form以及转发方式等在页面和后台servlet之间传递数据
开始页面的jsp:index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.List" %>
<%@ page import="com.guodiantong.mvc.domain.Customer" %>
<!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>
<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(function(){
$(".delete").click(function(){
var content=$(this).parent().parent().find("td:eq(1)").text();
var flag =confirm("确定要删除" + content + "的信息吗?");
return flag;
});
});
</script>
</head>
<body>
<form action="query.do" method="post">
<table>
<tr>
<td>CustomerName:</td>
<td><input type="text" name=name></td>
</tr>
<tr>
<td>Address:</td>
<td><input type="text" name="address"></td>
</tr>
<tr>
<td>Phone:</td>
<td><input type="text" name="phone"></td>
</tr>
<tr>
<td><input type="submit" value="Query"></td>
<td><a href="addCustomer.jsp">Add Customer123</a></td>
</tr>
</table>
</form>
<hr>
<br>
<%
List<Customer> customer=(List<Customer>)request.getAttribute("customers");
if(customer!=null && customer.size()>0){
%>
<table border="1" cellspacing="0" cellpadding="10">
<tr>
<th>id</th>
<th>name</th>
<th>address</th>
<th>phone</th>
<th>delete</th>
<th>edit</th>
</tr>
<%
for(Customer cust:customer)
{
%>
<tr>
<td><%=cust.getId() %></td>
<td><%=cust.getName() %></td>
<td><%=cust.getAddress() %></td>
<td><%=cust.getPhone() %></td>
<td><a class="delete" href="delete.do?id=<%=cust.getId()%>">delete</a></td>
<td><a class="edit" href="edit.do?id=<%=cust.getId() %>">edit</a></td>
</tr>
<%
}
%>
<%
}
%>
</table>
</body>
</html>
新增页面的jsp:addCustomer.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>Insert title here</title>
</head>
<body>
<% Object msg=request.getAttribute("message");
if(msg!=null){
%>
<%=request.getAttribute("message")%>
<%
}
%>
<form action="addCustomer.do" method="post">
<table>
<tr>
<td>customerName:<input type="text" name="name"
value="<%=request.getAttribute("name")==null? "":request.getAttribute("name") %>"></td>
</tr>
<tr>
<td>address:<input type="text" name="address"
value="<%=request.getAttribute("address")==null? "":request.getAttribute("address") %>"></td>
</tr>
<tr>
<td>phone:<input type="text" name="phone"
value="<%=request.getAttribute("phone")==null? "":request.getAttribute("phone") %>"></td>
</tr>
<tr>
<td><input type="submit" value="submit"></td>
</tr>
</table>
</form>
</body>
</html>
编辑页面的jsp:edit.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.guodiantong.mvc.domain.Customer" %>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
Object msg = request.getAttribute("message");
if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br>
<br>
<%
}
String id = null;
String oldName = null;
String name = null;
String address = null;
String phone = null;
Customer customer = (Customer)request.getAttribute("customer");
if(customer != null){
id = customer.getId() + "";
oldName = customer.getName();
name = customer.getName();
address = customer.getAddress();
phone = customer.getPhone();
}else{
id = request.getParameter("id");
oldName = request.getParameter("oldName");
name = request.getParameter("oldName");
address = request.getParameter("address");
phone = request.getParameter("phone");
}
%>
<form action="update.do" method="post">
<input type="hidden" name="id" value="<%= id %>"/>
<input type="hidden" name="oldName" value="<%= oldName %>"/>
<table>
<tr>
<td>CustomerName:</td>
<td><input type="text" name="name"
value="<%= name %>"/></td>
</tr>
<tr>
<td>Address:</td>
<td><input type="text" name="address"
value="<%= address %>"/></td>
</tr>
<tr>
<td>Phone:</td>
<td><input type="text" name="phone"
value="<%= phone %>"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit"/></td>
</tr>
</table>
</form>
</body>
</html>
四.后台中的控制类Servlet CustomerServlet.java
package com.guodiantong.mvc.servlet;
import java.io.IOException;
import java.lang.reflect.Method;
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.guodiantong.mvc.dao.CustomerDao;
import com.guodiantong.mvc.domain.CriteriaCustomer;
import com.guodiantong.mvc.domain.Customer;
import com.guodiantong.mvc.impl.CustomerDaoJdbcImpl;
public class CustomerServlet extends HttpServlet {
CustomerDao customerDao=new CustomerDaoJdbcImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String servletPath=req.getServletPath();
System.out.println(servletPath);
String methodName=servletPath.substring(1);
methodName=methodName.substring(0, methodName.length()-3);
/*
* 利用反射获取methodName对应的方法
*/
try {
Method method=getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
HttpServletResponse.class);
//利用反射调用对应的方法
method.invoke(this, req,resp);
} catch (Exception e) {
e.printStackTrace();
resp.sendRedirect("error.jsp");
}
}
private void query(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
String name=request.getParameter("name");
String address=request.getParameter("address");
String phone=request.getParameter("phone");
CriteriaCustomer criteriaCustomer=new CriteriaCustomer(name, address, phone);
List<Customer> customers=customerDao.getForListWithCriteriaCustomer(criteriaCustomer);
System.out.println(customers);
request.setAttribute("customers", customers);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
private void delete(HttpServletRequest request,HttpServletResponse response) throws IOException{
String idstr=request.getParameter("id");
int id=0;
try {
id=Integer.parseInt(idstr);
System.out.println(id);
customerDao.delete(id);
} catch (Exception e) {
}
response.sendRedirect("query.do");
}
private void addCustomer(HttpServletRequest resquest,HttpServletResponse response) throws IOException, ServletException{
String name=resquest.getParameter("name");
String address=resquest.getParameter("address");
String phone=resquest.getParameter("phone");
//String message="用户" + name + "已经注册过了";
long count=customerDao.getCountWithName(name);
if(count>0){
//resquest.setAttribute("count", count);
resquest.setAttribute("message","用户" + name + "已经注册过了");
resquest.setAttribute("address", address);
resquest.setAttribute("phone", phone);
resquest.getRequestDispatcher("/addCustomer.jsp").forward(resquest, response);
}
else{
Customer customer=new Customer(null, name, address, phone);
customerDao.save(customer);
response.sendRedirect("query.do");}
}
private void edit(HttpServletRequest request,HttpServletResponse response){
String idstr=request.getParameter("id");
int id=0;
try {
id=Integer.parseInt(idstr);
Customer cus=customerDao.get(id);
// String name=cus.getName();
// String address=cus.getAddress();
// String phone=cus.getPhone();
// request.setAttribute("name", name);
// request.setAttribute("address", address);
request.setAttribute("customer", cus);
request.getRequestDispatcher("/edit.jsp").forward(request, response);
} catch (Exception e) {
// TODO: handle exception
}
}
private void update(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
//1. 获取表单参数: id, name, address, phone, oldName
String id = request.getParameter("id");
String name = request.getParameter("name");
String phone = request.getParameter("phone");
String address = request.getParameter("address");
String oldName = request.getParameter("oldName");
//2. 检验 name 是否已经被占用:
//2.1 比较 name 和 oldName 是否相同, 若相同说明 name 可用.
//2.1 若不相同, 则调用 CustomerDAO 的 getCountWithName(String name) 获取 name 在数据库中是否存在
if(!oldName.equalsIgnoreCase(name)){
long count = customerDao.getCountWithName(name);
//2.2 若返回值大于 0, 则响应 updatecustomer.jsp 页面: 通过转发的方式来响应 newcustomer.jsp
if(count > 0){
//2.2.1 在 updatecustomer.jsp 页面显示一个错误消息: 用户名 name 已经被占用, 请重新选择!
//在 request 中放入一个属性 message: 用户名 name 已经被占用, 请重新选择!,
//在页面上通过 request.getAttribute("message") 的方式来显示
request.setAttribute("message", "用户名" + name + "已经被占用, 请重新选择!");
//2.2.2 newcustomer.jsp 的表单值可以回显.
//address, phone 显示提交表单的新的值, 而 name 显示 oldName, 而不是新提交的 name
//2.2.3 结束方法: return
request.getRequestDispatcher("/updatecustomer.jsp").forward(request, response);
return;
}
}
//3. 若验证通过, 则把表单参数封装为一个 Customer 对象 customer
Customer customer = new Customer(null, name, address, phone);
customer.setId(Integer.parseInt(id));
//4. 调用 CustomerDAO 的 update(Customer customer) 执行更新操作
customerDao.update(customer);
//5. 重定向到 query.do
response.sendRedirect("query.do");
}
}