⭐基于bootstap-jquery-jsp-servlet-mysql⭐博客项目——后台论坛管理demo(代码片段)

stormzhuo stormzhuo     2023-01-13     413

关键词:

这一篇主要实现后台论坛管理的实现,代码逻辑跟之前用户管理,资源管理是一样

表的设计

同样的,论坛管理需要两个表,一个是管理用户帖子的表post,另一个是管理帖子评论的表comment

显然,管理用户帖子的表需要一个外键,post_uid对应用户账号user_id

这样当删除用户时,用户所拥有的帖子也会被删除

而管理帖子评论的表,需要两个外键,其中一个外键comment_pid对应用户的帖子post_id,另一个comment_uid对应用户账号user_id

这样当删除用户时,用户所拥有的评论也会被删除,同理,当删除帖子时时,属于这种帖子的评论也会被删除

管理用户帖子表post如下

字段名称类型约束描述
post_idint(10)NOT NULL AUTO_INCREMENT帖子编号
post_uidvarchar(20)NOT NULL FOREIGN KEY (post_uid) REFERENCES user (user_id) ON DELETE CASCADE ON UPDATE CASCADE外键对应用户账号
post_titlevarchar(100)NOT NULL帖子标题
post_textlongtextNOT NULL帖子内容
post_imagevarchar(500)DEFAULT NULL图片路径
post_timedatetimeNOT NULL帖子发布时间

帖子评论表comment如下

字段名称类型约束描述
comment_idint(10)NOT NULL AUTO_INCREMENT评论编号
comment_pidint(10)NOT NULL FOREIGN KEY (comment_pid) REFERENCES post (post_id) ON DELETE CASCADE ON UPDATE CASCADE外键对应帖子编号
comment_uidvarchar(20)NOT NUL FOREIGN KEY (comment_uid) REFERENCES user (user_id) ON DELETE CASCADE ON UPDATE CASCADE外键对应用户账号
comment_textvarchar(250)NOT NULL评论内容
comment_timedatetimeNOT NUL评论时间

表的创建

post表的创建

在mysql命令行使用如下sql语句创建post表

