SpringBoot+MyBatisplus搭建校园新闻平台——已开源

news2024/11/24 11:25:25

概述

开发背景

校园新闻平台是以新闻宣传机构的在线信息发布需求为基础,随着数字化和信息化的快速发展,校园新闻在校园内的传播和沟通中变得越来越重要。学校需要一个有效的管理系统来整合、发布和传播校园新闻,以满足师生、校友和其他利益相关者的信息需求。借助互联网技术开发的信息化平台。在这一平台之上,不仅可以看到与常规纸质报纸相同的信息,还有助于实现新闻信息的规范化管理,为读者和采编人员查询和阅读带来便利。从目前看,通过网络获取新闻信息的人群远远大于纸质媒介用户,而且两者之间的差距还在进一步扩大。
在学校网站上,校园新闻平台是最为重要的组成部分,其主要作用有两个:一.是动态发布校内新闻或者重大项目公示;二是向社会传递学校的办学思路、教学成果、科研进展等,使学校获得更高的知名度和社会认可度。因此,研究网络环境下的电子新闻媒体,开发校园新闻平台完备校园网的重要工作之一。首先对校园新闻平台工作的实际需求进行了分析,特别是对其业务需求做了详尽的分析;而后,对校园新闻平台做了总体设计,从系统结构、总体框架、数据库等方面进行了详细阐述。在数据库设计上,阐述了该系统的概念结构设计、逻辑结构设计,描述了主要库表。从功能需求结构来看,校园新闻平台主要包括新闻浏览,论坛讨论和新闻管理三大功能模块。总之,开发一个校园新闻管理系统可以满足学校信息传播的需求,提高信息发布效率,增强用户参与度和体验,促进校园文化交流,并提供数据支持进行进一步的分析和优化。这样的系统将为学校带来更好的信息管理和校园文化建设。

开发目标

对于用户

  • 用户可以浏览全部新闻
  • 用户可以按照不同类型进行查阅新闻
  • 用户可以登录/注册论坛
  • 用户可以在不同的板块下发帖
  • 用户可以在帖子后面追加评论
  • 用户可以修改自己的密码

对于管理员

  • 管理员可以对用户进行维护
  • 管理员可以删除不友好的帖子或评论
  • 管理员可以按照关键字来查询帖子或新闻
  • 写手可以发表新闻
  • 审核员可以审核自身以下等级的新闻并可以发表新闻
  • 总管理可以审核所有等级的新闻,可以发布新闻,管理用户,维护管理员,管理论坛,管理新闻

