【云圖說】第235期 DDS讀寫兩步走 帶您領(lǐng)略只讀節(jié)點(diǎn)的風(fēng)采
945
2025-03-31
# JavaWeb+MySQL實(shí)現(xiàn)簡易留言板
> Hello,各位小伙伴們你們好,我是Bug終結(jié)者~,不知不覺,已經(jīng)放假2周了,一晃來到了一周一更,今天我決定更新文章,今天為大家?guī)砦覍W(xué)習(xí)過程中的一些經(jīng)驗(yàn),為小伙伴們避坑,下面為大家?guī)斫袢辗窒?/p>
## 留言板需求
**上圖顯示的是評論頁面的樣式**
評論頁面主要分為三部分: 登錄狀態(tài)區(qū)、 評論區(qū)(評論和回復(fù)操作的區(qū)域)、評論列表區(qū)(顯示所有的評論、回復(fù),以及翻頁控件)
1. 登錄狀態(tài)區(qū):
1.1 用戶不登錄也可以看到該列表,但必須登錄才可以發(fā)表評論和回復(fù)。
1.2 用戶不登錄也可以看到評論區(qū)
1.3 用戶不登錄也可以看到回復(fù)按鈕
1.4 用戶未登錄狀態(tài),在評論區(qū)上方顯示: 注冊 和 登錄 超級鏈接,點(diǎn)擊分別可以進(jìn)入注冊和登錄頁面。
1.5 登錄狀態(tài),在評論區(qū)上方顯示: 歡迎 XXXX ,注銷 ?。
1.6 注銷是超級鏈接,點(diǎn)擊注銷進(jìn)入未登錄狀態(tài)。
2. 評論區(qū):
2.1 默認(rèn)顯示為發(fā)表評論狀態(tài)。
2.2 發(fā)表評論狀態(tài)下,只顯示 textarea控件 和 發(fā)表評論按鈕。
點(diǎn)擊某條評論的回復(fù)按鈕,狀態(tài)切換為針對該條評論的回復(fù)狀態(tài)。
2.3 回復(fù)狀態(tài)下,在評論區(qū) textarea 上方將顯示:
我要回復(fù) XXX 在 2021-08-09 19:23 的評論: 聽的又123
2.4 回復(fù)狀態(tài)下,發(fā)表評論按鈕,變成 發(fā)表回復(fù)
2.5 回復(fù)狀態(tài)下,發(fā)表評論按鈕右側(cè)顯示一個按鈕“返回評論狀態(tài)” ,點(diǎn)擊將進(jìn)入評論狀態(tài)。
即評論區(qū)有兩個狀態(tài): 評論狀態(tài)和 回復(fù)狀態(tài)
2.6 評論狀態(tài),發(fā)表的是 評論,回復(fù)狀態(tài)是對某條評論回復(fù)評論。
2.7 回復(fù)狀態(tài)是針對某條評論的。
3. 評論列表:
顯示所有評論的列表。
顯示評論人、評論時間、評論內(nèi)容。
每條評論的右側(cè),有回復(fù)按鈕,點(diǎn)擊回復(fù)將進(jìn)入針對該條評論的 回復(fù)狀態(tài)。
登錄狀態(tài)下自己發(fā)表的評論,右側(cè)有刪除按鈕
其他人發(fā)表的評論,右側(cè)看不到刪除按鈕。
如果評論有回復(fù),則在評論下顯示回復(fù)列表。
每條回復(fù)顯示 回復(fù)人、回復(fù)時間、回復(fù)內(nèi)容。
在登錄狀態(tài)下,當(dāng)前登錄人可以看到自己回復(fù)記錄的右側(cè)有刪除按鈕。
評論要實(shí)現(xiàn)分頁,不需要查詢。
**看下效果:**



## 數(shù)據(jù)表
用戶表
```sql
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`realname` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
```
評論表
```sql
CREATE TABLE `t_comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '評論人id,對應(yīng)用戶表的id',
`pl_content` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '評論的內(nèi)容',
`pl_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
```
回復(fù)表
```sql
CREATE TABLE `t_revert` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pl_id` int(11) NOT NULL COMMENT '評論人id,對應(yīng)t_comment.id',
`user_id` int(11) DEFAULT NULL COMMENT '回復(fù)人id,對應(yīng)當(dāng)前登錄的賬號.id',
`hf_content` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '回復(fù)的內(nèi)容',
`hf_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '回復(fù)的時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
```
**項目結(jié)構(gòu)**

