SSH:SSH框架是Struts2,Spring和Hibernate框架的整合
其中Struts2 做控制器(controller),spring 管理各层的组件,hibernate 负责持久化层。
SSM:SSM框架是spring MVC ,spring和mybatis框架的整合
是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层
使用spring MVC负责请求的转发和视图管理,spring实现业务对象管理,mybatis作为数据对象的持久化引擎;
相比于之前的SSH(Struts+Spring+Hibernate),SSM更加轻量化和灵活,是目前比较主流的java web开发框架
SPRINGBOOT:项目初始化后,首要的就是各类资源文件的配置
而springboot少量的信息配置,就能替代spring大量的xml文件配置
在springboot中甚至都不需要配置web.xml,配置application.yml文件就可以了。
JPA:JAVA持久化API,基于ORM的一套规范, hibernate框架中提供了JPA的实现.
JPA → springdata JPA
ORM:目的——操作实体类就相当于操作数据库表
object relation mapper
实体类 表
属性 字段
Hibernate:Hibernate是一个基于JDBC的持久化框架,是一个优秀的ORM实现
Hibernate对JDBC访问数据库的代码做了封装,很大程度地简化了DAO层的编码工作
Thymeleaf:Thymeleaf是一个Java XML / XHTML / HTML5 模板引擎 ,可以在Web(基于servlet )和非Web环境中工作
配置
application.yml配置文件:对服务器端口号、mysql驱动、jpa进行配置
server:
port: 8088
spring:
datasource:
url: jdbc:mysql://localhost:3306/tnews?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: xyj123
jpa:
hibernate:
ddl-auto: update
show-sql: true
实现
从TNewsApplication类中的main方法启动
@SpringBootApplication
public class TNewsApplication {
public static void main(String[] args) {
SpringApplication.run(TNewsApplication.class,args);
}
}
实体类User
@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 +
'}';
}
}
实体类Type
@Entity
@Table(name = "t_type")
public class Type {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "type")
private List<News> news = 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> getNews() {
return news;
}
public void setNews(List<News> news) {
this.news = news;
}
@Override
public String toString() {
return "Type{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
登录
(1)在dao中,创建UserDao接口
public interface UserDao extends JpaRepository<User,Long> {
User findByUsernameAndPassword(String username, String password);
}
(2)在service中,创建UserService接口
public interface UserService {
User checkUser(String username, String password);
}
(3)在service下的impl中,实现UserService接口
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public User checkUser(String username, String password) {
return userDao.findByUsernameAndPassword(username,password);
}
}
(4)在Controller中创建LoginController类,在类中写toLogin、Login方法,控制页面的跳转
@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";
}
}
}
注销
在Controller下的LoginController类中,写logout方法,控制页面的跳转
@GetMapping("logout")
public String logout(HttpSession session){
session.removeAttribute("user");
return "admin/login";
}
fragments.html
将各个页面相同的部分写进fragments.html
实现注销,只需在fragments.html中编写相关代码
<div class="menu">
<a href="#" th:href="@{/admin/logout}" class="item">注销</a>
</div>
分页
(1)在dao中,创建TypeDao接口
public interface TypeDao extends JpaRepository<Type,Long> {}
(2)在service中,创建TypeService接口
public interface TypeService {
Page<Type> listType(Pageable pageable);
}
(3)在service下的impl中,实现TypeService接口
@Service
public class TypeServiceImpl implements TypeService {
@Autowired
private TypeDao typeDao;
@Override
public Page<Type> listType(Pageable pageable) {
return typeDao.findAll(pageable);
}
}
(4)在Controller中创建TypeController类,在类中写list方法,控制页面的跳转
ssm项目中,需要自定义PageInfo类实现分页,现在可以使用内置的Pageable来实现分页,简化了编程工作
@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";
}
}
types.html
Thymeleaf中th:each属性用于迭代循环,语法:th:each=“obj,iterStat:${objList}”
迭代对象可以是java.util.List,java.util.Map,数组等;
iterStat称作状态变量,属性有:
index:当前迭代对象的index(从0开始计算)
count: 当前迭代对象的index(从1开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个
遍历page对象,显示页面信息
<tr th:each="type,iterStat:${page.content}">
<td th:text="${iterStat.count}" >1</td>
<td th:text="${type.name}">刻意练习清单</td>
<td>
<a href="#" class="ui mini teal basic button">编辑</a>
<a href="#" class="ui mini red basic button">删除</a>
</td>
</tr>
若总页数大于1,显示上一页、下一页
若当前页是首页,不显示上一页
若当前页是尾页,不显示下一页
<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>
运行结果
登录
登录失败
登录成功
注销:点击注销,跳转到登录界面——http://localhost:8088/admin/logout
分页