欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【个人实习日志】Springboot新闻管理系统(一)

程序员文章站 2022-05-05 15:16:56
...

Springboot实现自动生成数据库表、登录注销以及分类展示

Springboot项目创建
一、自动生成数据库表
Springboot 之 Hibernate自动建表(Mysql)
先引入Maven依赖包,起作用的是如下两个:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

创建配置文件application.yml

server:
  port: 8082
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/tnews?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
   //自动创建数据库表
  jpa:
      hibernate:
        ddl-auto: update
      show-sql: true//在控制台显示sql语句

本次项目po包中主要有五个实体类:
1、 在主建Id上需要加注释:@Id和@GeneratedValue(strategy = GenerationType.AUTO)才会自动增长
2、 在需要重新设置表字段名的属性上加注释@Column(name = “字段名”)即可。
3、 在类名上添加注释:@Entity和@Table(name = “t_user”),t_user是表名
Comment.java

package com.wzx.po;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Entity
@Table(name = "t_comment")
public class Comment {

    @Id
    @GeneratedValue
    private Long id;
    private String nickname;
    private String email;
    private String content;
    private String avatar;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    @ManyToOne
    private News news;

    @OneToMany(mappedBy = "parentComment")
    private List<Comment> replyComments = new ArrayList<>();

    @ManyToOne
    private Comment parentComment;

    private boolean adminComment;

    public Comment() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }



    public List<Comment> getReplyComments() {
        return replyComments;
    }

    public void setReplyComments(List<Comment> replyComments) {
        this.replyComments = replyComments;
    }

    public Comment getParentComment() {
        return parentComment;
    }

    public void setParentComment(Comment parentComment) {
        this.parentComment = parentComment;
    }

    public boolean isAdminComment() {
        return adminComment;
    }

    public void setAdminComment(boolean adminComment) {
        this.adminComment = adminComment;
    }

    public News getNews() {
        return news;
    }

    public void setNews(News news) {
        this.news = news;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", nickname='" + nickname + '\'' +
                ", email='" + email + '\'' +
                ", content='" + content + '\'' +
                ", avatar='" + avatar + '\'' +
                ", createTime=" + createTime +
                ", news=" + news +
                ", replyComments=" + replyComments +
                ", parentComment=" + parentComment +
                ", adminComment=" + adminComment +
                '}';
    }
}

News.java

package com.wzx.po;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Entity
@Table(name = "t_News")
public class News {

    @Id
    @GeneratedValue
    private Long id;

    private String title;

    @Basic(fetch = FetchType.LAZY)
    @Lob
    private String content;
    private String firstPicture;
    private String flag;
    private Integer views;
    private boolean appreciation;
    private boolean shareStatement;
    private boolean commentabled;
    private boolean published;
    private boolean recommend;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;

    @ManyToOne
    private Type type;

    @ManyToMany(cascade = {CascadeType.PERSIST})
    private List<Tag> tags = new ArrayList<>();


    @ManyToOne
    private User user;

    @OneToMany(mappedBy = "news")
    private List<Comment> comments = new ArrayList<>();

    @Transient
    private String tagIds;

    private String description;

    public News() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getFirstPicture() {
        return firstPicture;
    }

    public void setFirstPicture(String firstPicture) {
        this.firstPicture = firstPicture;
    }

    public String getFlag() {
        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }

    public Integer getViews() {
        return views;
    }

    public void setViews(Integer views) {
        this.views = views;
    }

    public boolean isAppreciation() {
        return appreciation;
    }

    public void setAppreciation(boolean appreciation) {
        this.appreciation = appreciation;
    }

    public boolean isShareStatement() {
        return shareStatement;
    }

    public void setShareStatement(boolean shareStatement) {
        this.shareStatement = shareStatement;
    }

    public boolean isCommentabled() {
        return commentabled;
    }

    public void setCommentabled(boolean commentabled) {
        this.commentabled = commentabled;
    }

    public boolean isPublished() {
        return published;
    }

    public void setPublished(boolean published) {
        this.published = published;
    }

    public boolean isRecommend() {
        return recommend;
    }

