Java Web 入門項目 | 二手車交易平臺(保姆級指導)

一、需求分析

本項目實現的功能是一個網上二手車交易平臺,主要圍繞二手車的交易進行開發。
在該系統,分爲兩個角色,一個是普通用戶角色,即會員,另一個角色是管理員用戶,兩個角色分別有不同的權限。具體如下:
普通用戶(會員):

  1. 註冊、登錄
  2. 個人信息的查詢
  3. 個人信息及密碼修改
  4. 二手車的添加、修改、發佈、刪除
  5. 查詢並維護自己的出售信息並支持留言、同時支持對其他人的留言進行回覆
  6. 查看平臺所有二手車信息並進行留言
  7. 支持禁止他人對自己發佈的車輛留言

管理員用戶:

  1. 登錄
  2. 個人信息及密碼的修改
  3. 車輛管理:能查看平臺所有車輛,並進行留言操作、屏蔽操作
  4. 會員管理:支持修改、刪除會員的信息
  5. 查詢所有會員信息(支持模糊查詢)
  6. 可取消會員資格(使之可正常登錄但無法瀏覽網站信息)

二、使用的技術

本系統是基於 MVC 模式搭建的,使用的技術包括

Servlet
JSP
JDBC
EL 表達式
JSTL
Filter 過濾器

三、系統的結構層次

本系統的代碼結構邏輯清晰,具體的實現分爲Web層(表示層)、業務層、數據訪問層,利用MVC架構將JSP、Servlet、JavaBean分層操作並聯系起來,形成一種弱耦合關係,在後期對系統的維護上少了很多麻煩,例如要增加一個功能,只需在Servlet進行邏輯的控制,並調用Service業務服務層的代碼,業務層就去調用數據訪問層的具體邏輯實現,完成對數據庫項的增加操作,實現數據的持久化,在Servlet控制層裏,只需完成2件事,一件是調用業務邏輯層的實現方法,另一件事是將相關屬性放在request中,並轉發給其他JSP頁面去做顯示或輸入處理。代碼邏輯條理十分清晰,具體的代碼結構如下:
在這裏插入圖片描述在這裏插入圖片描述
不同層次的實現放在不同的 package 中,將代碼模塊化,方便維護。
其中:

com.bean:主要放實體類
com.controller:主要放Servlet
com.dao:主要放接口
com.daoImpl:主要放接口的實現類
com.filter:主要放filter過濾器
com.service:主要是業務邏輯的實現
com.utils:主要放工具類(對數據庫的連接和資源釋放)

MVC 模式的邏輯圖如下:
MVC模式邏輯圖
其中,JSP頁面即MVC模式中的V(view),Servlet爲MVC中的C(Controller),然後Service、Dao、MySql組成MVC中的M(model),每個層次每個模塊的功能如下:
1. JSP:
(1)呈現數據:從request中獲取Servlet放入的屬性
(2)接收用戶的輸入
(3)編寫前端頁面顯示代碼給出對於的提示,參與用戶交互

2. Servlet:
(1)獲取請求信息:獲取請求參數
(2)驗證請求參數的合法性:驗證失敗需要返回頁面,並給出提示
(3)把請求參數封裝爲一個JavaBean
(4)調用業務邏輯方法獲取返回的結果
(5)把返回的結果放入request中
(6)響應頁面:轉發、重定向

3. Service:
(1)實現業務邏輯
(2)返回結果

4. Dao:
(1)執行增刪改查操作(CRUD)
(2)返回結果

5. MySql:
(1)存儲數據,對數據進行持久化操作

四、系統部分功能和邏輯分析

1. MySQL 數據庫

該系統包含兩個數據表,一個是 user 表,一個是 car 表。它們分別包含的屬性如下
(1)user表

id:用戶 id 號(主鍵)
name:用戶登錄名稱
pwd:用戶登錄密碼
limit:該用戶的受限情況(int)
isadmin:該用戶是否是管理員(int)

(2)car表

userid:用戶 id 號(主鍵,同時是 user 表的 userid 屬性的外鍵)
carid:二手車 id 號
brand:車輛品牌
model:車輛型號
price:車輛價格
color:車輛顏色
dateposted:發佈日期(timestamp)
isrelease:發佈狀態(int)
canmessage:是否支持用戶留言(int)
carcomment:留言板(text)
isfake:是否是虛假消息(該屬性的操作屬於管理員權限)(int)

2. Servlet 控制器部分