设计原则

  1. 单一职责原则(Single Responsibility Principle,SRP):一个类或模块应该只有一个责任。这样可以降低类的复杂性,提高代码的可读性和可维护性。
  2. 开放封闭原则(Open-Closed Principle,OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。通过使用抽象和接口,可以在不修改现有代码的情况下扩展系统功能。
  3. 里氏替换原则(Liskov Substitution Principle,LSP):子类型必须能够替换它们的父类型。这意味着子类应该与其父类具有相同的行为,并且可以无缝地替换父类的实例。
  4. 依赖倒置原则(Dependency Inversion Principle,DIP):高层模块不应该依赖于低层模块,它们应该依赖于抽象。通过引入抽象接口,可以降低模块之间的耦合度,提高系统的灵活性和可测试性。
  5. 接口隔离原则(Interface Segregation Principle,ISP):客户端不应该依赖它们不需要的接口。接口应该细化,以满足特定客户端的需求,避免接口过于臃肿和冗余。
  6. 迪米特法则(Law of Demeter,LoD):一个对象应该对其他对象有尽可能少的了解。模块之间应该通过最小的接口进行通信,降低耦合度。
  7. 高内聚低耦合原则:模块内的组件应该紧密相关,而不同模块之间的依赖应该尽量减少。这样可以提高代码的可维护性和可测试性。
  8. 面向对象设计原则:封装、继承和多态是面向对象设计的基本原则。合理应用这些原则可以提高代码的可重用性和灵活性。

数据库设计

1.用户表(user)

字段类型说明
idvarchar用户编号
passwordvarchar用户密码

2.管理员表(admin)

字段类类型说明
idvarchar管理员编号
passwordvarchar管理员密码
levelint管理员等级

注:管理员有四个身份:总管理,一级审核,二级审核,写手。每个身份登录可以看到不同的界面,在数据库的level中分别用1,2,3,4标识

3.学校新闻表(schoolnews)

字段类型说明
idint新闻编号
writervarchar写手编号
titlevarchar新闻标题
wordvarchar新闻内容
timedatetime创建时间
typevarchar新闻类型
emoint审核人编号
wlevelint写手等级

4.论坛表(news)

字段类型说明
idint编号
uservarchar发表人
titlevarchar题目
newsvarchar正文
typevarchar类型
timedatetime发表时间

5.评论表(log)

字段类型说明
idint评论编号
lzidint论坛问题编号
loguservarchar评论者编号
titlevarchar评论标题
logvarchar评论内容
timedatetime评论时间

项目开发

开发环境

开发工具:

  • IntelliJ IDEA 2022.3.3
  • apache-maven-3.6.3
  • apache-tomcat-9.0.69
  • jdk1.8
  • Lombok

技术栈:

  • Springboot
  • Spring-MVC
  • myBatis-Puls
  • thymeleaf

新建项目

1.新建项目

image-20230606095539889

2.添加依赖

image-20230606095718685

环境配置

1.配置application.yaml

#关闭模版引擎缓存
spring:
  thymeleaf:
    cache: false
  #配置文件的位置
  messages:
    basename: i18n.login
#以下为数据库mybatis配置
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/hello?useUnicode=true&characterEncoding=utf-8
    #    如果时区异常可以加入&severTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver
  mvc:
    format:
      date: yyyy-MM-dd
#mybatis配置
mybatis:
  type-aliases-package: com.asuka.hellospring.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

2.给pom.xml添加依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.21</version>
		</dependency>

		<!--thymeleaf-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.4.3</version>
		</dependency>

		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper-spring-boot-starter</artifactId>
			<version>1.4.3</version>
		</dependency>
<!--		热部署-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
		</dependency>

开发过程

新闻部份

1.创建实体(Schoolnews)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Schoolnews {
    int id;
    String writer;
    String title;
    String word;

    String type;
    int emo;
    int wlevel;

    @TableField(fill= FieldFill.INSERT)
    Date time;
}

2.配置mapper

@Mapper
public interface SchoolnewsMapper extends BaseMapper<Schoolnews> {
}

3.配置控制器

根据标签选择新闻(回显全部新闻)

——SnewsController

    @RequestMapping("/snews")
    public String newjud(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "7", value = "pageSize") Integer pageSize) {

        //实现倒序输出(校内新闻)
        QueryWrapper<Schoolnews> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("id");//倒序
        newsQueryWrapper.eq("emo", 3);
        newsQueryWrapper.eq("type", "校内新闻");

        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnews = schoolnewsMapper.selectList(newsQueryWrapper);
        model.addAttribute("sdutcmnews", schoolnews);


        //实现倒序输出(院系速递)
        QueryWrapper<Schoolnews> wrapperb = new QueryWrapper<>();
        wrapperb.orderByDesc("id");
        wrapperb.eq("emo", 3);
        wrapperb.eq("type", "院系速递");
        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnewsb = schoolnewsMapper.selectList(wrapperb);
        model.addAttribute("yuanxinews", schoolnewsb);


        //实现倒序输出(通知公告)
        QueryWrapper<Schoolnews> wrapperc = new QueryWrapper<>();
        wrapperc.orderByDesc("id");
        wrapperc.eq("emo", 3);
        wrapperc.eq("type", "通知公告");

        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnewsc = schoolnewsMapper.selectList(wrapperc);
        model.addAttribute("tongzhinews", schoolnewsc);

        //实现倒序输出(电子校报)
        QueryWrapper<Schoolnews> wrapperd = new QueryWrapper<>();
        wrapperd.orderByDesc("id");
        wrapperd.eq("emo", 3);
        wrapperd.eq("type", "电子校报");

        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnewsd = schoolnewsMapper.selectList(wrapperd);
        model.addAttribute("dianzinews", schoolnewsd);

        //实现倒序输出(媒体)
        QueryWrapper<Schoolnews> wrappere = new QueryWrapper<>();
        wrappere.orderByDesc("id");
        wrappere.eq("emo", 3);
        wrappere.eq("type", "媒体");

        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnewse = schoolnewsMapper.selectList(wrappere);
        model.addAttribute("meitinews", schoolnewse);
        return "/snews/index";
    }

点击查看具体新闻

——SnewsController

    @GetMapping("/indnewss/{id}")
    public String indpageshouw(@PathVariable("id") String id, Model model) {
        Schoolnews schoolnews = schoolnewsMapper.selectById(id);
        model.addAttribute("news", schoolnews);
        return "snews/newshows";
    }

查看某类全部新闻

——SnewsController

    @GetMapping("/newlis/{type}")
    public String newliss(@PathVariable("type") String type, Model model) {
        QueryWrapper<Schoolnews> new233 = new QueryWrapper<>();
        new233.eq("type", type);
        List<Schoolnews> schoolnews = schoolnewsMapper.selectList(new233);
        model.addAttribute("type", type);
        model.addAttribute("news", schoolnews);
        return "snews/newslists";
    }

论坛部分

创建实体