    public void setRecommend(boolean recommend) {
        this.recommend = recommend;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }


    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }


    public List<Comment> getComments() {
        return comments;
    }

    public void setComments(List<Comment> comments) {
        this.comments = comments;
    }


    public String getTagIds() {
        return tagIds;
    }

    public void setTagIds(String tagIds) {
        this.tagIds = tagIds;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void init() {
        this.tagIds = tagsToIds(this.getTags());
    }

    //1,2,3
    private String tagsToIds(List<Tag> tags) {
        if (!tags.isEmpty()) {
            StringBuffer ids = new StringBuffer();
            boolean flag = false;
            for (Tag tag : tags) {
                if (flag) {
                    ids.append(",");
                } else {
                    flag = true;
                }
                ids.append(tag.getId());
            }
            return ids.toString();
        } else {
            return tagIds;
        }
    }


    @Override
    public String toString() {
        return "News{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", firstPicture='" + firstPicture + '\'' +
                ", flag='" + flag + '\'' +
                ", views=" + views +
                ", appreciation=" + appreciation +
                ", shareStatement=" + shareStatement +
                ", commentabled=" + commentabled +
                ", published=" + published +
                ", recommend=" + recommend +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                ", type=" + type +
                ", tags=" + tags +
                ", user=" + user +
                ", comments=" + comments +
                ", tagIds='" + tagIds + '\'' +
                ", description='" + description + '\'' +
                '}';
    }

    public void initTags(Long id) {
        //3,4,5
        List<Tag> tags = this.getTags();
        StringBuffer ids=new StringBuffer();
        if(!tags.isEmpty()){
            Boolean flag=false;
            for(Tag t:tags){
                if(flag){
                    ids.append(t.getId());
                    flag=true;
                }else {
                    ids.append(",");
                    ids.append(t.getId());
                }

            }
            this.setTagIds(ids.toString());
        }

    }
}

Tag.java

package com.wzx.po;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;


@Entity
@Table(name = "t_tag")
public class Tag {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @ManyToMany(mappedBy = "tags")
    private List<News> newsList = new ArrayList<>();

    public Tag() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<News> getNewsList() {
        return newsList;
    }

    public void setNewsList(List<News> newsList) {
        this.newsList = newsList;
    }

    @Override
    public String toString() {
        return "Tag{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Type.java

package com.wzx.po;


import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;


@Entity
@Table(name = "t_type")
public class Type {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "type")
    private List<News> newsList = new ArrayList<>();

    public Type() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<News> getNewsList() {
        return newsList;
    }

    public void setNewsList(List<News> newsList) {
        this.newsList = newsList;
    }

    @Override
    public String toString() {
        return "Type{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

User.java

package com.wzx.po;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Entity
@Table(name = "t_user")
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String nickname;
    private String username;
    private String password;
    private String email;
    private String avatar;
    private Integer type;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;

    @OneToMany(mappedBy = "user")
    private List<News> newsList = new ArrayList<>();

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }


    public List<News> getNewsList() {
        return newsList;
    }

    public void setNewsList(List<News> newsList) {
        this.newsList = newsList;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", nickname='" + nickname + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                ", avatar='" + avatar + '\'' +
                ", type=" + type +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                '}';
    }
}

启动项目后在tnews数据库中将出现数据表,且存在相应的表字段。
【个人实习日志】Springboot新闻管理系统(一)
Springboot中先在实体类中建立与存储过程的联系,dao层调用存储过程,控制层调用dao层方法,dao层继承JpaRepository类实现简单的对数据库的操作。

二、登录注销功能
Springboot项目与SSM项目类似,只不过Springboot中的一些sql操作不用自己实现
(一)UserDao.java

package com.wzx.dao;

import com.wzx.po.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserDao extends JpaRepository<User,Long> {
    User findByUsernameAndPassword(String username, String password);
}

(二)UserService.java

package com.wzx.service;

import com.wzx.po.User;
import org.springframework.stereotype.Service;

public interface UserService {
    User CheckUser(String username, String password);
}

UserServiceImpl.java

package com.wzx.service.impl;

import com.wzx.dao.UserDao;
import com.wzx.po.User;
import com.wzx.service.UserService;
import com.wzx.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public User CheckUser(String username, String password) {
        return userDao.findByUsernameAndPassword(username, MD5Util.code(password));
    }
}

(三)LoginController.java

package com.wzx.controller;

import com.wzx.po.User;
import com.wzx.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("admin")
public class LoginController {
    @Autowired
    private  UserService userService;

   @GetMapping
    public String toLogin(){
        return "admin/login";
    }