其中控制器,即 MVC 模式中的 C(Controller),我通過使用通配符,對Servlet進行配置,然後在doGet()方法利用反射機制分辨從JSP傳過來的請求,並映射到相應的Servlet中。通過使用這一方法,可以將同一類型的Servlet放在一個.java文件中,不需要每個servlet寫一個java文件進行配置。
在這裏插入圖片描述
其中
CarServlet 配置爲:@WebServlet(".car")
UserServlet配置爲:@WebServlet("
.do")

通過.do或.car將車輛管理和用戶管理這兩個業務分離開,這樣處理業務就變得非常方便,這一做法,可以讓在編碼過程中思路邏輯變得更加的清晰。而且採取上面所說的結構,在編碼過程中遇到報錯能更快的定位到bug,並進行更正。

3. JSP 視圖部分

系統採取的JSP顯示界面也進行了分類管理(結構如下圖),使編程思路更加清晰。
在這裏插入圖片描述
這裏關鍵的一點是登錄頁面,即首頁,要放在WebContent下面,不能放在WEB-INF下面,因爲WEB-INF屬於保護目錄,不能直接被訪問,本項目的登錄頁面 login.jsp 放在 WebContent 下,並在 web.xml 配置爲首頁,如下圖所示:
在這裏插入圖片描述
如果需要訪問 WEB-INF 下的 jsp 文件,需要通過servlet轉發,才能實現訪問操作。這同時也能保證系統的安全性,保證用戶權限得到有效的管理。

同時爲保證系統代碼結構各個層次各司其職,在JSP頁面沒有多餘的Java代碼,業務邏輯執行操作都在其他層次完成。

本系統在界面的顯示上,雖然沒有加入太多的樣式使界面更加高級,但基本保證了界面的可讀性和用戶交互性。

4. Filter過濾器

Filter是一個實現了Filter接口的Java類,與Servlet相似,它由Servlet容器進行調用和執行,Filter需要在web.xml文件中進行註冊和設置它所能攔截的資源。在註冊之後,該Filter就可以對Servlet容器發送給Servlet程序的請求Servlet程序回送給Servlet容器的響應進行攔截,可以決定是否將請求繼續傳遞給Servlet程序,以及對請求和響應信息是否進行修改。
該系統利用了Filter過濾器對Servlet容器調用Servlet的過程進行攔截,進行編碼的轉換,從而在Servlet進行響應處理的前後保證了編碼的統一,統一爲utf-8格式,如下圖:
在這裏插入圖片描述
同時需要在web.xml進行配置,如下圖:
在這裏插入圖片描述

5. EL表達式 和JSTL

在JSP頁面獲取request中的數據時並沒有出現JAVA代碼,而是採用EL表達式獲取值,實現0 Java代碼。讓JSP頁面的功能更加純粹。利用點訪問符訪問對象的屬性。
本系統採用JSTL與EL表達式結合使用,其中JSTL需要導入相應的jar包,並在JSP頁面導入標籤庫

<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>

本系統使用到的主要有 c:if、c:foreach 標籤。

6. 弱耦合邏輯結構關聯方式

其中的層層調用,除了類對象調用方法實現層層調用外,還有就是通過轉發將數據放在request域內,在jsp頁面可以通過requestScope去取到數據,在Servlet也可以接收jsp頁面傳過來的數據,通過request.getParameter( )可以獲取。

7. 接口設計

該系統還有一個比較好的一點就是在對業務邏輯進行處理時,利用接口,然後再在接口的實現類進行操作。面向接口編程可以增加複用性和通用性。
在這裏插入圖片描述

其中
Dao和DaoImpl分別是通用接口和通用接口的實現類,
CarDao和CarDaoImpl是二手車車輛管理的接口和實現類
UserDao和UserDaoImpl是用戶管理(包括管理員及普通用戶)的接口和實現類

爲了使接口更具通用性,這裏採用了“泛型”,代碼如下圖:
在這裏插入圖片描述

8. 數據庫操作和JDBC

使用JDBC可以直接訪問數據庫,JDBC是一個獨立於特定數據庫管理系統、通用的SQL數據庫存取和操作的公共接口(一組API),定義了用來訪問數據庫的標準Java類庫,使用這個類庫可以以一種標準的方法、方便地訪問數據庫資源。JDBC爲訪問不同的數據庫提供了一種統一的途徑,方便開發(本系統採用的是MySql數據庫)。
JDBC API 是一系列的接口,使應用程序能夠進行數據庫連接,執行SQL語句,並且得到返回結果。

基本的流程是:
(1)在Driver Manager中註冊
(2)獲取連接(Connection)
(3)調用相應的方法做增刪改查
(4)獲取處理結果數據

下面對這幾個基本過程進行解析:
<1>註冊
調用Class類的靜態方法forName(),向其傳遞要加載的JDBC驅動的類名,代碼如下:

String driverClass="com.mysql.cj.jdbc.Driver";
Class.forName(driverClass);

<2>建立連接
調用DriverManager類的getConnection()方法建立到數據庫的連接。JDBC URL標識一個被註冊的驅動程序,從而建立到數據庫的連接。通俗來說,就是JDBC URL說明要連接數據庫管理系統中的哪個數據庫。代碼如下:

String jdbcUrl="jdbc:mysql://localhost:3306/SecondCarTrade?serverTimezone=Hongkong";
Connection connection=DriverManager.getConnection(jdbcUrl, user, password);

<3>調用方法實現數據庫永久化操作
調用數據庫有3種方式,分別爲:

Statement
PreparedStatement
CallableStatement

該系統使用的是PreparedStatement。
因爲考慮到如果使用Statement的話,獲取sql語句是通過字符串拼接的方式,所以就必須得考慮到它的拼寫規則,並且得時刻注意不能和關鍵字和特殊字符進行衝突,這對編碼來說不方便,且容易出錯。
而PreparedStatement優勢就比較凸顯,使用PreparedStatement可以進行預編譯,提高性能,同時還可以防止SQL注入,對sql語句也不需要進行字符串拼接,直接寫sql語句就可以調用執行方法操作數據庫。對於語句中的屬性值,可以通過“?”作爲佔位符,可以傳入參數。
以添加用戶來舉例,參數傳遞過來user對象,在方法內部獲取user對象的所需的相應屬性,通過問號佔位符填入sql語句,然後調用update方法操作數據庫,代碼結構如下:
在這裏插入圖片描述

<4>獲取返回數據
將對數據庫操作的結果通過List或者ResultSet的方式返回,以“獲取所有用戶所有車輛”方法舉例,代碼如下:
在這裏插入圖片描述

五、代碼解析和功能演示

下面對具體的邏輯結構和具體實現代碼進行解析,JSP頁面的顯示代碼就不一一演示了,具體查看源代碼去看就行了,註釋都寫得很清晰。
首先從登錄頁面 login.jsp 啓動,登錄時會根據用戶類型和賬號密碼進行身份驗證:

//登錄
	public void LoginUserServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//得到jsp頁面傳過來的參數
				//(因爲在同個request域中,所以可以用request獲取其數據)
				String name=request.getParameter("name");
				String pwd=request.getParameter("pwd");
				int userType=Integer.parseInt(request.getParameter("userType"));// 會員0 /管理員1
				
				
				System.out.println("userType="+userType);
				/*這裏id不能直接request.getParameter獲取,因爲在用戶登錄的時候沒有填id,所以jsp頁面沒有傳"id"信息過來,這裏獲取不到的*/
				int id=service.LoginFindId(name, pwd);//根據name和pwd查找id
				UserDao ud =new UserDaoImpl();//創建接口的實現類,ud對象可以操作UserDaoImpl類內容
				System.out.println("id="+id);	
				
				//service.LimitUser(id)執行成功,返回true,則該用戶變爲受限
				//service.isLimit(id)返回true,則該用戶變爲受限
				//userType==0  會員
				if(service.login(name, pwd) && (!service.isLimit(id)) && (userType==0) && !service.isAdmin(id)) {//如果登錄通過,並且不受限
					//request.setAttribute("xiaoxi", "welcom "+name);//向request域中放置信息
					System.out.println("(會員)登錄成功");
					String message="個人會員 登錄成功";
					
					//注:個人用戶登錄成功,將他的id放在request域中,在jsp頁面可以獲取,然後通過jsp可以再把該id信息轉到其他servlet中(比如下面的SearchUserSelfById() )
					request.setAttribute("id", id);//設置id到request域,在每個個人用戶登錄後分別顯示他個人的信息(通過這個id去獲取)
					request.setAttribute("message", message);
					//轉發到個人用戶主頁UserHomePage.jsp
					request.getRequestDispatcher("/WEB-INF/user/UserHomePage.jsp").forward(request, response);//轉發到成功頁面
				}
				//userType==1  管理員
				else if(service.login(name, pwd) && (!service.isLimit(id)) && (userType==1) && service.isAdmin(id)) {//如果登錄通過,並且不受限
					//request.setAttribute("xiaoxi", "welcom "+name);//向request域中放置信息
					System.out.println("(管理員)登錄成功");
					String message="管理員登錄成功";
					request.setAttribute("message", message);
					request.getRequestDispatcher("/WEB-INF/admin/AdminHomePage.jsp").forward(request, response);//轉發到成功頁面
				}
				//個人用戶(受限用戶)
				else if(service.login(name, pwd) && service.isLimit(id) && (userType==0) && !service.isAdmin(id)){//登錄成功,但受限
					System.out.println("登錄成功,但您的會員資格受限,無法訪問汽車信息");
					String message="登錄成功,但您的會員資格受限,無法訪問汽車信息";
					request.setAttribute("ERRMESSAGE", message);
					request.getRequestDispatcher("/WEB-INF/admin/LimitedUser.jsp").forward(request, response);//轉發到成功頁面
				
				}
				//共用
				else {//登錄不通過,重定向到失敗界面(respnse 響應)
					System.out.println("登錄失敗,請確認賬號密碼以及身份是否正確");
					String message="登錄失敗,請確認賬號密碼以及身份是否正確";
					request.setAttribute("message", message);
					//response.sendRedirect("/WEB-INF/view/Fail.jsp"); 重定向不在一個request裏面
					request.getRequestDispatcher("/WEB-INF/view/LoginFail.jsp").forward(request, response);//轉發到失敗頁面
				}
	}