## 部分代碼
**IndexServlet**
```java
@WebServlet("/index")
public class IndexServlet extends HttpServlet{
public static final Integer pageSize = 5;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取當(dāng)前頁數(shù)
String strPageNumb = req.getParameter("pageNumb");
Integer pageNumb = 1;
if (!StringUtils.isEmpty(strPageNumb)) {
pageNumb = Integer.valueOf(strPageNumb);
}
CommentService commentService = new CommentServiceImpl();
try {
PageInfo pager = commentService.page(pageNumb, pageSize);
req.setAttribute("pager", pager);
req.getRequestDispatcher("/WEB-INF/comment.jsp")
.forward(req, resp);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
```
**CommentServlet**
```java
@WebServlet("/comment")
public class CommentServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取數(shù)據(jù),當(dāng)前評論人的id,評論的內(nèi)容
String content = req.getParameter("content");
User user = (User)req.getSession().getAttribute("user");
Integer userId = user.getId();
CommentService commentService = new CommentServiceImpl();
try {
if (commentService.saveComment(userId, content)) {
resp.sendRedirect(req.getContextPath()+"/index");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
```
**RevertServlet**
```java
@WebServlet("/revert")
public class RevertServlet extends HttpServlet{
RevertService RevertService = new RevertServiceImpl();
CommentService CommentService = new CommentServiceImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取回復(fù)的記錄id
String pl_id = req.getParameter("pl_id");
try {
Comment comment = CommentService.queryById(Integer.valueOf(pl_id));
System.out.println("123");
req.setAttribute("comment", comment);
req.getRequestDispatcher("/WEB-INF/revert.jsp")
.forward(req, resp);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取回復(fù)的具體信息
String plId = req.getParameter("pl_id");
String liuYan = req.getParameter("liuYan");
System.out.println(plId);
User user = (User) req.getSession().getAttribute("user");
Integer userId = user.getId();
try {
if (RevertService.saveRevert(plId, liuYan, userId)) {
resp.sendRedirect(req.getContextPath()+"/index");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
```
**Dao層核心代碼 **
------
**連接數(shù)據(jù)庫基類**
**BaseDao**
```java
public class BaseDao {
private static DataSource ds = null;
public QueryRunner initQueryRunner() throws Exception {
String dbFile = this.getClass().getClassLoader().getResource("/").getFile();
dbFile = dbFile.substring(1) + "db.properties";
FileReader fr = new FileReader(dbFile);
Properties pro = new Properties();
pro.load(fr);
// ? ? ? ?DataSource ds = DruidDataSourceFactory.createDataSource(pro);
if (ds == null) {
ds = DruidDataSourceFactory.createDataSource(pro);
}
QueryRunner qur = new QueryRunner(ds);
System.out.println(ds);
return qur;
}
}
```
**CommentDaoImpl**
```java
public class CommentDaoImpl extends BaseDao implements CommentDao{
@Override
public List
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "select * from t_comment order by pl_time desc limit ?, ? ";
return qur.query(sql, new BeanListHandler
}
@Override
public Comment queryById(Integer id) throws Exception {
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "select * from t_comment where id = ?";
return qur.query(sql, new BeanHandler
}
@Override
public Integer delete(String pl_id) throws Exception {
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "delete from t_comment where id = ?";
return qur.update(sql, pl_id);
}
@Override
public Integer saveComment(Integer userId, String content) throws Exception {
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "insert into t_comment (user_id, pl_content) values(?, ?)";
//如果update方法返回的大于0,代表增加成功,返回的小于0代表失敗
return qur.update(sql, userId, content);
}
@Override
public Integer getCount() throws Exception {
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "select count(1) from t_comment";
Long rowCount = qur.query(sql, new ScalarHandler
return rowCount.intValue();
}
}
```
**RevertDaoImpl**
```jav
public class RevertDaoImpl extends BaseDao implements RevertDao{
@Override
public Integer saveRevert(String plId, String liuYan, Integer userId) throws Exception {
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "insert into t_revert (pl_id, user_id, hf_content) values(?, ?, ?)";
System.out.println(plId);
return qur.update(sql, plId, userId, liuYan);
}
@Override
public List
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "select * from t_revert where pl_id = ?";
return qur.query(sql, new BeanListHandler
}
@Override
public Integer delete(String hfId) throws Exception {
// TODO Auto-generated method stub
QueryRunner qur = initQueryRunner();
String sql = "delete from t_revert where id = ?";
return qur.update(sql, hfId);
}
}
```
## 絮語
> 今日經(jīng)驗(yàn)分享到此就要結(jié)束了,代碼路漫漫,有人與你共赴前行,遇到困難去解決,最后都會化為你寶貴的經(jīng)驗(yàn),每周一更,回憶一周內(nèi)值得寫的項目,把代碼共享,分享自己做練習(xí)的一些思路,好了,本周分享該案例,我們下周見!
**都看到這了,點(diǎn)個贊支持一下博主吧~**
Java MySQL web前端
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。