DROP TABLE IF EXISTS `post`;
CREATE TABLE `post` (
  `post_id` int(10) NOT NULL AUTO_INCREMENT,
  `post_uid` varchar(20) NOT NULL,
  `post_title` varchar(100) NOT NULL,
  `post_text` longtext NOT NULL,
  `post_image` varchar(500) DEFAULT NULL,
  `post_time` datetime NOT NULL,
  PRIMARY KEY (`post_id`),
  KEY `post_uid` (`post_uid`),
  CONSTRAINT `post_ibfk_1` FOREIGN KEY (`post_uid`) REFERENCES `user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

comment表的创建

在mysql命令行使用如下sql语句创建comment表

DROP TABLE IF EXISTS `comment`;
CREATE TABLE `comment` (
  `comment_id` int(10) NOT NULL AUTO_INCREMENT,
  `comment_pid` int(10) NOT NULL,
  `comment_uid` varchar(20) NOT NULL,
  `comment_text` varchar(250) NOT NULL,
  `comment_time` datetime NOT NULL,
  PRIMARY KEY (`comment_id`),
  KEY `comment_uid` (`comment_uid`),
  KEY `comment_pid` (`comment_pid`),
  CONSTRAINT `comment_ibfk_2` FOREIGN KEY (`comment_uid`) REFERENCES `user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `comment_ibfk_3` FOREIGN KEY (`comment_pid`) REFERENCES `post` (`post_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

创建实体类

在entity包下,创建帖子实体post,如下

public class Post 
    private int postId;
    private String postUid;
    private String postTitle;
    private String postText;
    private String postImage;
    private String postTime;
	public Post() 
		super();
	
	public Post(int postId, String postUid, String postTitle, String postText, String postImage, String postTime) 
		super();
		this.postId = postId;
		this.postUid = postUid;
		this.postTitle = postTitle;
		this.postText = postText;
		this.postImage = postImage;
		this.postTime = postTime;
	
	public int getPostId() 
		return postId;
	
	public void setPostId(int postId) 
		this.postId = postId;
	
	public String getPostUid() 
		return postUid;
	
	public void setPostUid(String postUid) 
		this.postUid = postUid;
	
	public String getPostTitle() 
		return postTitle;
	
	public void setPostTitle(String postTitle) 
		this.postTitle = postTitle;
	
	public String getPostText() 
		return postText;
	
	public void setPostText(String postText) 
		this.postText = postText;
	
	public String getPostImage() 
		return postImage;
	
	public void setPostImage(String postImage) 
		this.postImage = postImage;
	
	public String getPostTime() 
		return postTime;
	
	public void setPostTime(String postTime) 
		this.postTime = postTime;
	
	@Override
	public String toString() 
		return "Post [postId=" + postId + ", postUid=" + postUid + ", postTitle=" + postTitle + ", postText=" + postText
				+ ", postImage=" + postImage + ", postTime=" + postTime + "]";
	

在entity包下,创建评论实体comment,如下

public class Comment 
    private int commentId;
    private int commentPid;
    private String commentUid;
    private String commentText;
    private String commentTime;
	public Comment() 
		super();
	
	public Comment(int commentId, int commentPid, String commentUid, String commentText, String commentTime) 
		super();
		this.commentId = commentId;
		this.commentPid = commentPid;
		this.commentUid = commentUid;
		this.commentText = commentText;
		this.commentTime = commentTime;
	
	public int getCommentId() 
		return commentId;
	
	public void setCommentId(int commentId) 
		this.commentId = commentId;
	
	public int getCommentPid() 
		return commentPid;
	
	public void setCommentPid(int commentPid) 
		this.commentPid = commentPid;
	
	public String getCommentUid() 
		return commentUid;
	
	public void setCommentUid(String commentUid) 
		this.commentUid = commentUid;
	
	public String getCommentText() 
		return commentText;
	
	public void setCommentText(String commentText) 
		this.commentText = commentText;
	
	public String getCommentTime() 
		return commentTime;
	
	public void setCommentTime(String commentTime) 
		this.commentTime = commentTime;
	
	@Override
	public String toString() 
		return "Comment [commentId=" + commentId + ", commentPid=" + commentPid + ", commentUid=" + commentUid
				+ ", commentText=" + commentText + ", commentTime=" + commentTime + "]";
	

论坛管理实现

用户帖子管理

获取所有用户帖子信息并分页

在controller中创建forum包,并在forum包下创建DoPostSelect.java,代码如下

@WebServlet("/manage/admin_do_post_select")
public class DoPostSelect extends HttpServlet 
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException 
		// 当前页
		int currentPage = 1;
		// 每页显示条数
		int count = 5; 
		// array[0]=帖子总数,array[1]=总页数,后面会被覆盖
		int array[] =  0, 0 ;
		// 获取用户指定的页面
		String cp = request.getParameter("currentPage");
		// 接收用户搜索的关键字
		String keyword = request.getParameter("keywords"); 
		/* 用户如果有指定当前页,则把字符串转化为int型 */
		if (cp != null) 
			currentPage = Integer.parseInt(cp);
		
		ForumServiceImpl forumServiceImpl = new ForumServiceImpl();// 创建帖子service层接口的实现类
		/*
		 * 调用业务逻辑方法获取帖子记录总数并算出总页数 即(array[0]=帖子总数,array[1]=总页数(帖子总数/每页显示条数)
		 */
		try 
			array = forumServiceImpl.getPostPageTotal(count, keyword);
		 catch (SQLException e) 
			e.printStackTrace();
		
		ArrayList<Post> listPost = null;
		try 
			listPost = forumServiceImpl.getAllPost(currentPage, count, keyword);
		 catch (SQLException e) 
			e.printStackTrace();
		
		/*
		 * 遍历所有帖子,遍历过程中利用帖子id 调用业务逻辑方法获取帖子用户信息,并添加到list集合中
		 */
		User user = null;
		ArrayList<User> listUser = new ArrayList<User>();
		for (int i = 0; i < listPost.size(); i++) 
			try 
				user = forumServiceImpl.getPostUser(listPost.get(i).getPostUid());
			 catch (SQLException e) 
				e.printStackTrace();
			
			listUser.add(user);
		
		/* 放到请求对象域里 */
		request.setAttribute("listPost", listPost);
		request.setAttribute("listUser", listUser);
		request.setAttribute("totalStudent", array[0]);
		request.setAttribute("totalPage", array[1]);
		request.setAttribute("currentPage", currentPage);
		if (keyword != null) 
			request.setAttribute("searchParams", "&keywords=" + keyword);
		
		request.getRequestDispatcher("/WEB-INF/manage/admin_post.jsp").forward(request, response);
	

在service层中创建ForumService接口,并在接口中添加如下业务逻辑抽象方法

	// 获取所有帖子记录总数及页数
	public int[] getPostPageTotal(int count, String keyword) throws SQLException;
	
	// 获取所有帖子信息
	public ArrayList<Post> getAllPost(int currentPage, int count, String keyword) throws SQLException;
	
	// 获取帖子的用户信息
	public User getPostUser(String postUid) throws SQLException;

在service层中创建接口的实现类ForumServiceImpl.java,并在实现类中重写接口方法

	/* 创建帖子dao层接口的实现类,并赋给接口对象变量
	 * 实现上转型,也就面向接口编程,而不关心它的实现类是谁 */
	ForumDao forumDao = new ForumDaoImpl();
	/*
	 * 创建用户dao层接口的实现类,并赋给接口对象变量。
	 *  实现上转型,也就面向接口编程,而不关心它的实现类是谁
	 */
	UserDao userDao = new UserDaoImpl();
	@Override
	public int[] getPostPageTotal(int count, String keyword) throws SQLException 
		// 检索所有帖子总数并算出总页数
		int[] array = forumDao.selectPostTotal(count, keyword);
		return array;
	
	@Override
	public ArrayList<Post> getAllPost(int currentPage, int count, String keyword) throws SQLException 
		// 检索所有帖子信息
		ArrayList<Post> listPost = forumDao.selectAllPost(currentPage, count, keyword);
		return listPost;
	
	@Override
	public User getPostUser(String postUid) throws SQLException 
		// 检索用户信息
		User user = userDao.selectUser(postUid, "");
		return user;
	

这里需要说一下获取帖子用户信息的业务功能,它调用了检索用户信息dao层方法。

在前面的用户管理中已经在dao层的UserDao编写了检索用户的方法,在这里就可以直接用了,而不需要重复在dao层的ForumDao编写检索用户信息的方法了

但是呢,UserDaoImpl是需要一个身份标识的参数的,这里只需传入空值即可

在dao层中创建接口ForumDao.java,并在接口中添加如下抽象方法,执行底层操作

	// 检索所有帖子总数并算出总页数
	public int[] selectPostTotal(int count, String keyword) throws SQLException;

	// 检索所有帖子信息
	public ArrayList<Post> selectAllPost(int currentPage, int count, String keyword) throws SQLException;

在dao层中创建接口的实现类ForumDaoImpl.java,并在实现类中重写接口方法

// 存放查询数据库返回的结果集
	ResultSet resultSet;
	@Override
	public int[] selectPostTotal(int count, String keyword) throws SQLException 
		String sql = "";
		// 0 帖子记录数 1 页数
		System.out.println("keyword =" + keyword);
		int array[] =  0, 1 ;
		if (keyword != null) 
			sql = "select count(*) from post where  post_title like ?";
			resultSet = JDBCUtil.executeQuery(sql, "%" + keyword + "%");
		 else 
			sql = "select count(*) from post";
			resultSet = JDBCUtil.executeQuery(sql);
		
		while (resultSet.next()) 
			array[0] = resultSet.getInt(1);
			if (array[0] % count == 0) 
				array[1] = array[0] / count;
			 else 
				array[1] = array[0] / count + 1;
			
		
		return array;
	
	@Override
	public ArrayList<Post> selectAllPost(int currentPage, int count, String keyword) throws SQLException 
		ArrayList<Post> listPost = new ArrayList<Post>();
		String sql = "";
		if (keyword != null) 
			sql = "select * from post where post_title like ? order by post_time desc limit ?, ?";
			resultSet = JDBCUtil.executeQuery(sql, "%" + keyword + 查看详情  

基于项目和基于内容的协同过滤有啥区别?

】基于项目和基于内容的协同过滤有啥区别?【英文标题】:What\'sdifferencebetweenitem-basedandcontent-basedcollaborativefiltering?基于项目和基于内容的协同过滤有什么区别?【发布时间】:2013-04-2815:23:02【问题描述】:我对基于项目的推... 查看详情

基于磁盘的基于文档的存储

】基于磁盘的基于文档的存储【英文标题】:Diskbaseddocumentbasedstorage【发布时间】:2012-02-2509:34:17【问题描述】:网络上有免费的基于磁盘的高度可扩展的NoSQL存储系统吗?SQLServer的好处是它可以扩展,但是将我的项目迁移到SQL... 查看详情

依存句法分析:基于图的依存句法分析基于转移的依存句法分析基于神经网络的依存句法分析

依存句法分析:基于图的依存句法分析、基于转移的依存句法分析、基于神经网络的依存句法分析目录 查看详情

事件处理:基于功能的组件与基于类的组件

】事件处理:基于功能的组件与基于类的组件【英文标题】:Eventhandling:functionalbasedcomponentvsclassbasedcomponent【发布时间】:2019-07-1016:49:41【问题描述】:这是我的第一个React应用程序(react@16.8.1)。我试图找出为什么onClick事件在... 查看详情

显示基于文化的日期,但基于模式的时间

】显示基于文化的日期,但基于模式的时间【英文标题】:DisplayDatebasedonculturebutTimebasedonapattern【发布时间】:2010-06-0412:31:41【问题描述】:有人知道怎么显示吗基于CurrentCulture的日期时间的日期,但时间遵循此模式"HH:mm:ss.ff... 查看详情

基于角色与基于资源的权限访问控制

  基于角色的权限访问控制RBAC(role-basedaccesscontrol)是以角色为中心进行的访问控制,也就是判断主体subject是那个角色的方式进行权限访问控制,是粗粒度的  基于资源的权限访问控制RBAC(resource-basedaccesscontrol)是以资源... 查看详情

基于主机的容器与基于图像的容器

】基于主机的容器与基于图像的容器【英文标题】:Host-based-containersvsimage-based-containers【发布时间】:2014-12-2614:46:03【问题描述】:基于主机的linux容器和基于镜像的linux容器有什么区别?各自的优缺点是什么?如何决定哪种类... 查看详情

如何基于基于字符的 RNN 模型预测字符?

】如何基于基于字符的RNN模型预测字符?【英文标题】:howtopredictacharacterbasedoncharacterbasedRNNmodel?【发布时间】:2021-02-0513:00:08【问题描述】:我想创建一个预测函数来完成“句子”的一部分这里使用的模型是基于字符的RNN(LSTM)... 查看详情

基于stm32单片机项目设计目录-加油吧√

★♥基于STM32单片机项目设计目录√♥※目录★♥基于STM32单片机项目设计目录√♥※1、基于STM32的音乐喷泉2、STM32的智能浇水补光系统3、基于STM32的手机通过wifi控LED灯4、基于STM32的电子打铃器5、基于STM32的智能手环6、基于STM32... 查看详情

基于stm32单片机项目设计目录-加油吧√

★♥基于STM32单片机项目设计目录√♥※目录★♥基于STM32单片机项目设计目录√♥※1、基于STM32的音乐喷泉2、STM32的智能浇水补光系统3、基于STM32的手机通过wifi控LED灯4、基于STM32的电子打铃器5、基于STM32的智能手环6、基于STM32... 查看详情

基于角色的授权和基于角色的访问控制颤动

】基于角色的授权和基于角色的访问控制颤动【英文标题】:rolebasedauthorizationandrolebasedaccesscontrolflutter【发布时间】:2020-06-2207:24:55【问题描述】:我试图做的是设置一个基于角色的授权(普通用户和订阅用户),并基于角色用... 查看详情

混合身份验证 - 基于 Spring MVC 会话 + 基于 JWT 令牌

】混合身份验证-基于SpringMVC会话+基于JWT令牌【英文标题】:Hybridauthentication-SpringMVCsessionbased+JWTtokenbased【发布时间】:2020-02-0418:53:27【问题描述】:我有一个情况,我正在使用SpringMVC(jsp、控制器、服务、dao)和基于会话的身... 查看详情

基于类的视图 VS 基于函数的视图

】基于类的视图VS基于函数的视图【英文标题】:ClassBasedViewsVSFunctionBasedViews【发布时间】:2013-01-2503:22:11【问题描述】:在创建django应用程序时,我总是使用FBV(基于函数的视图),因为它非常易于处理。但是大多数开发人员... 查看详情

基于国家/地区的基于IP的内容[重复]

】基于国家/地区的基于IP的内容[重复]【英文标题】:ipbasedcontentbasedoncountry[duplicate]【发布时间】:2012-04-1516:50:23【问题描述】:可能重复:IPtoCountry?IPToCountryinPHP我有一个网站,当他们访问时,我存储了用户的IP地址。我想为他... 查看详情

基于原型与基于类的继承

】基于原型与基于类的继承【英文标题】:prototypebasedvs.classbasedinheritance【发布时间】:2010-10-2309:32:50【问题描述】:在JavaScript中,每个对象同时是一个实例和一个类。要进行继承,您可以使用任何对象实例作为原型。在Python、... 查看详情

活动菜单项不是基于 URL 而是基于变量

】活动菜单项不是基于URL而是基于变量【英文标题】:ActivemenuitemNOTbasedonURLbutbasedonavariable【发布时间】:2022-01-1522:01:42【问题描述】:我想在我的网站上有一个包含活动项目的菜单。应该添加一个类来激活该项目。由于该项目... 查看详情

从基于源的索引转换为基于目标的索引

】从基于源的索引转换为基于目标的索引【英文标题】:ConvertingfromSource-basedIndicestoDestination-basedIndices【发布时间】:2016-08-3123:35:07【问题描述】:我在一些C代码中使用AVX2指令。VPERMD指令采用两个8整数向量a和idx,并通过基于idx... 查看详情