*.數據庫連接池c3p0,連接mysql數據庫;
*.Jquery使用,刪除時跳出框,確定是否要刪除;
*.使用EL和JSTL,簡化在jsp頁面中插入的java語言
1.連接數據庫
(1)導入連接數據庫連接池的開源架包和EL和JSTL的架包(在lib目錄下導入)
c3p0-0.9.1.2jar
commons-dbutils-1.3jar
mysql-connector-java-5.1jar
jstl.jar
standard.jar
(2)在src目錄下建立一個c3p0-config.xml文件,存放數據庫連接池的變量:
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <named-config name="mvcapp"> <!-- 指定連接數據源的基本屬性 --> <property name="user">root</property> <property name="password">lxn123</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql:///test</property> <!-- 若數據庫中連接數不足時, 一次向數據庫服務器申請多少個連接 --> <property name="acquireIncrement">5</property> <!-- 初始化數據庫連接池時連接的數量 --> <property name="initialPoolSize">10</property> <!-- 數據庫連接池中的最小的數據庫連接數 --> <property name="minPoolSize">10</property> <!-- 數據庫連接池中的最大的數據庫連接數 --> <property name="maxPoolSize">50</property> <!-- C3P0 數據庫連接池可以維護的 Statement 的個數 --> <property name="maxStatements">20</property> <!-- 每個連接同時可以使用的 Statement 對象的個數 --> <property name="maxStatementsPerConnection">5</property> </named-config> </c3p0-config>
(2)連接數據庫連接池的類:JdbcUtils
package com.lanqiao.javatest; import java.sql.Connection; import java.sql.SQLException; import org.junit.Test; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JdbcUtils { //實現數據庫連接池的方法類 //該靜態代碼塊只執行一次 private static ComboPooledDataSource dataSource=null; static{ dataSource=new ComboPooledDataSource("mvcapp"); } public static Connection getConnection() throws SQLException{ return dataSource.getConnection(); } @Test //測試數據庫連接池是否連接成功 public void testT() throws SQLException{ System.out.println(getConnection()); } //釋放connection連接 public static void releaseConnection(Connection connection){ try { if(connection!=null){ connection.close(); } } catch (Exception e) { e.printStackTrace(); } } }
2.建立customer類,對數據庫中的屬性進行封裝;
package com.lanqiao.javatest; public class Customer { private Integer id; private String name; private String address; private String phone; public Customer() { super(); // TODO Auto-generated constructor stub } public Customer(String name, String address, String phone) { this.name = name; this.address = address; 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 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; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", address=" + address + ", phone=" + phone + "]"; } }
3.建立CriteriaCustomer類,對數據庫中的部分數據進行封裝,便於模糊查詢使用
package com.lanqiao.javatest; //模糊查詢的類 public class CriteriaCustomer { private String name; private String address; private String phone; public CriteriaCustomer() { super(); } public CriteriaCustomer(String name, String address, String phone) { super(); this.name = name; this.address = address; this.phone = phone; } public String getName() { if (name==null) { name="%%"; } else{ name="%"+name+"%"; } return name; } public void setName(String name) { this.name = name; } public String getAddress() { if (address==null) { address="%%"; } else{ address="%"+address+"%"; } return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { if (phone==null) { phone="%%"; } else{ phone="%"+phone+"%"; } return phone; } public void setPhone(String phone) { this.phone = phone; } }
4.在src目錄下建立一個接口類:CustomerDAO,對一些方法進行了封裝;
package com.lanqiao.javatest; import java.util.List; //創建以CustomerDAO接口,可以實現其他類的調用 public interface CustomerDAO { //模糊查詢方法 public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc); //查詢的方法,將數據庫的所有數據放在list集合中,並實現輸出的查詢 public List<Customer> getAll(); // public void save(Customer customer); //通過jsp超鏈接里面?后面的id,獲取該id下的各屬性的值 public Customer get(Integer id); //通過jsp超鏈接里面?后面的id,並且實現刪除的功能 public void delete(Integer id); //返回和該name相等的個數 public long getCountWithName(String name); void update(Customer customer); }
5.建一個DAO類,有得到某一個類方法明的反射方法,實現對數據的增刪改查的方法
package com.lanqiao.javatest; 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; /* * 封裝了基本的增刪改查方法,以供子類繼承使用; * 當前dao沒有事務,直接在方法中獲取數據庫的鏈接 * */ public class DAO <T>{ //這個是線程安全的 private QueryRunner queryRunner=new QueryRunner(); private Class<T> clazz; //類的構造方法 public DAO() { //得到父類帶泛型的類型 //type類型導包為import java.lang.reflect.Type;反射類型里面的 //反射。。。。。。Type所有超級類接口,ParameterizedType表示參數化類型,參數化類型在反射方法首次需要時創建(在此包中指定)。 //當創建參數化類型 p 時,p 實例化的一般類型聲明會被解析,並且按遞歸方式創建 p 的所有類型參數。 Type superClass=getClass().getGenericSuperclass(); if (superClass instanceof ParameterizedType) { ParameterizedType parameterizedType=(ParameterizedType) superClass; // getActualTypeArguments():返回表示此類型實際類型參數的 Type 對象的數組。 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; } //返回所對應的list集合,獲得的是一組的 public List<T> getForList(String sql,Object...args){ Connection connection=null; try { connection=JdbcUtils.getConnection(); return queryRunner.query(connection,sql,new BeanListHandler<>(clazz),args); } catch (Exception e) { e.printStackTrace(); }finally { JdbcUtils.releaseConnection(connection); } return null; } //返回對應的T的一個實體類的對象 public T get(String sql,Object...args){ Connection connection=null; try { connection=JdbcUtils.getConnection(); return queryRunner.query(connection,sql,new BeanHandler<>(clazz),args); } catch (Exception e) { e.printStackTrace(); }finally { JdbcUtils.releaseConnection(connection); } return null; } //該方法封裝了增刪改操作 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); } } }
6.建立一個類:CustomerDAOJdbcImpl 繼承於父類 DAO<Customer> 和繼承於接口 CustomerDAO,增刪改查方法和模糊查詢的方法;
package com.lanqiao.javatest; import java.util.List; import com.lanqiao.javatest.CriteriaCustomer; import com.lanqiao.javatest.CustomerDAO; import com.lanqiao.javatest.DAO; //實現各個功能的類 public class CustomerDAOJdbcImpl extends DAO<Customer> implements CustomerDAO{ @Override //模糊查詢的方法 public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) { String sql="select id,name,address,phone from customer " + "where name like ? and address like ? and phone like ?"; //修改了CriteriaCustomer的get方法,使其返回的字符串中含有%% return getForList(sql,cc.getName(),cc.getAddress(),cc.getPhone()); } @Override //獲取整個數據庫中的所有數據 public List<Customer> getAll() { String sql1="select id,name,address,phone from customer"; return getForList(sql1); } @Override //插入數據到數據庫的方法 public void save(Customer customer) { String sql2="insert into customer(name,address,phone) values(?,?,?)"; update(sql2, customer.getName(),customer.getAddress(),customer.getPhone()); } @Override //獲取某個數據 public Customer get(Integer id) { String sql3="select id,name,address,phone from customer where id=?"; return get(sql3,id); } @Override //刪除id=?的數據 public void delete(Integer id) { String sql4="delete from customer where id=?"; update(sql4, id); } @Override //用名字獲取count(name),即獲取用戶的數量 public long getCountWithName(String name) { String sql5="select count(name) from customer where name=?"; return getForValue(sql5, name); } @Override public void update(Customer customer) { String sql = "UPDATE customer SET name = ?, address = ?, phone = ? " + "WHERE id = ?"; update(sql, customer.getName(), customer.getAddress(), customer.getPhone(), customer.getId()); } }
7.建立一個Servlet類:doGet和doPost方法;
package com.lanqiao.javatest1; import java.io.IOException; import java.lang.reflect.Method; import java.util.List; import javax.management.Query; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lanqiao.javatest.CriteriaCustomer; import com.lanqiao.javatest.Customer; import com.lanqiao.javatest.CustomerDAO; import com.lanqiao.javatest.CustomerDAOJdbcImpl; public class CustomerServlet extends HttpServlet { private static final long serialVersionUID = 1L; private CustomerDAO customerDAO=new CustomerDAOJdbcImpl(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //利用反射,接受多個以.do結尾的請求 //1.變量 servletPath獲取所有后邊帶.do的方法名和.do ,例如這個/pass.do String servletPath=request.getServletPath(); //2.在字符串后面除去.do這個字符 String methodName=servletPath.substring(1); methodName=methodName.substring(0,methodName.length()-3); //System.out.println(methodName); try { //反射獲取該類的該方法 Method method=getClass().getDeclaredMethod (methodName, HttpServletRequest.class,HttpServletResponse.class); //這里面的this指通過這個方法的到方法名字,並且輸出,及this指methodName的到的方法名字 method.invoke(this,request,response); } catch (Exception e) { //如果出現錯誤,去error頁面 response.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 cc=new CriteriaCustomer(name,address,phone); //1.調用CustomerDAO的getForListWithCriteriaCustomer(cc)方法得到lists的集合 List<Customer> lists=customerDAO.getForListWithCriteriaCustomer(cc); //2.把list集合放到request中 request.setAttribute("list", lists); //3.轉發頁面到index.jsp(不能使用重定向) /代表的是根目錄下的jsp文件; request.getRequestDispatcher("/index.jsp").forward(request, response); } //插入數據的方法: private void addCustomer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ //1.獲取表單參數,name,address,phone String name=request.getParameter("name"); String address=request.getParameter("address"); String phone=request.getParameter("phone"); //檢驗名字是否已經被占用了:調用CustomerDAO的getCountWithName方法,獲取name參數是否大於0,如果大於.... //並且消息可以回顯:value="<%=request.getParameter("name")==null ? "" :%>" long count=customerDAO.getCountWithName(name); if (count>0) { request.setAttribute("message","用戶名"+name+"已經被占用了,請重新選擇!!!"); //名字重復了,請求的轉發到/newcustomer.jsp request.getRequestDispatcher("/newcustomer.jsp").forward(request, response); //結束方法 return ; } //2.若驗證通過的話,把表單參數封裝為一個customer的對象 Customer customer=new Customer(name,address,phone); //3.調用CustomerDAO的save方法執行保存 customerDAO.save(customer); //數據插入成功后,請求的轉發到newcustomer.jsp //request.getRequestDispatcher("/newcustomer.jsp").forward(request, response); //4.數據插入成功后,重定向到success.jsp頁面:使用重定向可以避免出現表單的重復提交問題. response.sendRedirect("success.jsp"); } private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException { //1.獲取請求的id String idStr=request.getParameter("id"); int id=0; try { id=Integer.parseInt(idStr); //2.調用CustomerDAO的getId()方法執行刪除 customerDAO.delete(id); } catch (Exception e) { response.sendRedirect("query.do"); } //重定向的頁面jsp,其前面不用加"/" response.sendRedirect("success.jsp"); } //修改數據表里的數據 private void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //出現了所查詢的數據不存在的錯誤顯示到error.jsp頁面 String forwardPath="/error.jsp"; //1.獲取請求的id String idStr=request.getParameter("id"); //2. 調用 CustomerDAO 的 customerDAO.get(id) 獲取和 id 對應的 Customer 對象 customer try { Customer customer=customerDAO.get(Integer.parseInt(idStr)); //如果數據存在的跳轉到updatecustomer.jsp頁面,進行修改數據 if(customer!=null){ forwardPath="/updatecustomer.jsp"; //將數據放到request請求的轉發的里面 request.setAttribute("customer", customer); } } catch (Exception e) { System.out.println("fsdlkf"); } //4. 響應 updatecustomer.jsp 頁面: 轉發. request.getRequestDispatcher(forwardPath).forward(request, response); } 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 address=request.getParameter("address"); String phone=request.getParameter("phone"); 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(name,address,phone); customer.setId(Integer.parseInt(id)); //4. 調用 CustomerDAO 的 update(Customer customer) 執行更新操作 customerDAO.update(customer); //5. 重定向到 query.do response.sendRedirect("query.do"); } }
8.在WEB-INF下的web.xml文件;
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>day-11</display-name> <servlet> <description></description> <display-name>CustomerServlet1</display-name> <servlet-name>CustomerServlet1</servlet-name> <servlet-class>com.lanqiao.javatest1.CustomerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CustomerServlet1</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
9.幾個jsp頁面;
(1)index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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="scripts/jquery-1.7.2.js"></script> <script type="text/javascript"> $(function(){ $(".delete12").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>Name:</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="newcustomer.jsp">Add New Customer</a></td> </tr> </table> </form> <br><br> <c:if test="${!empty requestScope.list }"> <hr> <br><br> <table border="1" cellpadding="10" cellspacing="0"> <tr> <th>id</th> <th>name</th> <th>address</th> <th>phone</th> <th>update</th> <th>delete</th> </tr> <c:forEach items="${requestScope.list }" var="cust"> <tr> <td>${cust.id }</td> <td>${cust.name }</td> <td>${cust.address }</td> <td>${cust.phone }</td> <td> <c:url value="/edit.do" var="editurl"> <c:param name="id" value="${cust.id }"></c:param> </c:url> <a href="${editurl }">UPDATE</a> <td/> <c:url value="/delete.do" var="deleteurl"> <c:param name="id" value="${cust.id }"></c:param> </c:url> <a href="${deleteurl }" class="delete12">DELETE</a> </tr> </c:forEach> </table> </c:if> </body> </html>
(2)newcustomer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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> <c:if test="${requestScope.message != null }"> <br> <font color="red">${requestScope.message }</font> <br> <br> </c:if> <form action="addCustomer.do" method="post"> <table> <tr> <td>Name:</td> <td><input type="text" name="name" value="${param.name }"/></td> </tr> <tr> <td>Address:</td> <td><input type="text" name="address" value="${param.address }"/></td> </tr> <tr> <td>Phone:</td> <td><input type="text" name="phone" value="${param.phone }"/></td> </tr> <tr> <td colspan="2"><input type="submit" value="Submit"/></td> </tr> </table> </form> </body> </html>
(3)updatecustomer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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> <c:if test="${requestScope.message != null }"> <br> <font color="red">${requestScope.message }</font> <br> <br> </c:if> <c:set var="id" value="${customer != null ? customer.id : param.id }"></c:set> <c:set var="oldName" value="${customer != null ? customer.name : param.oldName }"></c:set> <c:set var="name" value="${customer != null ? customer.name : param.oldName }"></c:set> <c:set var="address" value="${customer != null ? customer.address : param.address }"></c:set> <c:set var="phone" value="${customer != null ? customer.phone : param.phone }"></c:set> <form action="update.do" method="post"> <input type="hidden" name="id" value="${id }"/> <input type="hidden" name="oldName" value="${oldName }"/> <table> <tr> <td>Name:</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>
(4)success.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>
<h2>操作成功!!!</h2>
<a href="index.jsp">Return....</a>
</body>
</html>
(5)error.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>
<h3>不好意思頁面無法打開!!!</h3>
</body>
</html>