需求分析:
通過數據庫連接池,可以查詢到數據庫中員工的各種信息,通過點擊下拉框的方式實現三級聯動,即:沒有點擊city下拉框,后面兩個下拉框中沒有值,這樣,點擊city下拉框,department下拉框中才有值,點擊department下拉框后employee下拉框中才有值,才可以進行選擇,不可以跨級點擊;點擊最后一個下拉框可以將員工的id,last_name,email,salary,顯示在下面的表格中;
實現上述功能的方法:
1.c3p0數據庫連接池,實現數據庫的鏈接;JdbcUtils類,連接數據庫,代碼更加簡潔;
2.Jackson架包,簡化JSON代碼,使用其類,方法;ObjectMapper mapper=new ObjectMapper();String result=mapper.writeValueAsString(employee);其可以獲取類中get方法名,並且獲取其值;
3.使用了jstl標准標簽庫,jQuery,不用在jsp中插入代碼
4.使用到了Ajax:不需要刷新頁面,就可實現局部頁面更新的技術;其方法:$.getJSON(url,args,function(data){}向指定的jsp頁面中插入標簽;
5.使用blockUI,使用時要插入jQuery插件jquery.blockUI.js,每次點擊下拉框都出現正在刷新的假象,其實就是一張靜態的圖片
----------------------------------------------------------------------------------------------
先將一些架包導進去:
連接c3p0數據連接池的架包:c3p0-0.9.1.2.jar;
實現oracle數據庫和Eclipse軟件跨平台連接的包:ojdbc6.jar
實現數據庫連接池方法的包:commons-dbutils-1.3.jar
Jackson架包,簡化JSON代碼:jackson-core-asl-1.9.11.jar,jackson-mapper-asl-1.9.11.jar
jstl標准標簽庫相關的包:jstl.jar,standard.jar
jQuery架包,放在WebContent/scripts:jquery-1.7.2.js,jQuery插件:jquery.blockUI.js
----------------------------------------------------------------------------------------------
連接c3p0數據庫連接池,成功后,獲取oracle數據中的三張表:分別是:employees,departments,locations;兩兩之間有相同的列,可以實現內連接;
三個封裝表中部分信息的類:employee,department,location;
package com.lanqiao.javaweb.jdbc; public class Employee { private Integer employeeId; private String lastName; private String email; private double salary; public Employee() { super(); // TODO Auto-generated constructor stub } public Employee(Integer employeeId, String lastName, String email, double salary) { super(); this.employeeId = employeeId; this.lastName = lastName; this.email = email; this.salary = salary; } public Integer getEmployeeId() { return employeeId; } public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } @Override public String toString() { return "Employee [employeeId=" + employeeId + ", lastName=" + lastName + ", email=" + email + ", salary=" + salary + "]"; } }
package com.lanqiao.javaweb.jdbc; public class Department { private Integer departmentId; private String departmentName; public Department() { super(); // TODO Auto-generated constructor stub } public Department(Integer departmentId, String departmentName) { super(); this.departmentId = departmentId; this.departmentName = departmentName; } public Integer getDepartmentId() { return departmentId; } public void setDepartmentId(Integer departmentId) { this.departmentId = departmentId; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } @Override public String toString() { return "Department [departmentId=" + departmentId + ", departmentName=" + departmentName + "]"; } }
package com.lanqiao.javaweb.jdbc; public class Location { private Integer locationId; private String city; public Location() { super(); // TODO Auto-generated constructor stub } public Location(Integer locationId, String city) { super(); this.locationId = locationId; this.city = city; } public Integer getLocationId() { return locationId; } public void setLocationId(Integer locationId) { this.locationId = locationId; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "Location [locationId=" + locationId + ", city=" + city + "]"; } }
在src目錄下建立c3p0-config.xml文件,配置和映射連接數據庫的屬性;
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <named-config name="mvcapp"> <!-- 指定連接數據源的基本屬性 --> <property name="user">oraclejava</property> <property name="password">lxn123</property> <property name="driverClass">oracle.jdbc.driver.OracleDriver</property> <property name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:orcl1</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>
建立JdbcUtils類:利用JdbcUtils包中的方法,簡便的實現數據庫連接池的連接
package com.lanqiao.javaweb.jdbc; import java.sql.Connection; import java.sql.SQLException; import org.junit.Test; import com.mchange.v2.c3p0.ComboPooledDataSource; //c3p0數據庫連接池的方法類 public class JdbcUtils { //釋放數據庫連接的方法 public static void releaseConnection(Connection connection){ try { if(connection!=null){ connection.close(); } } catch (Exception e) { e.printStackTrace(); } } //連接數據庫的方法 public static ComboPooledDataSource dataSource=null; static{ dataSource=new ComboPooledDataSource("mvcapp"); } //獲取數據庫的鏈接,返回connection對象 public static Connection getConnection() throws Exception{ return dataSource.getConnection(); } @Test //測試數據庫連接池是否連接成功 public void testTT() throws Exception{ System.out.println(getConnection()); } //類的私有構造方法 private JdbcUtils() {} //此方法,是本類的調用方法,可以調用本類的各個方法 private static JdbcUtils instance=new JdbcUtils(); public static JdbcUtils getInstanece(){ return instance; } }
建立BaseDAO類,其中有查詢數據庫中數據的方法;
package com.lanqiao.javaweb.jdbc; import java.sql.Connection; import java.util.List; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; public class BaseDAO { //此類是 對數據庫的增傷改查的一些方法,調用的是QueryRunner類中的一些方法,實現對數據庫中數據的增傷改查 private static final QueryRunner runner=new QueryRunner(); //返回所對應的list集合,獲得的是數據庫中所有數據的集合 public <T> List<T> getForList(String sql,Class<T> clazz,Object...args) throws Exception{ //Object...args,為可變參數 //Class<T> clazz,反射參數 List<T> list=null; Connection conn=null; try { conn=JdbcUtils.getConnection(); list=runner.query(conn, sql, new BeanListHandler<T>(clazz),args); } catch (Exception e) { e.printStackTrace(); }finally { //DbUtils是,架包commons-dbutils-1.3.jar里面的類, //方法closeQuietly為該類的方法,實現了關閉數據庫連接池 DbUtils.closeQuietly(conn); } return list; } //此方法是傳入一個sql語句進入,返回某一個對象 public <T> T get(String sql,Class<T> clazz,Object...args){ T result=null; Connection conn=null; try { conn=JdbcUtils.getConnection(); result=runner.query(conn, sql, new BeanHandler<T>(clazz),args); } catch (Exception e) { }finally { DbUtils.closeQuietly(conn); } return result; } }
------------------------------------------------------------------------------------------
數據庫連接池,連接的方法,查詢方法等前期准備工作完成了;然后是servlet類的建立和jsp頁面的處理工作;
建立一個點擊觸發的jsp頁面:employee.jsp(比較簡單);
<%response.sendRedirect("employeeServlet?method=listLocation");%>
web.xml文件中的配置和映射;是servlet類:EmployeeServlet與兩個jsp頁面實現連接;
<?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>Ajax-1</display-name> <servlet> <description></description> <display-name>EmployeeServlet</display-name> <servlet-name>EmployeeServlet</servlet-name> <servlet-class>com.lanqiao.javaweb.jdbc.EmployeeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>EmployeeServlet</servlet-name> <url-pattern>/employeeServlet</url-pattern> </servlet-mapping> </web-app>
建立servlet類:EmployeeServlet,及employees.jsp頁面,實現三級聯動的功能;
package com.lanqiao.javaweb.jdbc; 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 org.codehaus.jackson.map.ObjectMapper; public class EmployeeServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取method的值 String methodName=request.getParameter("method"); try { //利用反射獲取本類中method=?,的方法名, Method method= getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); method.invoke(this, request, response); } catch (Exception e) { e.printStackTrace(); } } //調用 BaseDAO類,其中有查詢員工信息的方法 private static BaseDAO baseDao=new BaseDAO(); //通過locations查詢員工id,所在城市 protected void listLocation (HttpServletRequest request, HttpServletResponse response) throws Exception{ String sql="select location_id locationId,city from locations"; //調用BaseDAO的getForList方法,查詢所有的值 List<Location> locations=baseDao.getForList(sql, Location.class); request.setAttribute("locations", locations); request.getRequestDispatcher("/employees.jsp").forward(request, response); } protected void listDepartments(HttpServletRequest request, HttpServletResponse response) throws Exception{ String locationId=request.getParameter("locationId"); String sql="select department_id departmentId,department_name departmentName " + "from departments d where d.location_id=?"; List<Department> departments= baseDao.getForList(sql, Department.class, Integer.parseInt(locationId)); //Jackson架包,簡化JSON代碼,使用其類,方法;ObjectMapper mapper=new ObjectMapper(); //String result=mapper.writeValueAsString(employee);其可以獲取類中get方法名,並且獲取其值; ObjectMapper mapper=new ObjectMapper(); String result=mapper.writeValueAsString(departments); //System.out.println(result); //text/javascript重定向到jsp頁面的類型 response.setContentType("text/javascript"); response.getWriter().print(result); } // protected void listEmployees(HttpServletRequest request, HttpServletResponse response) throws Exception{ String departmentId=request.getParameter("departmentId"); String sql="select employee_id employeeId,last_name lastName " + "from employees e where e.department_id=?"; List<Employee> employees= baseDao.getForList(sql, Employee.class, Integer.parseInt(departmentId)); ObjectMapper mapper=new ObjectMapper(); String result=mapper.writeValueAsString(employees); response.setContentType("text/javascript"); response.getWriter().print(result); } //通過employeeId 查看某個員工的信息 protected void listMessage(HttpServletRequest request, HttpServletResponse response) throws Exception{ String employeeId=request.getParameter("employeeId"); String sql="select employee_id employeeId,last_name lastName,email,salary " + "from employees where employee_id=?"; List<Employee> employee= baseDao.getForList(sql, Employee.class, Integer.parseInt(employeeId)); ObjectMapper mapper=new ObjectMapper(); String result=mapper.writeValueAsString(employee); //System.out.println(result); response.setContentType("text/javascript"); response.getWriter().print(result); } }
employees.jsp頁面
<%@page import="com.lanqiao.javaweb.jdbc.Location"%> <%@ 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="${pageContext.request.contextPath }/scripts/jquery-1.7.2.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath }/scripts/jquery.blockUI.js"></script> <script type="text/javascript"> $(function(){ //剛開始隱藏查詢的table $("#emp").hide(); //使用blockUI,使用時要插入jQuery插件jquery.blockUI.js //每次點擊下拉框都出現正在刷新的假象,其實就是一張靜態的圖片 $(document).ajaxStart(function(){ $.blockUI({ message: $('#loading'), css:{ top:($(window).height()-400)/2+'px', lift:($(window).width()-400)/2+'px', width:'400px', border:'none' }, overlayCSS:{backgroundColor:'#fff'} }) }).ajaxStop($.unblockUI); //第一個下拉框, $("#city").change(function(){ $("#department option:not(:first)").remove(); var city=$(this).val(); if(city != ""){ var url="employeeServlet?method=listDepartments"; var args={"locationId":city,"time":new Date()}; $.getJSON(url,args,function(data){ if(data.length==0){ alert("當前城市沒有部門!!!"); } else{ for(var i=0;i<data.length;i++){ var deptId=data[i].departmentId; var deptName=data[i].departmentName; $("#department").append("<option value='"+deptId+"'>"+deptName+"</option>"); } } }); } }); //第二個下拉框 $("#department").change(function(){ $("#employee option:not(:first)").remove(); var departmentName=$(this).val(); if(departmentName !=""){ var url="employeeServlet?method=listEmployees"; var args={"departmentId":departmentName,"time":new Date()}; $.getJSON(url,args,function(data){ if(data.length==0){ alert("當前部門沒有員工!!!"); } else{ for(var i=0;i<data.length;i++){ var employeeId=data[i].employeeId; var employeeName=data[i].lastName; //alert("dd"); $("#employee").append("<option value='"+employeeId+"'>"+employeeName+"</option>"); } } }); } }); //第三個下拉框 $("#employee").change(function(){ $("#emp").show(); var employeeName=$(this).val(); if(employeeName!=""){ var url="employeeServlet?method=listMessage"; var args={"employeeId":employeeName,"time":new Date()}; $.getJSON(url,args,function(data){ if(data.length==0){ alert("此員工無信息無信息!!!"); } else{ for(var i=0;i<data.length;i++){ var employeeId=data[i].employeeId; var lastName=data[i].lastName; var email=data[i].email; var salary=data[i].salary; //alert(email); $("#id").append("<td>"+employeeId+"</td>"); $("#name").append("<td>"+lastName+"</td>"); $("#email").append("<td>"+email+"</td>"); $("#salary").append("<td>"+salary+"</td>"); } } }); } }); }); </script> </head> <body> <img alt="" id="loading" src="images/1.jpg" style="display:none"> <center> <br><br> City: <select id="city"> <option value="">請選擇...</option> <c:forEach items="${locations }" var="location"> <option value="${location.locationId }">${location.city }</option> </c:forEach> </select> Department: <select id="department"> <option value="">請選擇...</option> </select> Employee: <select id="employee"> <option value="">請選擇...</option> </select> <br><br> <br><br> <table id="emp" width="350" border="1" cellpadding="5" cellspacing="0" > <tr> <th>Id</th> <th>Name</th> <th>Email</th> <th>Salary</th> </tr> <td id="id"></td> <td id="name"></td> <td id="email"></td> <td id="salary"></td> </table> </center> </body> </html>