登錄成功會跳轉到個人用戶主頁,如下圖:
個人用戶主頁
下面演示”顯示個人信息“:

	/*根據個人id查詢個人信息(個人用戶)*/
	public void SearchUserSelfById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		int id=Integer.parseInt(request.getParameter("id"));//從jsp頁面傳過來,用getParameter

		request.setAttribute("id", id);//把id放在request域中,然後在ShowUserInfoSelf可以獲取到,顯示用
		User user=service.getUser(id);
		
		/*轉發提交到request,到相應jsp頁面顯示*/
		request.setAttribute("user", user);	/*將取出來的user對象保存在request域裏面*/
		
		String message="個人信息查詢成功";
		request.setAttribute("message", message);
		request.getRequestDispatcher("/WEB-INF/user/ShowUserInfoSelf.jsp").forward(request, response);
		
	}

在這裏插入圖片描述
我們可以對個人信息進行更新:

	//個人用戶修改信息觸發界面(跳轉到修改的界面)
	public void editUserSelfInfo(HttpServletRequest request, HttpServletResponse response) throws Exception {
		int id=Integer.parseInt(request.getParameter("id"));
		User user=service.getUser(id);
		
		/*轉發提交到request,到相應jsp頁面顯示*/
		request.setAttribute("user", user);	/*將取出來的user對象保存在request域裏面*/
		request.getRequestDispatcher("/WEB-INF/update/UpdateUserInfoSelf.jsp").forward(request, response);//轉發到jsp頁面顯示
	}

在這裏插入圖片描述
修改完成後提交,完成數據庫持久化操作,如下:

	//個人用戶信息修改成功後回到這裏
	public void UpdateUserInfoSelfServlet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		/*獲取從 Update.jsp 頁面輸入的信息(用戶修改後的信息)*/
		System.out.println("進入 UpdateUserInfoSelfServlet ");
		int id=Integer.parseInt(request.getParameter("id"));//從jsp頁面傳過來,用getParameter
		
		String name=request.getParameter("name");
		String pwd=request.getParameter("pwd");
		String sex=request.getParameter("sex");
		System.out.println("name="+name+"  pwd="+pwd+"  sex="+sex);
	
		User user=new User(id,name,pwd,sex,0,0);//User類必須有個帶參構造方法(因爲這是在個人信息修改的方法裏,所以直接把limit和isAdmin默認0)
		service.UpdateUserServlet(user);//Userservice的同名方法
		System.out.println("update successfully");
		String message="個人信息修改成功";
		request.setAttribute("message", message);
		
		//修改成功回到顯示個人信息的界面
		request.setAttribute("user",user);//傳回ShowUserInfoSelf.jsp,不然那邊無法顯示更新後的信息
		request.getRequestDispatcher("/WEB-INF/user/ShowUserInfoSelf.jsp").forward(request, response);
		
	}

下面進行”二手車管理首頁“進行二手車的相關操作:

	//二手車輛管理首頁
	public void CarsManageHomePageServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		List<Car> cars=new ArrayList<Car>();
		int userid=Integer.parseInt(request.getParameter("userid"));//這裏是userid,不是id
		
		User user = serviceOfUser.getUser(userid);//根據jsp傳過來的用戶id,定位到用戶
		cars=serviceOfCar.getCarsListOfUserid(userid);//根據userid獲取到
		//String message="-------二手車管理首頁---------";
		request.setAttribute("user", user);//放在request,到CarsManageHomePage.jsp可以取出來用
		request.setAttribute("cars", cars);
		request.setAttribute("userid", userid);//單獨傳userid過去,因爲CarsManageHomePageServlet不僅連接user,又連接對car的一系列操作
		//request.setAttribute("message", message);
		request.getRequestDispatcher("/WEB-INF/car/CarsManageHomePage.jsp").forward(request, response);
		
	}

來到了二手車管理首頁
在這裏插入圖片描述
下面一一進行演示
添加二手車:

	//添加車輛 觸發界面(編輯界面)
	public void AddCarPageServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		/*實現*/
		int userid=Integer.parseInt(request.getParameter("userid"));//通過 " ?userid " 傳過來了
		System.out.println("AddCarServlet()---userid="+userid);
	
		User user = serviceOfUser.getUser(userid);//根據jsp傳過來的用戶id,定位到用戶
		
		

		/*轉發*/
		String message="添加車輛頁面";		
		request.setAttribute("user", user);//user放在這個request裏
		/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
		request.setAttribute("message", message);
		request.getRequestDispatcher("/WEB-INF/add/AddCarPage.jsp").forward(request, response);

	}

在AddCarPage.jsp頁面進行車輛信息的添加後,來到AddCarServlet

//添加車輛
	//獲取添加界面的信息
	public void AddCarServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		/*實現*/
		int userid=Integer.parseInt(request.getParameter("userid"));//userid:jsp頁面作爲?參數傳過來的
		String brand=request.getParameter("brand");
		String model=request.getParameter("model");
		String price=request.getParameter("price");
		String color=request.getParameter("color");
		String carcomment=request.getParameter("carcomment");
		
		
		//默認設置的屬性,這些直接寫null(注意,id這些整型屬性在Car類要定義成Integer,不能是int)
		Car car = new Car(userid,null,brand,model,price,color,null,null,null,carcomment,null);
		boolean result=serviceOfCar.AddCarServlet(car);
		
		/*轉發*/
		if(result) {//成功添加
			String message="添加車輛成功";		
			/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
			request.setAttribute("car",car);//記得setAttribute過去成功頁面,不然那邊獲取不到
			request.setAttribute("message", message);
			request.getRequestDispatcher("/WEB-INF/car/SuccessOfCar.jsp").forward(request, response);
		}
		else {	//添加失敗
			String message="添加車輛失敗";
			request.setAttribute("message", message);
			request.getRequestDispatcher("/WEB-INF/car/FailOfCar.jsp").forward(request, response);
		
		}
		
	}