①.帖子(News)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class News {
    int id;
    String user;
    String title;
    String news;
    String type;

    @TableField(fill= FieldFill.INSERT)
    Date time;
}

②.用户(User)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    String id;
    String password;
}

③.评论(Log)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Log {
    int id;
    int lzid;
    String loguser;
    String title;
    String log;

    @TableField(fill= FieldFill.INSERT)
    Date time;
}

④.管理员(Admin)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Admin {
    String id;
    String password;
    int level;
}

配置mapper

@Mapper
public interface NewsMapper extends BaseMapper<News> {
}

@Mapper
public interface LogMapper extends BaseMapper<Log> {
}

@Mapper
public interface AdminMapper extends BaseMapper<Admin> {
}

@Mapper
public interface UserMapper extends BaseMapper<User> {

}

登录,注册,退出功能

——LoginController

用户或管理员登录

不同的角色跳转的页面不同——LoginController

 @RequestMapping("/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        Model model
                        ,HttpSession session
    ) {

        //登录实现
        User user = userMapper.selectById(username);
        if(username.equals("admin")&&password.equals("123")){//管理员登录
            session.setAttribute("loginUser", username);
            return "redirect:/userlist";
        }else {//普通用户登录
            if (user != null) {
                if (password.equals(user.getPassword())) {
                    session.setAttribute("loginUser", username);
                    //登录成功
                    return "redirect:/Main";
                } else {
                    model.addAttribute("msg", "密码错误");
                    return "loginl";
                }

            } else {
                model.addAttribute("msg", "用户不存在");
                return "loginl";
            }
        }

用户或管理员注册

    @RequestMapping("/rege")
    public String save (User user,Model model){
        //添加的操作
        User user233 = userMapper.selectById(user.getId());
        if (user.getId().equals("admin")) {
            model.addAttribute("msg", "不准注册管理员帐号");
            return "register";
        } else {
            if (user233 == null) {
                userMapper.insert(user); //调用底层业务保存用户
                model.addAttribute("msg", "注册成功,请返回登录");
                return "loginl";
            } else {

                model.addAttribute("msg", "用户已存在");
                return "register";

            }
        }

    }

用户或管理员登录

    @RequestMapping("/user/logout")
    public String logout(HttpSession session){
        session.invalidate();
        return "redirect:/login.html";
    }

用户功能

查看不同板块帖子

以综合板块和匿名板块为例,综合板块除了匿名板块包括日常,学习,围炉夜话和询问板块

——NewsController

 @RequestMapping("/zonghe")
    public String zonghe(Model model
            , @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum
            , @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        //实现按照时间倒序输出
        QueryWrapper<News> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("time");
        newsQueryWrapper.ne("type","匿名");
        //分页
        PageHelper.startPage(pageNum, pageSize);
        List<News> news = newsMapper.selectList(newsQueryWrapper);
        PageInfo<News> newsPageInfo = new PageInfo<>(news);
        model.addAttribute("news",news);
        model.addAttribute("pageInfo", newsPageInfo);
        return "News/zonghe";
    }

匿名板块

——NewsController

    @RequestMapping("/niming")
    public String niming(Model model
            , @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum
            , @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        //实现倒序输出
        QueryWrapper<News> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("time");
        newsQueryWrapper.eq("type","匿名");
        //分页
        PageHelper.startPage(pageNum, pageSize);
        List<News> news = newsMapper.selectList(newsQueryWrapper);
        PageInfo<News> newsPageInfo = new PageInfo<>(news);
        model.addAttribute("news",news);
        model.addAttribute("pageInfo", newsPageInfo);
        return "News/niming";
    }

查看帖子详情

——NewsController

    @GetMapping("/news/{id}")
    public String newsshouw(@PathVariable("id")String id,Model model){
        News newz = newsMapper.selectById(id);
        HashMap<String, Object> map = new HashMap<>();
        map.put("lzid",id);
        List<Log> logs = logMapper.selectByMap(map);
        model.addAttribute("logs",logs);
        model.addAttribute("news",newz);
        return "News/zshow";
    }

跟帖评论

——NewsController

    @RequestMapping("/newslog")
    public String logsub(Log log){
        if(log.getTitle().isEmpty() || log.getLog().isEmpty()){
            return "redirect:/news/"+log.getLzid();
        }else {
            logMapper.insert(log);
            return "redirect:/news/"+log.getLzid();
        }
    }

发布帖子

——NewsController

    @RequestMapping("/newssubmit")
    public String newssub(News news,Model model){
        System.out.println(news);
        if (news.getTitle().isEmpty()){
            model.addAttribute("msg","标题写点东西再发布!");
            return "fail";
        }else {

            newsMapper.insert(news);
            model.addAttribute("msg","发帖成功");
            return "succ";
        }
    }

用户改自己密码

——UserController

    @GetMapping("/useru/{id}")
    public String editu(@PathVariable("id")String id,Model model){
        //查出原先的数据
        User user = userMapper.selectById(id);
        model.addAttribute("user",user);
        return "user/editu";
    }

管理员功能

用户管理

1.查找用户

——UserController

    @RequestMapping("/quary")
    public String qula(String name,Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.like("id",name);
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectList(objectQueryWrapper);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        model.addAttribute("user",users);
        model.addAttribute("name",name);
        model.addAttribute("pageInfo", pageInfo);

        return "user/userlista";
    }

2.显示用户列表

——UserController

    @RequestMapping("/userlist")
    public String userlist(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){


        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectList(null);
        PageInfo<User> pageInfo = new PageInfo<>(users);

        model.addAttribute("user",users);
        model.addAttribute("pageInfo", pageInfo);

        return "user/userlist";
    }

3.维护用户信息

——UserController

    @GetMapping("/user/{id}")
    public String edit(@PathVariable("id")String id,Model model){//回显用户信息
        //查出原先的数据
        User user = userMapper.selectById(id);
        model.addAttribute("user",user);
        return "user/edit";
    }
    @PostMapping("/edituser")
    public String edit(User user){//修改信息
        userMapper.updateById(user);
        return "redirect:/userlist";
    }

4.删除用户

——UserController

    @GetMapping("/userdel/{id}")
    public String del(@PathVariable("id")String id){
        userMapper.deleteById(id);
        return "redirect:/userlist";
    }
帖子管理

1.查找帖子

——NewsController

    @RequestMapping("/quarynew")
    public String qula(String name,Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){

        QueryWrapper<News> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.like("title",name);

        PageHelper.startPage(pageNum, pageSize);
        List<News> news = newsMapper.selectList(objectQueryWrapper);
        PageInfo<News> pageInfo = new PageInfo<>(news);

        model.addAttribute("news",news);
        model.addAttribute("name",name);
        model.addAttribute("pageInfo", pageInfo);

        return "user/newsb";
    }

2.查看帖子列表

——NewsController

    @RequestMapping("/newsa")
    public String newsa(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<News> news = newsMapper.selectList(null);
        PageInfo<News> pageInfo = new PageInfo<>(news);

        model.addAttribute("news",news);
        model.addAttribute("pageInfo", pageInfo);
        return "user/newsa";
    }

3.查看具体帖子以及评论

——NewsController

    @GetMapping("/newsa/{id}")
    public String newsashow(@PathVariable("id")String id,Model model){
        News newz = newsMapper.selectById(id);
        HashMap<String, Object> map = new HashMap<>();
        map.put("lzid",id);
        List<Log> logs = logMapper.selectByMap(map);
        model.addAttribute("logs",logs);
        model.addAttribute("news",newz);
        return "user/newsashow";
    }

4.删除帖子

——NewsController

    @GetMapping("/newsadel/{id}")
    public String del(@PathVariable("id")String id){
        newsMapper.deleteById(id);
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("lzid",id);
        logMapper.deleteByMap(objectObjectHashMap);
        return "redirect:/newsa";
    }

后台管理部分

管理员有四个身份:总管理,一级审核,二级审核,写手。每个身份登录可以看到不同的界面。

审核部分

1.提交新闻

总管理,一级审核,二级审核,写手都可以发布新闻

——SchoolnewsController

    @RequestMapping("/snewspost")
    public String snewpost(Schoolnews schoolnews,Model model){
        if(schoolnews.getTitle().isEmpty() || schoolnews.getWord().isEmpty()){
            model.addAttribute("msg","请保证标题或内容不为空。");
            return "admin/postnew";
        }else {
            schoolnewsMapper.insert(schoolnews);
            model.addAttribute("msg","发布成功,您的投稿已进入审核队列。");
            return "admin/postnew";
        }
    }

2.一级审核

只能审核写手写的新闻

——SchoolnewsController

 @RequestMapping("/newjud")
    public String newjud(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        QueryWrapper<Schoolnews> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("id"); 
        newsQueryWrapper.gt("wlevel",3);//大于
        newsQueryWrapper.eq("emo",1);
        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnews = schoolnewsMapper.selectList(newsQueryWrapper);
        PageInfo<Schoolnews> pageInfo = new PageInfo<>(schoolnews);
        model.addAttribute("news",schoolnews);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/juda";
    }

3.二级审核

能审核写手和一级审核写的新闻

——SchoolnewsController

    @RequestMapping("/newjudb")
    public String newjudb(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        //实现倒序输出
        QueryWrapper<Schoolnews> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("id");
        //选择等级为2的
        newsQueryWrapper.gt("wlevel",2);
        newsQueryWrapper.eq("emo",1);
        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnews = schoolnewsMapper.selectList(newsQueryWrapper);
        PageInfo<Schoolnews> pageInfo = new PageInfo<>(schoolnews);
        model.addAttribute("news",schoolnews);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/judb";
    }

4.三级审核

能审核所有人写的新闻

——SchoolnewsController

    @RequestMapping("/newjudd")
    public String newjudc(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        //实现倒序输出
        QueryWrapper<Schoolnews> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("id");
        //选择等级为2的
        newsQueryWrapper.gt("wlevel",1);
        newsQueryWrapper.eq("emo",1);
        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnews = schoolnewsMapper.selectList(newsQueryWrapper);
        PageInfo<Schoolnews> pageInfo = new PageInfo<>(schoolnews);
        model.addAttribute("news",schoolnews);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/judd";
    }

管理部分

管理员

显示管理员列表

——AdminController

    @RequestMapping("/adlist")
    public String adlist(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<Admin> users = adminMapper.selectList(null);
        PageInfo<Admin> pageInfo = new PageInfo<>(users);
        model.addAttribute("user",users);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/adlist";
    }

添加管理员

——AdminController

    //前往增加管理员页面 
    @RequestMapping("/addad")
    public String savead(){
        return "admin/addadmin";
    }
    //接收添加管理员请求
    @PostMapping("/addad")
    public String save (Admin admin,Model model){
        //添加的操作
        Admin ad233 = adminMapper.selectById(admin.getId());
        if (ad233 != null){
            model.addAttribute("msg","该昵称已存在");
            return "admin/addadmin";
        }else {
            if (admin.getId().isEmpty() || admin.getPassword().isEmpty()){
                model.addAttribute("msg","昵称和密码不为空");
                return "admin/addadmin";
            }else {

                System.out.println("save-->"+admin);
                adminMapper.insert(admin); //调用底层业务保存员工信息
                return "redirect:/adlist";
            }
        }

    }

维护管理员

——AdminController

    //修改管理员时填的默认值(数据回显) 跳往admin/editad.html
    @GetMapping("/aded/{id}")
    public String edit(@PathVariable("id") String id, Model model){
        //先查出原来的数据
        Admin admin = adminMapper.selectById(id);
        model.addAttribute("user",admin);
        return "admin/editad";
    }
    
    @PostMapping("/edad")
    public String edit(Admin admin){
        adminMapper.updateById(admin);
        return "redirect:/adlist";
    }

删除管理员

——AdminController

    @GetMapping("/delad/{id}")
    public String del(@PathVariable("id")String id){
        adminMapper.deleteById(id);
        return "redirect:/adlist";
    }
论坛

显示论坛列表

——AdminController

    @RequestMapping("/newslist")
    public String newsa(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){
        PageHelper.startPage(pageNum, pageSize);
        List<News> news = newsMapper.selectList(null);
        PageInfo<News> pageInfo = new PageInfo<>(news);
        model.addAttribute("news",news);
        model.addAttribute("pageInfo", pageInfo);

        return "admin/newslist";
    }

查看具体帖子

——AdminController

    @GetMapping("/newslist/{id}")
    public String newsashow(@PathVariable("id")String id, Model model){
        News newz = newsMapper.selectById(id);
        HashMap<String, Object> map = new HashMap<>();
        map.put("lzid",id);
        List<Log> logs = logMapper.selectByMap(map);
        model.addAttribute("logs",logs);
        model.addAttribute("news",newz);
        return "admin/adnewsshow";
    }

删除帖子

——AdminController

    @GetMapping("/newsqdel/{id}")
    public String delnews(@PathVariable("id")String id){
        newsMapper.deleteById(id);
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("lzid",id);
        logMapper.deleteByMap(objectObjectHashMap);
        return "redirect:/newslist";
    }
全部新闻

查看新闻列表

——SchoolnewsController

    @RequestMapping("/listed")
    public String judlists(Model model, @RequestParam(defaultValue = "1", value = "pageNum") Integer pageNum, @RequestParam(defaultValue = "10", value = "pageSize") Integer pageSize){

        //实现倒序输出
        QueryWrapper<Schoolnews> newsQueryWrapper = new QueryWrapper<>();
        newsQueryWrapper.orderByDesc("id");
        //选择等级为3的
        newsQueryWrapper.ge("emo",1);//大于等于
        PageHelper.startPage(pageNum, pageSize);
        List<Schoolnews> schoolnews = schoolnewsMapper.selectList(newsQueryWrapper);
        PageInfo<Schoolnews> pageInfo = new PageInfo<>(schoolnews);
        model.addAttribute("news",schoolnews);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/judc";
    }

查看具体新闻

——SchoolnewsController

    @GetMapping("/pageshowc/{id}")
    public String pageshouwc(@PathVariable("id")String id, Model model){
        Schoolnews schoolnews = schoolnewsMapper.selectById(id);
        model.addAttribute("news",schoolnews);
        return "admin/pageshowjudc";
    }

删除新闻

——SchoolnewsController

    @GetMapping("/delsnews/{id}")
    public String nessdel(@PathVariable("id")String id){
        schoolnewsMapper.deleteById(id);
        return "redirect:/admin";
    }

关键技术总结

一.Spring Boot集成Thymeleaf模板引擎

Thymeleaf 介绍

Thymeleaf 是适用于 Web 和独立环境的现代服务器端 Java 模板引擎。Thymeleaf 的主要目标是为您的开发工作流程带来优雅的自然模板 - 可以在浏览器中正确显示的HTML,也可以用作静态原型,从而在开发团队中实现更强大的协作。

Thymeleaf 使用

1.导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2.在 html 页面上如果要使用 thymeleaf 模板

<html xmlns:th="http://www.thymeleaf.org">

3.thymeleaf 相关配置

因为 Thymeleaf 中已经有默认的配置了,我们不需要再对其做过多的配置,有一个需要注意一下,Thymeleaf 默认是开启页面缓存的,所以在开发的时候,需要关闭这个页面缓存,配置如下。

spring:
  thymeleaf:
    cache: false #关闭缓存

4.在 thymeleaf 模板中,使用 th:object="${}" 来获取对象信息,然后在表单里面可以有三种方式来获取对象属性。

使用 th:value="*{属性名}"
使用 th:value="${对象.属性名}",对象指的是上面使用 th:object 获取的对象
使用 th:value="${对象.get方法}",对象指的是上面使用 th:object 获取的对象

5.thymeleaf 处理list

@GetMapping("/getList")
public String getList(Model model) {
    Blogger blogger1 = new Blogger(1L, "好富帅", "123456");
    Blogger blogger2 = new Blogger(2L, "达人课", "123456");
    List<Blogger> list = new ArrayList<>();
    list.add(blogger1);
    list.add(blogger2);
    model.addAttribute("list", list);
    return "list";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>博主信息</title>
</head>
<body>
<form action="" th:each="blogger : ${list}" >
    用户编号:<input name="id" th:value="${blogger.id}"/><br>
    用户姓名:<input type="text" name="password" th:value="${blogger.name}"/><br>
    登录密码:<input type="text" name="username" th:value="${blogger.getPass()}"/>
</form>
</body>
</html>

可以看出,其实和处理单个对象信息差不多,Thymeleaf 使用 th:each 进行遍历,${} 取 model 中传过来的参数,然后自定义 list 中取出来的每个对象,这里定义为 blogger。表单里面可以直接使用 ${对象.属性名} 来获取 list 中对象的属性值,也可以使用 ${对象.get方法} 来获取,这点和上面处理对象信息是一样的,但是不能使用 *{属性名} 来获取对象中的属性,thymeleaf 模板获取不到。

二.MybatisPlus

简介

概述:

MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

MybatisPlus特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

使用

1.创建数据库并创建对应的实体类

2.导入依赖

<dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <!--MybatisPlus-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

3.配置配置文件

  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/hello?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver

spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/hello?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

4.建立mapper并在主启动类上添加包扫描注解

@Mapper
public interface UserMapper extends BaseMapper<User> {

}

5.配置日志输出

#配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

条件构造器Wrapper方法

  • gt:大于,ge:大于等于,lt:小于,le:小于等于
  • eq:等于,ne:不等于
  • between:在值1和值2之间,notBetween:不在值1和值2之间
  • like:’%值%’,notLike:’%值%’,likeLeft:’%值’,likeRight:‘值%’
  • isNull:字段 IS NULL,isNotNull:字段 IS NOT NULL
  • in:字段 IN (v0, v1, …),notIn:字段 NOT IN (value.get(0), value.get(1), …)
  • 主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
  • orderByAsc:升序:ORDER BY 字段, … ASC,orderByDesc:降序:ORDER BY 字段, … DESC
  • inSql:字段 IN ( sql语句 ),notInSql:字段 NOT IN ( sql语句 )
  • exists:拼接 EXISTS ( sql语句 ),notExists:拼接 NOT EXISTS ( sql语句 )

使用代码生成器

代码生成器简介

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

代码生成器配置

添加依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.0</version>
</dependency>

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>

编写配置

public class CodeGenerator {


    public static void main(String[] args) {
        //创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        //全局配置
        GlobalConfig gc = new GlobalConfig();
        //获取当前系统目录
        String projectPath = System.getProperty("user.dir");
        
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("dong");  //生成作者注释
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖
        gc.setServiceName("%sService"); //去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(false);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/mp?serverTimezone=GMT%2B8");  //url
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");  //数据库驱动
        dsc.setUsername("root");  //数据库账号
        dsc.setPassword("root");  //数据库密码
        dsc.setDbType(DbType.MYSQL);  //数据库类型
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("test"); //模块名,可以不设置
        pc.setParent("cn.dong");  //放在哪个包下
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("employee");//对哪一张表生成代码
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setLogicDeleteFieldName("deleted"); //逻辑删除字段设置

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
        mpg.setStrategy(strategy);

        //执行
        mpg.execute();

    }
}

页面展示

项目首页

image-20230605212729213

新闻页面

新闻主页

image-20230605212855426

新闻页面

image-20230605215117723

查看所有新闻

image-20230605215204969

论坛页面

论坛登录

image-20230605215518012

论坛注册

image-20230605215555453

论坛主页(用户登录)

image-20230605215650590

查看论坛

image-20230605215743006

发表问题

image-20230605220415211

追加评论

image-20230605220457928

用户自行修改密码

image-20230605215825152

论坛主页(管理员登录)

image-20230605221437129

新闻管理

image-20230605221628864

后台页面

后台管理登录

image-20230605221728184

写手页面

image-20230605221825227

一级审核

image-20230605222248233

二级审核

image-20230605222332608

总管理

image-20230605223024252

管理员列表

image-20230605223055965

维护管理员

image-20230605223123239

论坛维护

image-20230605223235496

已发布主页新闻维护页面

image-20230605223342105

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/616914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我对测试行业发展和自我价值诉求的思考

测试圈子生态的思考 其实测试的生态&#xff0c;说起来蛮简单的&#xff0c;一个词语概括就是两极分化。有个梗&#xff1a;hand hands&#xff0c;load loads&#xff0c;太贴切了。 两极分化这个词&#xff0c;可以从下面三个维度来看&#xff1a; 薪资 我认识的测试也算不少…

搜索插入位置 力扣 Python

题目描述&#xff1a; 解题代码&#xff1a; class Solution:def searchInsert(self, nums: List[int], target: int) -> int:if target in nums:return nums.index(target)else:nums.append(target)nums.sort()return nums.index(target)题目分析&#xff1a; 时间复杂度…

0804空间直线及其方程-向量代数与空间解析几何

文章目录 1 空间直线方程1.1 空间直线的一般方程1.2 空间直线的对称式方程1.3 空间直线的参数方程1.4 空间直线的两点式方程 3 两直线的夹角4 直线与平面的夹角4.1 定义4.2 夹角的正弦公式 5 例题6 平面束方程结语 1 空间直线方程 1.1 空间直线的一般方程 空间直线L可以看做是…

【3DsMAX】从零开始建房(4)

目录 1. 制作二层主体 2. 制作二楼顶层栏杆 1. 制作二层主体 将二层的长方体转换为可编辑多边形&#xff0c;将左半部分的点向左移动一点距离 选中左右边线进行连接 移动连接线 选中如下的面挤出 选中一条边线&#xff0c;再点击环形 再点击连接 挤出 选中如下一条边线向上移…

【Windows安装】Windows详细安装nginx部署教程

1、先下载直接去官网nginx.org 点击后就会下载&#xff0c;下载完成后开始安装&#xff0c;其实官网已经告诉了如何安装&#xff0c;右侧“documentation -> nginx windows”就有详细的说明&#xff0c;只是英文而已 2、下载完成后&#xff0c;解压缩&#xff0c;运行cmd&a…

【网络工程师必备知识点】从头认识IPv6!

1. IPv6 的背景 IPv4 地址空间已经消耗殆尽&#xff0c;近乎无限的地址空间是 IPv6 的最大优势 2. IPv6 基本报头 在 IPv4 的基础上增加了流标签&#xff0c;去掉了一些冗余字段&#xff0c;使报文头部的处理更 为简单、高效 3. IPv6 扩展报头 是跟在 IPv6 基本报头后面的可…

自定义类型作为map或者unordered_map的key需要额外做哪些事情

文章目录 1、自定义类型作为map的key2、自定义类型作为unordered_map的key 1、自定义类型作为map的key map中有4个参数&#xff0c;前两个参数是key和val的类型&#xff0c;第三个参数表示比较的仿函数&#xff0c;用于对键值进行比较&#xff0c;默认情况下采用less<Key>…

Shell脚本攻略:shell实现pxe无人值守安装

目录 一、实验 1.shell实现pxe无人值守安装 一、实验 1.shell实现pxe无人值守安装 &#xff08;1&#xff09;脚本截图 1 echo set nu > ~/.vimrc2 systemctl stop firewalld3 setenforce 04 umount /dev/sr0 /mnt5 mount /dev/sr0 /mnt6 cd /etc/yum.repos.d/7 mkdir b…

汇编学习教程:bp 寄存器

引言 我们在此前的学习中已经了解了CPU中众多的寄存器&#xff0c;比如通用寄存器 AX、BX、CX、DX&#xff0c;还有段寄存器 CS、DS、SS、ES。在内存访问和灵活寻址的学习中&#xff0c;我们重点学习了 BX 寄存器和 CX 寄存器。BX 寄存器通常配合 DS段寄存器来实现内存访问&am…

做完瑞吉外卖项目的一点笔记和源码

源码在 https://gitee.com/pluto8/take-out 一、软件开发整体介绍 1、软件开发流程 需求分析 &#xff1a;产品原型&#xff0c;需求规格说明书&#xff08;文档形式&#xff09;设计&#xff1a;产品文档、UI界面设计、概要设计、详细设计、数据库设计编码&#xff1a;项目…

STM32 实现简单定时任务调度器,支持动态添加临时任务

代码实现和硬件没关系&#xff0c;所以并不限于STM32&#xff0c;Arduino 之类的其他地方也能用&#xff0c;只要有一个能获取时间的函数就行&#xff0c;或者说&#xff0c;只要有一个会随着时间自动增加的变量就行&#xff0c;时间单位无所谓&#xff0c;所以确实想的话&…

菜单权限验证和分页功能

权限验证 1.创建数据库&#xff0c;然后测试菜单权限的联合查询语句&#xff1b; 2.创建项目&#xff0c;导入jar包&#xff0c;配置实体类和工具类 3.完成登录功能&#xff0c;当输入用户名和密码正确后跳转到框架页面 编写导航页&#xff08;top.jsp&#xff09;和内容页…

Vscode +Msys2配置C/C++环境

目录 前期准备&#xff1a;Step1: 安装Msys2Step2: 安装编译器Step3: 安装VScodeStep4: 配置VScodec_cpp_properties.jsonlaunch.jsontasks.json Step5: 创建C/C项目 前期准备&#xff1a; 首先&#xff0c;你需要下载并安装以下软件&#xff1a; VsCode&#xff1a;https://c…

软件需求分析-复习指南

这里写自定义目录标题 下面是一段用例的描述&#xff0c;针对一个汽车保险系统中“将一辆新车加入一个已有保单中”的用例。请你为其设计&#xff1a; (1) 领域模型&#xff08;要求给出建立过程&#xff09;(20分)&#xff1b; (2) 活动图 (14分)&#xff1b; (3) 顺序图 (14分…

linux内核open文件流程

打开文件流程 本文基本Linux5.15 当应用层通过open api打开一个文件&#xff0c;内核中究竟如何处理&#xff1f; 本身用来描述内核中对应open 系统调用的处理流程。 数据结构 fdtable 一个进程可以打开很多文件&#xff0c; 内核用fdtable来管理这些文件。 include/linu…

为项目添加 HibernateValidator

HibernateValidatorhttps://hibernate.org/validator/ 引入依赖项 首先&#xff0c;确保已将Hibernate Validator添加到Maven或Gradle依赖项中&#xff1a; <!-- Maven 依赖 --> <dependency><groupId>org.hibernate.validator</groupId><artifa…

三年功能测试经验,投了几百份简历,为什么没有收到offer?

软件测试行业3年多经验&#xff0c;学历大专自考本科&#xff0c;主要测试方向web&#xff0c;PC端&#xff0c;wap站&#xff0c;小程序公众号都测试过&#xff0c;app也测过一些&#xff0c;C端B端都有&#xff0c;除功能外&#xff0c;接口性能也有涉猎&#xff0c;但是不能…

kafka--多易杰哥讲解

Kafka是一种分布式的流式数据平台&#xff0c;广泛应用于实时流数据处理和消息系统。它可以让处理数据的应用程序能够处理高流量的数据流&#xff0c;同时提供可靠性和可扩展性。 【多易教育】-Kafka文档 1.基本概念 1.1什么是kafka Kafka 最初是由 LinkedIn 即领英公司…

教你如何用fiddler抓取https(详细教程)

对于想抓取HTTPS的测试初学者来说&#xff0c;常用的工具就是fiddler&#xff0c;可是在初学时&#xff0c;大家对于fiddler如何抓取HTTPS真是伤了脑筋&#xff0c;可能你一步步按着网上的帖子成功了&#xff0c;那当然是极好的&#xff0c;有可能没有成功&#xff0c;这时候你…

前端基础(JavaScript)——基础语法(变量,分支...) Json对象【重要】 函数定义 事件(未完待续)

目录 引出JS是啥&#xff0c;能干啥基础语法1.变量----let2.怎么打印---console3.if条件分支--啥都可以是条件例子&#xff1a;输入框&#xff0c;打印输入和未输入4.数组push 和 splice&#xff08;2&#xff09;splice&#xff0c;3个参数&#xff0c;索引开始、删除几个&…