    @PostMapping("login")
    public String login(String username, String password, HttpSession session, RedirectAttributes redirectAttributes){
        User user=userService.CheckUser(username,password);
                if(user!=null){
                    session.setAttribute("user",user);
                    return "admin/index";
                }else {
                    redirectAttributes.addFlashAttribute("message","用户名和密码错误1");
                    return "redirect:/admin";
                }
    }

    @GetMapping("logout")
    public String logout(HttpSession session){
        session.removeAttribute("user");
        return "admin/login";

    }
}

(四)login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head th:replace="admin/_fragments :: head(~{::title})">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>新闻管理登录</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
  <link rel="stylesheet" href="../../static/css/me.css">
</head>
<body>

<br>
<br>
<br>
 <div class="m-container-small m-padded-tb-massive" style="max-width: 30em !important;">
   <div class="ur container">
     <div class="ui middle aligned center aligned grid">
       <div class="column">
         <h2 class="ui teal image header">
           <div class="content">
             管理后台登录
           </div>
         </h2>
         <form class="ui large form" method="post" action="#" th:action="@{/admin/login}" >
           <div class="ui  segment">
             <div class="field">
               <div class="ui left icon input">
                 <i class="user icon"></i>
                 <input type="text" name="username" placeholder="用户名">
               </div>
             </div>
             <div class="field">
               <div class="ui left icon input">
                 <i class="lock icon"></i>
                 <input type="password" name="password" placeholder="密码">
               </div>
             </div>
             <button class="ui fluid large teal submit button">登   录</button>
           </div>

           <div class="ui error mini message"></div>
           <div class="ui mini negative message" th:unless="${#strings.isEmpty(message)}" th:text="${message}">用户名密码错误</div>

         </form>

       </div>
     </div>
   </div>
 </div>

<th:block th:fragment="script">
  <script src="https://cdn.jsdelivr.net/npm/aaa@qq.com/dist/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script>
  <script src="../../static/lib/editormd/editormd.min.js" th:src="@{/lib/editormd/editormd.min.js}"></script>
</th:block>

<script>
  $('.ui.form').form({
    fields : {
      username : {
        identifier: 'username',
        rules: [{
          type : 'empty',
          prompt: '请输入用户名'
        }]
      },
      password : {
        identifier: 'password',
        rules: [{
          type : 'empty',
          prompt: '请输入密码'
        }]
      }
    }
  });
</script>

</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head th:replace="admin/_fragments :: head(~{::title})">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>新闻管理</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
  <link rel="stylesheet" href="../../static/css/me.css">
</head>
<body>

  <!--导航-->
  <nav th:replace="admin/_fragments :: menu(0)" class="ui inverted attached segment m-padded-tb-mini m-shadow-small" >
    <div class="ui container">
      <div class="ui inverted secondary stackable menu">
        <h2 class="ui teal header item">管理后台</h2>
        <a href="#" class="active m-item item m-mobile-hide">新闻</a>
        <a href="#" class=" m-item item m-mobile-hide">分类</a>
        <a href="#" class="m-item item m-mobile-hide">标签</a>
        <div class="right m-item m-mobile-hide menu">
          <div class="ui dropdown  item">
            <div class="text">
              <img class="ui avatar image" src="../static/images/wechat.jpg">
              hualili
            </div>
            <i class="dropdown icon"></i>
            <div class="menu">
              <a href="#"  class="item">注销</a>
            </div>
          </div>
        </div>
      </div>
    </div>
    <a href="#" class="ui menu toggle black icon button m-right-top m-mobile-show">
      <i class="sidebar icon"></i>
    </a>
  </nav>


  <!--中间内容-->
  <div  class="m-container-small m-padded-tb-big">
    <div class="ui container">
      <div class="ui success large  message">
        <h3>Hi,</h3>
        <p>hualili,欢迎登录!</p>
      </div>

      <img src="../static/images/wechat.jpg" alt="" class="ui rounded bordered fluid image">
    </div>
  </div>

  <br>
  <br>

  <!--底部footer-->
  <footer th:replace="admin/_fragments :: footer" class="ui inverted vertical segment m-padded-tb-massive">
    <div class="ui center aligned container">
      <div class="ui inverted divided stackable grid">
        <div class="three wide column">
          <div class="ui inverted link list">
            <div class="item">
              <img src="../../static/images/wechat.jpg" class="ui rounded image" alt="" style="width: 110px">
            </div>
          </div>
        </div>
        <div class="three wide column">
          <h4 class="ui inverted header m-text-thin m-text-spaced " >最新新闻</h4>
          <div class="ui inverted link list">
            <a href="#" class="item m-text-thin">用户故事(User Story)</a>
            <a href="#" class="item m-text-thin">用户故事(User Story)</a>
            <a href="#" class="item m-text-thin">用户故事(User Story)</a>
          </div>
        </div>
        <div class="three wide column">
          <h4 class="ui inverted header m-text-thin m-text-spaced ">联系我</h4>
          <div class="ui inverted link list">
            <a href="#" class="item m-text-thin">Email:hualili@163.com</a>
            <a href="#" class="item m-text-thin">QQ:1234567</a>
          </div>
        </div>
        <div class="seven wide column">
          <h4 class="ui inverted header m-text-thin m-text-spaced ">news</h4>
          <p class="m-text-thin m-text-spaced m-opacity-mini">消息即狭义的新闻,它是对新近发生的有社会意义并引起公众兴趣的事实的简短报道。因此,真实性、时效性及文字少、篇幅小成为消息的基本特征。...</p>
        </div>
      </div>
      <div class="ui inverted section divider"></div>
      <p class="m-text-thin m-text-spaced m-opacity-tiny">Copyright © 2016 - 2017 liuhuali Designed by liuhuali</p>
    </div>

  </footer>
    <script src="https://cdn.jsdelivr.net/npm/aaa@qq.com/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script>
    <script src="../../static/lib/editormd/editormd.min.js" th:src="@{/lib/editormd/editormd.min.js}"></script>
  <script>
    $('.menu.toggle').click(function () {
      $('.m-item').toggleClass('m-mobile-hide');
    });

    $('.ui.dropdown').dropdown({
      on : 'hover'
    });

  </script>