顯示我的二手車倉庫:

	//顯示我當前所有的車輛(本地倉庫)
	public void ShowAllLocalCarSelfServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		/*實現*/
		int userid=Integer.parseInt(request.getParameter("userid"));	
		List<Car> cars=new ArrayList<Car>();
		cars=serviceOfCar.getCarsListOfUserid(userid);//根據userid獲取到當前車主所有車輛
		
		/*轉發*/
		String message="顯示我當前所有的車輛 界面";		
		/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
		request.setAttribute("message", message);
		request.setAttribute("cars", cars);
		request.setAttribute("userid", userid);//!!
		request.getRequestDispatcher("/WEB-INF/user/ShowAllLocalCarSelf.jsp").forward(request, response);
	
	}

在這裏插入圖片描述
可以對自己的二手車進行修改、發佈、刪除、留言回覆以及禁止其他用戶留言的操作
下面直接貼出這個操作涉及的相關Servlet的代碼:

修改信息:

	//修改車輛信息(編輯界面)
	public void EditCarServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		/*實現*/
		System.out.println("進入EditCarServlet");
		//定位到用戶
		int userid=Integer.parseInt(request.getParameter("userid"));
		User user=serviceOfUser.getUser(userid);//這裏不用new User,因爲service.getUser()方法中有了。
		System.out.println("userid="+userid);
		//定位到車輛
		int carid=Integer.parseInt(request.getParameter("carid"));
		Car car = serviceOfCar.getCarOfCarid(carid);
		System.out.println("carid="+carid);

		if(car.getIsrelease()==0) {//未發佈,可進行修改
			/*轉發*/
			String message="進入修改界面";		
			/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
			
			request.setAttribute("message", message);
			request.setAttribute("car", car);//to UpdateCarSelf.jsp
			request.getRequestDispatcher("/WEB-INF/update/UpdateCarSelf.jsp").forward(request, response);
		}
		else {
			System.out.println("該車輛已發佈,不可修改");
			String message="該車輛已發佈,不可修改";
			request.setAttribute("message", message);
			
			/*//這裏直接轉到這個servlet比較好,如果轉到FailOfCar的話,還要在request域放參數,才能正常跳轉到首頁,
			 * 還不如這裏直接轉過去,但是這樣缺少交互
			 * 所以還是轉到jsp -> servlet -> 首頁 
			 * 
				ShowAllLocalCarSelfServlet(request,response);
			*/		
			
			request.setAttribute("car", car);
			request.getRequestDispatcher("/WEB-INF/update/UpdateCarFail.jsp").forward(request, response);
			
		}
	}

在修改界面完成修改並且提交之後,來到UpdateCarSelfServlet調用方法進行數據庫的持久化操作

//更新車輛信息(實現)
	public void UpdateCarSelfServlet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		
		/*實現*/
		//userid和carid是通過這句傳過來的 " <form action="... .car?userid=${requestScope.car.userid}&carid=${requestScope.car.carid}" ...> "
		int userid=Integer.parseInt(request.getParameter("userid"));
		int carid=Integer.parseInt(request.getParameter("carid"));
		System.out.println("carid="+carid);
		System.out.println("userid="+userid);
		
		String brand=request.getParameter("brand");
		String model=request.getParameter("model");
		String price=request.getParameter("price");
		String color=request.getParameter("color");
		String carcomment=request.getParameter("carcomment");
		
		
		//報錯,注意這裏的carid的位置不能寫null,因爲寫null,就不知道更新哪一輛車了
		Car car = new Car(userid,carid,brand,model,price,color,null,null,null,carcomment,null);
		
		serviceOfCar.UpdateCarSelfServlet(car);//同名方法
		System.out.println("車輛信息修改成功");
		
		System.out.println("ShowAllLocalCarSelfServlet------userid="+userid);
		
		//List<Car> cars=new ArrayList<Car>();
		//cars=serviceOfCar.getCarsListOfUserid(userid);//根據userid獲取到當前車主所有車輛
		
		//根據carid獲取到要更新那樣車的car信息
		//car=serviceOfCar.getCarOfCarid(carid);
		
		System.out.println("根據carid="+carid+" 更新該車信息成功");
		
		/*轉發*/
		String message="車輛信息修改成功";
		request.setAttribute("message", message);
		
		//ShowAllLocalCarSelf.jsp顯示需要,所以這裏要再用userid獲取一次該車主所有信息(放到request域中)
		List<Car> cars=new ArrayList<Car>();
		cars=serviceOfCar.getCarsListOfUserid(userid);
		request.setAttribute("cars", cars);//本地倉庫那邊要根據這裏穿過去的userid判斷是誰的倉庫,然後顯示用戶自己的本地倉庫
		request.setAttribute("userid", userid);//!!
		request.getRequestDispatcher("/WEB-INF/user/ShowAllLocalCarSelf.jsp").forward(request, response);
	}

發佈車輛::

//發佈該車輛
	//發佈成功,到ShowAllLocalCarSelf可以看到"發佈狀態"的屬性更新
	//對已發佈的汽車點擊"發佈"按鈕,會跳到失敗界面併發message,然後可點擊跳回顯示主頁
	public void ReleaseCarServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		/*實現*/
		int carid=Integer.parseInt(request.getParameter("carid"));	
		
		int isrelease=Integer.parseInt(request.getParameter("isrelease"));
		
		int userid=Integer.parseInt(request.getParameter("userid"));
		
		
		if(isrelease==0) {//未發佈
			serviceOfCar.ReleaseCarServlet(carid);
			System.out.println("車輛發佈成功");
			
			/*轉發*/
			//String message="message:車輛發佈成功";		
			/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
			//request.setAttribute("message", message);
			request.setAttribute("userid", userid);
			
			ShowAllLocalCarSelfServlet(request,response);//再次顯示(最新)頁面(需要傳userid過去)
		}
		else {
			request.setAttribute("userid", userid);
			String message="車輛已發佈,請勿重複發佈";
			request.setAttribute("message", message);
			request.getRequestDispatcher("/WEB-INF/car/ReleaseCarFail.jsp").forward(request, response);
			
		}
	}

刪除車輛:

	//刪除該車輛
	//根據carid刪除車輛信息
	public void DeleteCarServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		/*實現*/
		int carid=Integer.parseInt(request.getParameter("carid"));
		//int userid=Integer.parseInt(request.getParameter("userid"));
		serviceOfCar.DeleteCarServlet(carid);//調用方法實現刪除
		ShowAllLocalCarSelfServlet(request,response);//再次顯示(最新)頁面
		
	}

留言回覆:

//對留言進行回覆(個人用戶)
	public void RespondCommentServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		/*實現*/
		int carid=Integer.parseInt(request.getParameter("carid"));
		int userid=Integer.parseInt(request.getParameter("userid"));
		String carcomment=request.getParameter("carcomment");	
		int canmessage=Integer.parseInt(request.getParameter("canmessage"));
		
		//留言權限設置
		if(canmessage==0) {//可留言:0
			/*轉發*/
			String message="留言板";		
			/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
			request.setAttribute("message", message);
			//request.setAttribute("carid", carid);

			
			if(request.getParameter("respondid")!=null) {
				int respondid=Integer.parseInt(request.getParameter("respondid"));
				request.setAttribute("respondid", respondid);//對“是哪個用戶”留言進行標註
			}
			
			//User user=serviceOfUser.getUser(userid);//獲取到當前是哪個登錄用戶
			
			//這裏必須setAttribute(car),不然無法做留言的回顯
			//需要把userid傳過去,不然在留言板的“只讀”顯示那裏沒辦法顯示userid出來
			Car car = new Car(userid,carid,null,null,null,null,null,null,canmessage,carcomment,null);
			request.setAttribute("car", car);
			
			request.getRequestDispatcher("/WEB-INF/car/RespondComment.jsp").forward(request, response);
		}
		else {//canmessage爲1則不可留言
			String message="該車輛已被車主禁止留言";
			request.setAttribute("message", message);
			Car car = new Car(userid,carid,null,null,null,null,null,null,canmessage,carcomment,null);
			request.setAttribute("car", car);
			request.getRequestDispatcher("/WEB-INF/car/RespondFail.jsp").forward(request, response);
		}
	}
	





//把留言更新到數據庫中(個人用戶)
	public void AddResondComment(HttpServletRequest request, HttpServletResponse response) throws Exception {
		/*實現*/
		int carid=Integer.parseInt(request.getParameter("carid"));
		int userid=Integer.parseInt(request.getParameter("userid"));
		String carcomment=request.getParameter("carcomment");
		

		int respondid=Integer.parseInt(request.getParameter("respondid"));
		request.setAttribute("respondid", respondid);//對“是哪個用戶”留言進行標註
	
		
		/*
		//不需要更新的屬性寫null即可
		Car car = new Car(null,carid,null,null,null,null,null,null,null,carcomment);
		serviceOfCar.UpdateCarSelfServlet(car);//同名方法
		*/
		User user=serviceOfUser.getUser(userid);
		//直接傳入carid和carcomment作爲參數也行,但是這樣需要再寫一個update方法
		serviceOfCar.UpdateCarComment(carcomment,carid);
		
		
		System.out.println("留言更新成功");
				
		String message="留言成功";
		request.setAttribute("message", message);
		request.setAttribute("userid", userid);
		request.setAttribute("user", user);
		
		//轉發到留言成功界面
		request.getRequestDispatcher("/WEB-INF/car/SuccessOfRespond.jsp").forward(request, response);
		
	}

對個人車庫車輛的管理大概就以上幾個功能,接下來返回上一層,我們來查看平臺所有已發佈車輛信息
在這裏插入圖片描述
相關的代碼爲:

//顯示所有用戶二手車
	public void ShowAllCarsServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		/*實現*/	
		int respondid;
		int userid=Integer.parseInt(request.getParameter("userid"));//!!
		List<Car> cars=new ArrayList<Car>();
		//cars=serviceOfCar.getAllCarsList();//獲取到所有車主所有車輛(這個會把未發佈的汽車也獲取到)
		cars=serviceOfCar.getAllReleaseCarsList();//獲取已發佈車輛
		
		respondid=userid;
		
		/*轉發*/
		String message="所有用戶的二手車信息頁面";		
		/*將消息message轉到一個jsp頁面success.jsp,在頁面打印一個“成功”消息*/
		request.setAttribute("message", message);
		request.setAttribute("cars", cars);
		request.setAttribute("userid", userid);//!!
		request.setAttribute("respondid", respondid);
		request.getRequestDispatcher("/WEB-INF/car/ShowAllCars.jsp").forward(request, response);
	
	}

個人用戶相關的操作大概就是這些了,下面我們來看看 管理員用戶 的相關操作:

在這裏插入圖片描述
在這裏插入圖片描述
管理員可以顯示所有用戶信息並進行修改等操作,也可以對平臺的二手車輛進行管理,下面貼出部分功能的代碼:
顯示所有用戶信息:

	public void ShowAllUserServlet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		java.util.List<User> users=service.getAllUsers();//獲取UserService中查詢結果
		request.setAttribute("users",users);//把獲取到的users放到request裏	
		System.out.println("進入ShowAllUserServlet");
		/*轉交給jsp頁面顯示*/
		request.getRequestDispatcher("/WEB-INF/admin/ShowAllUser.jsp").forward(request, response);
	}

在這裏插入圖片描述
並且支持對用戶進行模糊查詢,比如Name欄什麼都不輸入,在Sex欄輸入”女“,系統就會自動查詢到性別是女的所有用戶信息,如下圖:
在這裏插入圖片描述

顯示所有二手車信息:

//(管理員)顯示所有車輛信息(比普通用戶多了“屏蔽”功能,即 “留言+屏蔽” )
	//管理員可以看到所有車輛信息,包括未發佈的
	public void ShowAllCarForAdminServlet(HttpServletRequest request, HttpServletResponse response) throws Exception {
		System.out.println("進入ShowAllCarForAdminServlet()");
		List<Car> cars=new ArrayList<Car>();
		cars=serviceOfCar.getAllCarsList();//獲取到所有車主所有車輛
		String message="所有用戶的二手車信息頁面";		//(管理員頁面)
		
		request.setAttribute("message", message);
		request.setAttribute("cars", cars);
		request.getRequestDispatcher("/WEB-INF/admin/ShowAllCarForAdmin.jsp").forward(request, response);
	
	}

在這裏插入圖片描述
其他剩餘的功能這裏就不一一演示了。

上面的Servlet調用的業務邏輯實現方法放在CarService和UserService裏,下面直接貼出代碼:
UserService:

package com.service;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.bean.User;
import com.bean.UserSearchConditions;
import com.dao.UserDao;
import com.daoImpl.UserDaoImpl;
import com.utils.JdbcTools;


public class UserService {
private UserDao dao;
	
	/*獲取dao(/初始化)*/
	public UserService() {
		this.dao=new UserDaoImpl();
	}
	
	
	
