本文致力於,讓編程者一步步明白書寫一個JavaWeb項目應該做些什麼,梳理清楚流程框架,需要的jar包,同時手寫了一個分頁工具類也在其中,讓你在編程中更加絲滑。 ...
搭建一個JavaWeb項目流程
本文致力於,讓編程者一步步明白書寫一個JavaWeb項目應該做些什麼,梳理清楚流程框架,需要的jar包,同時手寫了一個分頁工具類也在其中,讓你在編程中更加絲滑。
1.src\main\java\com\einmeer\qianyu
刪除系統預設生成的
HelloServlet.java
1.1tools包
DruidTools.java
需要在
lib
中加入druid-1.1.22.jar
package com.einmeer.qianyu.tools;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* @author 芊嵛
* @date 2024/1/18
* JDBC操作,就是在java中操作資料庫
* 封裝資料庫連接工具,帶連接池的
*/
public class DruidTools {
//聲明連接池對象
private static DruidDataSource dataSource;
//java的靜態代碼塊,作初始化用
static {
//讀取外部配置文件的內容,生成位元組流輸入流對象
InputStream in = DruidTools.class.getResourceAsStream("/Druid.properties");
//創建屬性集合對象
Properties properties = new Properties();
try {
//載入輸入流對象
properties.load(in);
//生成連接池對象
dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取接池對象,便於dbutils使用,簡化原生JDBC的增刪改查功能CURD
public static DruidDataSource getDataSource(){
return dataSource;
}
//拿到資料庫連接對象,便於我們操作MYSQL
public static Connection getConn() {//方便之後重覆使用
Connection conn = null;
try {
//創建資料庫連接對象(資料庫地址,用戶名,密碼)
conn = dataSource.getConnection();
System.out.println("資料庫連接成功success!");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
////測試一下,建議用單元測試
public static void main(String[] args) {
getConn();
}
}
Pagination.java
分頁,封裝好了方法之後直接調用就行
package com.einmeer.qianyu.tools;
import java.util.List;
/**
* @author 芊嵛
* @date 2024/1/19
*/
public class Pagination<T> { // 使用泛型是為了復用
// 當前頁號
private int currentPage;
// 總頁號或總頁數
private int totalPage;
// 每頁記錄數或行數
private int limitRows;
// 總的記錄數或行數
private int totalRows;
// 每頁開始的記錄號
private int startRecord;
// 每頁結束的記錄號,這個沒用,只需每頁記錄行數limitRows即可
// private int endRecord;
// 存每頁中的記錄
private List<T> list;
// //初始化操作
public void init() {
// 1.求總頁數,通過總記錄數與每頁行數來計算,有幾種情況
// (1)不夠一頁(2)有零頭(3)剛好是整數頁
int tp = totalRows / limitRows;
if (totalRows > limitRows) {
// 判斷是是剛剛好還是一頁多一點
totalPage = (totalRows % limitRows) == 0 ? tp : tp + 1;
} else {
totalPage = 1;
}
// 2.將當頁保留在第一頁或最後一頁
if (currentPage > totalPage) {
currentPage = totalPage;
} else if (currentPage < 1) {
currentPage = 1;
}
// 3.初始化開始記錄數,mysql應用的limit它不包括開始記錄,所以不要加1;
// 還有limit傳入的是開始記錄號與查詢的條數,此處是每頁可顯示數limitRows,
// 如果查到最後沒有limitRows限制的行數,則顯示剩餘部分
this.startRecord = (currentPage - 1) * limitRows;
}
// 無參構造,便於使用
public Pagination() {
}
// 當前頁號,總記錄數,每頁行數;這些屬性需要傳入後初始化,其它的可以set設置
public Pagination(int currentPage, int totalRows, int limitRows) {
this.currentPage = currentPage;
this.totalRows = totalRows;
this.limitRows = limitRows;
}
// get與set方法
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getLimitRows() {
return limitRows;
}
public void setLimitRows(int limitRows) {
this.limitRows = limitRows;
}
public int getTotalRows() {
return totalRows;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public int getStartRecord() {
return startRecord;
}
public void setStartRecord(int startRecord) {
this.startRecord = startRecord;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
1.2entity包
Entity層,實體層,放入實體類
// Lombok註解
@Builder // 一步步創建一個對象,它對用戶屏蔽了裡面構建的細節,但卻可以精細地控制對象的構造過程,不寫@Builder,@AllArgsConstructor會報紅
@Data // 提供了get、set、equals、toString方法
@NoArgsConstructor // 生成一個無產構造函數
@AllArgsConstructor // 生成一個包含所有變數的有參構造函數
實現序列化
Serializable介面就是Java提供用來進行高效率的異地共用實例對象的機制,實現這個介面即可。
implements Serializable
1.3dao包
DAO數據訪問層,把訪問資料庫的代碼封裝起來,不涉及業務邏輯
// 介面:寫需要的細分功能的名字,能用sql語句表示出來,如格局用戶id查詢用戶全部信息
User selectUserById(Long userId);
// 實現類
//1.建議先定義一個全局結果集返回對象,應為每次運行sql語句都會返回結果
QueryRunner qr = new QueryRunner(DruidTools.getDataSource());
// 2.每個介面第一句都把返回值類型置為空(查詢語句置為null)或者0(增刪改置為0)
List<User> list = null;
int n = 0;
// 3.每個介面第二句寫sql語句(我這裡舉例簡單寫寫*號實際一定不要寫*)
String sql = "select * from user where username like ? and userGender = ? limit ?,?";
// 4.創建一個對象類數組(裡面放?號代替的東西,註意位置不要錯)
// 如果就一個參數或者不需要參數不用寫這個,多個參數再寫
Object[] param = {"%"+username+"%",userGender,start,number};
// 5.處理異常,執行sql
try {
// 查詢
// 返回list結果集BeanListHandler<>()
// 返回對象BeanHandler<>()
// 返回單個數據ScalarHandler<>()
// query(String sql, ResultSetHandler<T> rsh)
// query(String sql, Object param, ResultSetHandler<T> rsh)
// query(String sql, Object[] params, ResultSetHandler<T> rsh)
// 更多可以看看源碼
list = qr.query(sql, new BeanListHandler<User>(User.class));
user = qr.query(sql, param, new BeanHandler<>(User.class));
// 這個看其他資料說是返回Object類型需要轉,但是我測試並不需要,返回的就是我要的類型
n = qr.query(sql,parm,new ScalarHandler<>());
// 更新/刪除/插入
// update(String sql, Object param)
// update(String sql, Object... params)
n = qr.update(sql, username);
n = qr.update(sql, param);
} catch (SQLException e) {
throw new RuntimeException(e);
}
// 6.return 第一步的名字;
return list;
return n;
1.4service包
Service業務邏輯層,處理邏輯上的業務,而不去考慮具體的實現。
通過調用數據訪問層,實現邏輯上的業務,一個介面的實現可能需要多個dao層的介面
// 介面:定義好方法,之後servlet直接調用,與servlet方法數量相同
// 名字最好不要跟dao層一樣
// dao:select
// service:query
// 實現類
// 1.全局調一下dao層,方便下麵調用
private UserDao userDao = new UserDaoImpl;
// 2.自由發揮
1.5servlet包
Servlet(Server Applet)是Java Servlet的簡稱,是為小服務程式或服務連接器,用Java編寫的伺服器端程式,主要功能在於互動式地瀏覽和修改數據,生成動態Web內容。
// 1.註解,
@WebServlet("/user")
// 2.繼承HttpServlet
public class UserServlet extends HttpServlet{}
// 3.創建服務類對象
private UserService userService = new UserServiceImpl();
// 4.重寫doGet()方法,如果調用它就會調用doPost()方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
// 5.重寫doPost()方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 首局一定要寫這句,把用戶傳來的數據如果有漢字轉為漢字,不然亂碼
req.setCharacterEncoding("utf8");
// 這裡我前端頁面隱藏了一個表單,區分頁面傳入的是哪個方法
// <input type="hidden" name="method" value="pn-prid">
String method = req.getParameter("method");
// 根據method判斷需要調用什麼方法
}
// 6.具體方法,舉一個例子
public void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 前端傳來的參數
String proCode = req.getParameter("queryProCode");
String proName = req.getParameter("queryProName");
Object current = req.getParameter("current");
// 實現分頁(當時劃分不清楚,這塊感覺可以寫進service進行封裝)
int temp1 = 0;
if (current != null) {
temp1 = Integer.parseInt(req.getParameter("current"));
}
long temp = ps.queryCount(proCode,proName);
int totalRows = (int) temp;
Pagination<Provider> pg = new Pagination<>(temp1, totalRows, 10);
pg.init();
List<Provider> providers = ps.queryLimit(proCode,proName,pg.getStartRecord(), 10);
pg.setList(providers);
// 攜帶數據請求轉發
RequestDispatcher rd = req.getRequestDispatcher("WEB-INF/jsp/providerlist.jsp");
// 攜帶數據
req.setAttribute("p1",proCode);
req.setAttribute("p2",proName);
req.setAttribute("providers", pg.getList());
req.setAttribute("pg", pg);
rd.forward(req, resp);
}
2.src\main\resources
druid.properties
# 如果mysql是5版本的去掉cj
driverClassName=com.mysql.cj.jdbc.Driver
# 埠號預設3306如果修改了記得把此處進行修改
# 記得修改資料庫的名字
url=jdbc:mysql://localhost:3306/資料庫名字?rewriteBatchedStatements=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
# 資料庫賬號,根據實際填寫
username=root
# 資料庫密碼,根據實際填寫
password=quanyu9988.gmail.com
# 一般不需要更改,初始化資料庫連接池
initialSize=10
# 一般不需要更改,連接池的最大資料庫連接數
maxActive=20
# 一般不需要更改,超時等待時間一毫秒為單位
maxWait=1000
# 一般不需要更改,連接池的最小空閑連接數,如果空閑的連接數大於該值,則關閉多餘連接,反之創建更多連接滿足最小連接數的要求
minIdle=5
3.src\main\webapp
3.1WEB-INF\lib
// 不導入,連接池用不了
druid-1.1.22.jar
// 導入可以使用QueryRunner類+ResultSetHandler類,更方便的完成curd
commons-dbutils-1.7.jar
// 資料庫驅動,我這裡用的8
mysql-connector-java-8.0.25.jar
//使用JSTL核心標簽庫,需要導入下麵兩個依賴
standard.jar
jstl.jar
3.2WEB-INF\jsp
存放無法直接在地址欄訪問的界面
3.3WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--歡迎頁,也就是一啟動就能看見的頁面-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
3.4暴露在外面的內容
例如:
css
js
images以及能直接在地址欄訪問的界面
login.jsp
register.jsp下麵jsp頁面第八行必須寫上,才能證明他是jsp頁面
<%--
Created by IntelliJ IDEA.
User: Qy
Date: 2024/1/18
Time: 20:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--如果用到了核心標簽記得加上核心標簽庫--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
<%--所有外面的靜態資源一定要用<%=request.getContextPath()%>代替..不然找不到數據--%>
<link type="text/css" rel="stylesheet" href="<%=request.getContextPath()%>/css/style.css"/>
</head>
<body>
</body>
</html>
4.pom.xml
這份說明沒用到maven,採取自己導入jar包,這麼的代碼沒有修改只是作為說明
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- maven的基本信息-->
<modelVersion>4.0.0</modelVersion>
<!-- 聲明遵循哪一個pom模型版本-->
<!-- 組織表示,一般是公司網站倒過來-->
<groupId>com.einmeer</groupId>
<!-- 本項目的唯一標識ID,項目名稱-->
<artifactId>qianyu</artifactId>
<!-- 項目當前版本號-->
<version>1.0-SNAPSHOT</version>
<!-- 右邊maven名字-->
<name>qianyu</name>
<!-- 打包方式-->
<packaging>war</packaging>
<!-- POM之間的關係-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.9.2</junit.version>
</properties>
<!-- 依賴關係列表-->
<dependencies>
<!-- 自己添加的lombok可以讓我們在寫實體類的時候大大減少代碼量-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<!-- 依賴項的組織名-->
<groupId>javax.servlet</groupId>
<!-- 依賴項的子項目名-->
<artifactId>javax.servlet-api</artifactId>
<!-- 依賴項的版本-->
<version>4.0.1</version>
<!-- 依賴項的適用範圍-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 構建設置-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>