</body>
</html>

三、分类显示
SSM项目中分页是通过新建了一个PageInfo实体类来实现的,Springboot中是通过@PageableDefault来实现的
TypeController.java

package com.wzx.controller;

import com.wzx.po.Type;
import com.wzx.service.TypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;



@Controller
@RequestMapping("/admin/types")
public class TypeController {

    @Autowired
    private TypeService typeService;

    @RequestMapping
    public String list(@PageableDefault(size = 5,sort = {"id"},direction = Sort.Direction.DESC) Pageable pageable, Model model){
        Page<Type> page=typeService.listType(pageable);
        model.addAttribute("page",page);
        return "admin/types";
    }
}

TypeService.java

import com.wzx.po.Type;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;

public interface TypeService {
    Page<Type> listType(Pageable pageable);
}

TypeServiceImpl.java

package com.wzx.service.impl;

import com.wzx.dao.TypeDao;
import com.wzx.po.Type;
import com.wzx.service.TypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class TypeServiceImpl implements TypeService {
    @Autowired
    private TypeDao typeDao;

    @Override
    public Page<Type> listType(Pageable pageable) {
        return typeDao.findAll(pageable);
    }
}

types.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head th:replace="admin/_fragments :: head(~{::title})">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>分类管理</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
  <link rel="stylesheet" href="../../static/css/me.css">