	//登錄login(name+pwd)
		public boolean login(String name, String pwd) throws Exception {
			boolean flag=false;
			Connection connection = null;
			User user = new User(); 
			String sql="select * from user where name='"+name+"' and pwd='"+pwd+"'";
			try {
				
				/*獲取連接*/
				connection=JdbcTools.getconnection();
				
				System.out.println("開始調用resultset");
			
				//將查詢的結果放在一個ResultSet裏面
			ResultSet rs =dao.selectSqlLogin(connection,sql);
			
			System.out.println("查詢結果已封裝到resultset中");
			
			//遍歷ResultSet
			while(rs.next()) {
				
					if(rs.getString("name").equals(name) && rs.getString("pwd").equals(pwd)) {
						flag=true;
					}
					
				} 
				
			}catch (SQLException e) {
					e.printStackTrace();
			}finally {
				JdbcTools.releaseResource(null, connection);
			}
			
			return flag;//true即登錄成功
		}
		
		
		//根據name和pwd查找id
		public int LoginFindId(String name, String pwd) throws Exception {
			Connection connection = null;
			User user = new User(); 
			//不能寫select id ...,因爲下面要用到name和pwd(異常:Column 'name' not found)
			String sql="select * from user where name='"+name+"' and pwd='"+pwd+"'";
			try {
				
				/*獲取連接*/
				connection=JdbcTools.getconnection();
				
				System.out.println("開始調用resultset");
			
				//將查詢的結果放在一個ResultSet裏面
			ResultSet rs =dao.selectSqlLogin(connection,sql);
			System.out.println("查詢結果已封裝到resultset中");
			
			//遍歷ResultSet
			while(rs.next()) {
				System.out.println("進入while(rs.next())");
					if(rs.getString("name").equals(name) && rs.getString("pwd").equals(pwd)) {
						System.out.println("匹配到用戶");
						return rs.getInt("id");
					}
					
				} 
				
			}catch (SQLException e) {
					e.printStackTrace();
			}finally {
				JdbcTools.releaseResource(null, connection);
			}		
			return -1;//true即登錄成功
		}
		
	
	/*模糊查詢*/
	public java.util.List<User> SearchUsersByConditions(UserSearchConditions conditions){
		Connection connection = null;
		java.util.List<User> users=new java.util.ArrayList<User>();
		try {
			/*獲取連接*/
			connection=JdbcTools.getconnection();
			/*通過dao將通用查詢結果返回給名爲user的List保存*/
			users=dao.SearchUsersByConditions(connection,conditions);
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return users;
	}
	
	
	/*修改 之 實際的對數據庫更新*/
	public void UpdateUserServlet(User user){
		Connection connection =null;
		try {
			System.out.println("進入Service的UpdateUserServlet()");
			connection=JdbcTools.getconnection();
			dao.updateUser(connection, user);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		
	}
	

	
	
	/*修改 之 根據id查詢user對象*/
	public User getUser(int id){
		User user=new User();
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			user=dao.searchUserById(connection, id);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return user;
	}
	
	
	
	/*將數據添加到數據庫*/
	public boolean RegisterUserServlet(User user) throws Exception {
		boolean result=false;//因爲IdCard具有唯一性約束,所以自定義輸入數據時可能出錯,用result指示
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			dao.addUser(connection,user);
			result=true;//當添加成功時,true
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return result;
	}
	
	
	
	//刪除
	public void DeleteUserServlet(int id) throws Exception {
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			dao.deleteUser(connection, id);
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
	}
	
	public java.util.List<User> getAllUsers(){
		Connection connection = null;
		java.util.List<User> users=new java.util.ArrayList<User>();
		try {
			/*獲取連接*/
			connection=JdbcTools.getconnection();
			/*通過dao將通用查詢結果返回給名爲users的List保存*/
			users =dao.fetchAllUsers(connection);
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return users;
	}
	
	
	

	
	/*受限用戶管理--------更新表信息,將limit屬性置爲1*/
	//傳入id
	public boolean LimitUser(int id) {
		Connection connection =null;
		try {
			
			connection=JdbcTools.getconnection();
			dao.updateLimit(connection, id);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return false;
	}
	
	
	//根據id判斷該用戶是否受限(在登錄的時候判斷)
	public boolean isLimit(int id) throws Exception {
		Connection connection = null;
		User user = new User(); 
		
		//注意:sql不能寫"select limit ... 應該寫* (否則:數據庫查詢異常)
		String sql = "select * from user where id='"+id+"'";
		try {
			
			/*獲取連接*/
			connection=JdbcTools.getconnection();
			
			System.out.println("開始調用resultset");
		
			//將查詢的結果放在一個ResultSet裏面
		ResultSet rs =dao.selectSqlLogin(connection,sql);
		
		System.out.println("查詢結果已封裝到resultset中");
		
		//遍歷ResultSet
		while(rs.next()) {
			//rs.getInt("id")記得加引號(雖然id是int型,也要加)
				if(rs.getInt("id")==id) {
					System.out.println("定位到該用戶(isLimit())");
					if((rs.getInt("limit")==0)) {//==0正常用戶
						return false;//isLimit=false
					}
				}
			} 
			
		}catch (SQLException e) {
				e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		
		return true;//true即受限用戶
	}
	
	
	///
	
	
	
	//*用戶角色判斷--------判斷是否爲管理員(返回true爲管理員)*/
	//傳入id
	public boolean isAdmin(int id) throws Exception {
		Connection connection = null;
		User user = new User(); 

		//注意:sql不能寫"select limit ... 應該寫* (否則:數據庫查詢異常)
		String sql = "select * from user where id='"+id+"'";
		try {
			
			/*獲取連接*/
			connection=JdbcTools.getconnection();
		
			//將查詢的結果放在一個ResultSet裏面
		ResultSet rs =dao.selectSqlLogin(connection,sql);
		
		System.out.println("查詢結果已封裝到resultset中");
		
		//遍歷ResultSet
		while(rs.next()) {
			//rs.getInt("id")記得加引號(雖然id是int型,也要加)
				if(rs.getInt("id")==id) {
					System.out.println("定位到該用戶(isAdmin())");
					if((rs.getInt("isAdmin")==1)) {//==1爲管理員
						return true;
					}
				}
			} 
			
		}catch (SQLException e) {
				e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		
		return false;//false爲普通用戶
	}
	
	
	
	
	
}

CarService:

package com.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.bean.Car;
import com.dao.CarDao;
import com.dao.UserDao;
import com.daoImpl.CarDaoImpl;
import com.daoImpl.UserDaoImpl;
import com.utils.JdbcTools;

public class CarService {

	private UserDao userdao;
	private CarDao cardao;
	
	/*獲取dao(/初始化)*/
	public CarService() {
		this.cardao=new CarDaoImpl();
		this.userdao=new UserDaoImpl();
	}
	
	
	/*將車輛數據添加到數據庫*/
	public  boolean AddCarServlet(Car car) throws Exception {
		boolean result=false;//因爲IdCard具有唯一性約束,所以自定義輸入數據時可能出錯,用result指示
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			
			cardao.addCar(connection,car);//實現
			
			result=true;//當添加成功時,true
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return result;
	}
	
	/*修改 之 根據carid定位到車輛*/
	public Car getCarOfCarid(int carid){
		Car car=new Car();
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			car=cardao.searchCarByCarId(connection, carid);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return car;//返回car對象
	}
	
	
	/*get 根據userid定位到該車主的所有車輛*/
	public List<Car>getCarsListOfUserid(int userid){
		Connection connection =null;
		List<Car> cars=new ArrayList<Car>();
		try {
			connection=JdbcTools.getconnection();
			cars=cardao.fetchAllCarsByUserId(connection, userid);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return cars;//返回car對象
	}
	
	
	
	//獲取到所有車主所有車輛
	public List<Car> getAllCarsList(){
		Connection connection =null;
		List<Car> cars=new ArrayList<Car>();
		try {
			System.out.println("進入 getAllCarsList");
			connection=JdbcTools.getconnection();
			cars=cardao.fetchAllCars(connection);
		} catch (Exception e) {
			//System.out.println("獲取所有車主所有車輛,獲取失敗");
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return cars;//返回car對象
	}
	
	
	
	
	//獲取已發佈車輛
	public List<Car> getAllReleaseCarsList(){
		Connection connection =null;
		List<Car> cars=new ArrayList<Car>();
		try {
			connection=JdbcTools.getconnection();
			cars=cardao.fetchAllReleaseCars(connection);
		} catch (Exception e) {
			//System.out.println("獲取所有車主所有車輛,獲取失敗");
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		return cars;
	}
	
	
	
	
	/*修改 之 實際的對數據庫更新*/
	public void UpdateCarSelfServlet(Car car){
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			cardao.updateCar(connection, car);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		
	}
	
	
	
	//刪除該用戶的某一輛二手車(根據carid)
	public void DeleteCarServlet(int carid) throws Exception {
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			cardao.deleteCar(connection, carid);
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
	}
	
	
	//更新 留言 到數據庫
	public void UpdateCarComment(String carcomment,int carid){
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			cardao.updateCarComment(connection,carcomment,carid);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		
	}
	
	
	//發佈車輛
	public void ReleaseCarServlet(int carid){
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			cardao.updateRelease(connection,carid);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
		
	}
	
	//禁止該車輛留言功能(根據carid)
	public void RespondBan(int carid){
		Car car=new Car();
		Connection connection =null;
		try {
			connection=JdbcTools.getconnection();
			cardao.updateCanMessage(connection,carid);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcTools.releaseResource(null, connection);
		}
	}
	
	
	
	
}

在Service中調用的對數據庫的方法,放在了下面這幾個文件中:
在這裏插入圖片描述
這裏通過接口的方式進行處理,在接口實現類CarDaoImpl、UserDaoImpl、DaoImpl對數據庫進行處理,其中CarDaoImpl和UserDaoImpl都繼承了DaoImpl,作爲它的子類,在CarDaoImpl、UserDaoImpl中,可以直接調用父類的方法,下面是這幾個接口實現類的代碼:
(1)DaoImpl:

package com.daoImpl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
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.dao.Dao;

public class DaoImpl<T> implements Dao<T> {
	private QueryRunner queryRunner;//因爲QueryRunner是線程安全的,所以可以寫在所有方法的外面
	private Class<T> type;//成員變量
	
	/*利用“反射”機制,獲取到 類的類型
	 * 下面這個函數本質是站在 DAOImpl 類的一個子類的對象 的角度上考慮
	 * */
	@SuppressWarnings("rawtypes")
	private Class getSuperClassGenricType(Class clazz, int index) {
		Type genType = clazz.getGenericSuperclass();
		if (!(genType instanceof ParameterizedType)) {
			return Object.class;
		}
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		if (index >= params.length || index < 0) {
			return Object.class;
		}
		if (!(params[index] instanceof Class)) {
			return Object.class;
		}
		return (Class) params[index];
	}
	
	/*
	 * 構造器
	 * 1.創建QueryRunner對象
	 * 2.獲取類的類型type
	 * */
	@SuppressWarnings("unchecked")
	public DaoImpl() {
		queryRunner = new QueryRunner();
		type = getSuperClassGenricType(getClass(), 0);
	}
	
	
	/*查詢(獲取)一行數據
	 * 注意:是向函數外拋出異常,而不是在函數內部處理
	 * */
	@Override
	public T fetch(Connection connection, String sql, Object... objects) throws SQLException {
		
		/*BeanHandler需要傳入一個“類.class”參數,但是這裏並不知道這個類是什麼類型(/什麼類)
		 * 這裏利用到“反射”機制,實現了用於尋找類型type的方法
		 * */
		BeanHandler<T> rsh = new BeanHandler<T>(type);//返回一行數據,用到BeanHandler
		
		return queryRunner.query(connection, sql, rsh, objects);//直接返回這個對象
	}

	@Override
	public List<T> fetchList(Connection connection, String sql, Object... objects) throws SQLException {
		
		/*同上*/
		BeanListHandler<T> rsh = new BeanListHandler<T>(type);//返回一行數據,用到BeanHandler
		
		return queryRunner.query(connection, sql, rsh, objects);//直接返回這個對象
	}

	@Override
	public void update(Connection connection, String sql, Object... objects) throws SQLException {
		queryRunner.update(connection, sql, objects);	
	}

	@Override
	public <E> E fetchScaler(Connection connection, String sql, Object... objects) throws SQLException {
		ScalarHandler <E> rsh =new ScalarHandler<E>();//泛型
		return (E) queryRunner.query(connection, sql, rsh, objects);//強制轉換爲(E)
	}

}

(2)CarDaoImpl:

package com.daoImpl;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import com.bean.Car;
import com.bean.CarSearchConditions;
import com.bean.User;
import com.dao.CarDao;

/*繼承父類,這裏實現的是Car表,類型是Car
 * 
 * 繼承DaoImpl,可以直接使用裏面的方法
 * */
public class CarDaoImpl extends DaoImpl<Car> implements CarDao {

	@Override
	public void addCar(Connection connection, Car car) throws SQLException {
		
		String sql = "INSERT INTO car (userid,brand,model,price,color,carcomment) VALUES (?,?,?,?,?,?)";//屬性carid是遞增,所以這裏不用寫(默認的屬性也不用寫)
	
		Object[] objs = {car.getUserid(),car.getBrand(),car.getModel(),car.getPrice(),car.getColor(),car.getCarcomment() };//用對象去類中獲取數據
		//queryRunner.update(connection, sql, objs);//調用QueryRunner類中的方法
		update(connection,sql,objs);//更新數據庫

	}

	@Override
	public void deleteCar(Connection connection, int carid) throws SQLException {
		String sql = "DELETE FROM car WHERE carid=?";
		update(connection, sql, carid);
	}

	@Override
	public void updateCar(Connection connection, Car car) throws SQLException {
		String sql = "UPDATE car set brand=?,model=?,price=?,color=?,carcomment=? WHERE carid=?";
		Object[] objs = {car.getBrand(),car.getModel(),car.getPrice(),car.getColor(),car.getCarcomment(),car.getCarid()};
		update(connection, sql, objs);
		
	}
	
	//更新留言
	public void updateCarComment(Connection connection,String carcomment,int carid) 
			throws SQLException{
		String sql = "UPDATE car set carcomment=? WHERE carid=?";
		update(connection, sql, carcomment,carid);
	}

	
	///更新發布信息
	public void updateRelease(Connection connection,int carid) 
			throws SQLException{
		String sql = "UPDATE car set isrelease=1 WHERE carid=?";
		update(connection, sql,carid);
	}
	
	
	@Override
	public Car searchCarByCarId(Connection connection, int carid) throws SQLException {
		String sql = "SELECT * FROM car WHERE carid=?";
		return fetch(connection, sql, carid);
	}
	

	
//獲取所有用戶所有車輛
	@Override
	public List<Car> fetchAllCars(Connection connection) throws SQLException {
		String sql = "SELECT * FROM car";
		return fetchList(connection, sql);
	}
	
	
	//獲取已發佈車輛
	@Override
	public List<Car> fetchAllReleaseCars(Connection connection) throws SQLException {
		String sql = "SELECT * FROM car where isrelease=1";
		return fetchList(connection, sql);
	}
	

	
	//根據userid找到該車主名下所有汽車
	public List<Car> fetchAllCarsByUserId(Connection connection,int userid) throws SQLException {
		String sql = "SELECT userid,carid,brand,model,price,color,datePosted,isrelease,CanMessage,carcomment FROM car where userid=?";
		System.out.println("在fetchAllCarsByUserId即將調用fetchList執行sql");

		return fetchList(connection, sql,userid);
	}
	
	
	@Override
	public List<Car> SearchCarsByConditions(Connection connection, CarSearchConditions conditions)
			throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	//禁止該車輛留言功能
	public void updateCanMessage(Connection connection,int carid) 
			throws SQLException{
		String sql = "UPDATE car set canmessage=1 WHERE carid=?";
		update(connection, sql,carid);
	}

}

(3)UserDaoImpl:

package com.daoImpl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;

import com.bean.User;
import com.bean.UserSearchConditions;
import com.dao.UserDao;

/*繼承父類,這裏實現的是User表,類型是User
 * 
 * 繼承DaoImpl,可以直接使用裏面的方法
 * */
public class UserDaoImpl extends DaoImpl <User> implements UserDao {
	static ResultSet rs = null;
	static PreparedStatement ps =null;

		/*因爲QueryRunner是線程安全的,所以可以寫在所有方法的外面*/
		QueryRunner queryRunner=new QueryRunner();//QueryRunner類
		
		
		//登錄驗證(name+pwd)
		public ResultSet selectSqlLogin(Connection connection,String sql){
			try {
				ps=connection.prepareStatement(sql);
				rs=ps.executeQuery(sql);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				System.out.println("數據庫查詢異常");
				e.printStackTrace();
			}
			return rs;//返回查詢的數據集
	}
		
		
		public void addUser(Connection connection, User user) throws SQLException {
			String sql = "INSERT INTO user (name,pwd, sex) VALUES ( ?, ?, ?)";//屬性id是遞增,所以這裏不用寫
			Object[] objs = {user.getName(), user.getPwd(), user.getSex()};//用對象去類中獲取數據
			//queryRunner.update(connection, sql, objs);//調用QueryRunner類中的方法
			update(connection,sql,objs);//更新數據庫
		}

		public void deleteUser(Connection connection, int id) throws SQLException {
			String sql = "DELETE FROM user WHERE id=?";
			update(connection, sql, id);
		}

		public void updateUser(Connection connection, User user) throws SQLException {
			System.out.println("進入UserDaoImpl的updateUser");
			String sql = "UPDATE user set name=?, pwd=?, sex=? WHERE id=?";
			Object[] objs = {user.getName(), user.getPwd(), user.getSex(), user.getId()};
			update(connection, sql, objs);
		}

		public User searchUserById(Connection connection, int id) throws SQLException {
			String sql = "SELECT id,name,pwd,sex,isAdmin FROM user WHERE id=?";
			return fetch(connection, sql, id);
		}

		public List<User> fetchAllUsers(Connection connection) throws SQLException {
			String sql = "SELECT * FROM user";
			return fetchList(connection, sql);
		}
		

		
		
		//模糊查詢
		public List<User> SearchUsersByConditions(Connection connection, UserSearchConditions conditions) throws SQLException {
			String sql = "SELECT name,sex FROM user " //這裏換行時要加個空格,否則會與下面的where識別成一個單詞
		+"WHERE name like ? AND sex like ?";
			Object[] objs= {conditions.getName(),conditions.getSex()};
			return fetchList(connection, sql,objs);
		}
	

		
		//受限用戶管理(管理員權限)
		public void updateLimit(Connection connection, int id) 
				throws SQLException{
			System.out.println("進入updateLimit,下面創建sql");
			
			/*注意,limit在mysql是關鍵字,在這裏要加符號圈起來*/
			String sql = "UPDATE user set `limit`=1 WHERE id=?";
			
			System.out.println("sql創建完成,下面開始執行sql");
//			ps=connection.prepareStatement(sql);
//			ps.executeQuery(sql);
			//queryRunner.update(connection, sql);
			update(connection, sql, id);
			System.out.println("limit更新成功");
		}
	
		
		//登錄時查詢該用戶是否受限
		public ResultSet SearchIsLimit(Connection connection, String sql) 
				throws SQLException{
			try {
			ps=connection.prepareStatement(sql);
			rs=ps.executeQuery(sql);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("數據庫查詢異常");
			e.printStackTrace();
		}
			return rs;//返回查詢的數據集
		}
		

	
}

六、結語

縱觀整個項目,可以發現,在實現具體的功能時,方法都是大同小異,基於MVC模式讓代碼的邏輯結構變得清晰,在功能實現上也變得方便快捷,遇到報錯也能夠迅速定位到錯誤的地方,並且基於這種模式在後期系統擴容或更新時會讓維護更加簡單,不需要進行徹頭徹尾的大變動。
這個項目所實現的功能並不複雜,只能作爲一個入門項目,分析完這個項目,可以讓你對該項目設計到的技術有個更加清晰的認識,並通過這個項目,作爲一個敲門磚,打開你對這一方向的大門,爲更加深入的學習各種框架以及更加深入的知識打下一個基礎。作爲一名學生,我也在不斷地努力,也許這篇文章並不能給你的學習甚至工作帶來幫助,但是隻要我們有一顆愛學並且上進的心,一切都會變得美好。我也是第一次寫這麼長的文章,裏面的不足之處肯定也體現的很明顯,我很歡迎各位路過的大神對我這個項目進行批評指正,我會虛心接受您的意見,並不斷學習。大家一起加油!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章