</head>
<body>

  <!--导航-->
  <nav th:replace="admin/_fragments :: menu(2)" class="ui inverted attached segment m-padded-tb-mini m-shadow-small" >
    <div class="ui container">
      <div class="ui inverted secondary stackable menu">
        <h2 class="ui teal header item">管理后台</h2>
        <a href="#" class="active m-item item m-mobile-hide">新闻</a>
        <a href="#" class=" m-item item m-mobile-hide">分类</a>
        <a href="#" class="m-item item m-mobile-hide">标签</a>
        <div class="right m-item m-mobile-hide menu">
          <div class="ui dropdown  item">
            <div class="text">
              <img class="ui avatar image" src="../static/images/wechat.jpg">
              hualili
            </div>
            <i class="dropdown icon"></i>
            <div class="menu">
              <a href="#" class="item">注销</a>
            </div>
          </div>
        </div>
      </div>
    </div>
    <a href="#" class="ui menu toggle black icon button m-right-top m-mobile-show">
      <i class="sidebar icon"></i>
    </a>
  </nav>
  <div class="ui attached pointing menu">
    <div class="ui container">
      <div class="right menu">
        <a href="#"  class="item">新增</a>
        <a href="#" class="teal active item">列表</a>
      </div>
    </div>
  </div>

  <!--中间内容-->
  <div  class="m-container-small m-padded-tb-big">
    <div class="ui container">
      <div class="ui success message" th:unless="${#strings.isEmpty(message)}">
        <i class="close icon"></i>
        <div class="header">提示:</div>
        <p th:text="${message}">恭喜,操作成功!</p>
      </div>
      <table class="ui celled table">
        <thead>
        <tr>
          <th></th>
          <th>名称</th>
          <th>操作</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="type,iterStat:${page.content}">
          <td th:text="${iterStat.count}" >1</td>
          <td th:text="${type.name}">刻意练习清单</td>
          <td>
            <a href="#" th:href="@{/admin/types/input/{id}(id=${type.id})}" class="ui mini teal basic button">编辑</a>
            <a href="#" th:href="@{/admin/types/delete/{id}(id=${type.id})}" class="ui mini red basic button">删除</a>
          </td>
        </tr>
        </tbody>
        <tfoot>
        <tr>
          <th colspan="6">
            <div class="ui mini pagination menu" th:if="${page.totalPages}>1">
              <a  class="  item" th:href="@{/admin/types(page=${page.number}-1)}" th:unless="${page.first}" >上一页</a>
              <a  class=" item"  th:href="@{/admin/types(page=${page.number}+1)}" th:unless="${page.last}">下一页</a>
            </div>
            <a href="#" th:href="@{/admin/types/input/{id}(id=-1)}"  class="ui mini right floated teal basic button">新增</a>
          </th>
        </tr>
        </tfoot>
      </table>
    </div>
  </div>

  <br>
  <br>
  <!--底部footer-->
  <footer th:replace="admin/_fragments :: footer" class="ui inverted vertical segment m-padded-tb-massive">
    <div class="ui center aligned container">
      <div class="ui inverted divided stackable grid">
        <div class="three wide column">
          <div class="ui inverted link list">
            <div class="item">
              <img src="../../static/images/wechat.jpg" class="ui rounded image" alt="" style="width: 110px">
            </div>
          </div>
        </div>
        <div class="three wide column">
          <h4 class="ui inverted header m-text-thin m-text-spaced " >最新新闻</h4>
          <div class="ui inverted link list">
            <a href="#" class="item m-text-thin">用户故事(User Story)</a>
            <a href="#" class="item m-text-thin">用户故事(User Story)</a>
            <a href="#" class="item m-text-thin">用户故事(User Story)</a>
          </div>
        </div>
        <div class="three wide column">
          <h4 class="ui inverted header m-text-thin m-text-spaced ">联系我</h4>
          <div class="ui inverted link list">
            <a href="#" class="item m-text-thin">Email:liuhuali@163.com</a>
            <a href="#" class="item m-text-thin">QQ:liuhuali</a>
          </div>
        </div>
        <div class="seven wide column">
          <h4 class="ui inverted header m-text-thin m-text-spaced ">news</h4>
          <p class="m-text-thin m-text-spaced m-opacity-mini">消息即狭义的新闻,它是对新近发生的有社会意义并引起公众兴趣的事实的简短报道。因此,真实性、时效性及文字少、篇幅小成为消息的基本特征。...</p>
        </div>
      </div>
      <div class="ui inverted section divider"></div>
      <p class="m-text-thin m-text-spaced m-opacity-tiny">Copyright © 2016 - 2017 liuhuali Designed by liuhuali</p>
    </div>

  </footer>
    <script src="https://cdn.jsdelivr.net/npm/aaa@qq.com/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script>
    <script src="../../static/lib/editormd/editormd.min.js" th:src="@{/lib/editormd/editormd.min.js}"></script>
  <script>
    $('.menu.toggle').click(function () {
      $('.m-item').toggleClass('m-mobile-hide');
    });

    $('.ui.dropdown').dropdown({
      on : 'hover'
    });

    //消息提示关闭初始化
    $('.message .close')
            .on('click', function () {
              $(this)
                      .closest('.message')
                      .transition('fade');
            });

  </script>
</body>
</html>

四、运行截图
登录界面
【个人实习日志】Springboot新闻管理系统(一)
主页面
【个人实习日志】Springboot新闻管理系统(一)
分类页面
【个人实习日志】Springboot新闻管理系统(一)
【个人实习日志】Springboot新闻管理系统(一)
注销页面
【个人实习日志】Springboot新闻管理系统(一)

相关标签: 实习