搭建实体类
博客 Blog、博客分类 Type、博客标签 Tag、博客评论 Comment、用户 User(这里其实只有一个用户就是自己。也是管理员)
确定实体类之间的关系,通过JPA直接生成数据库表结构。
首先在使用JPA之前需要在application.yml中配置一下,这里开发环境的配置如下:
spring:
jpa:
hibernate:
ddl-auto: update
show-sql: true
配置自动建表:updata:如果没有表的话则新建,有表则进行更新操作,控制台显示建表语句
然后开始搭建实体类,这里以博客 Blog为例。首先确定实体类之间的关系。如博客和博客类型是多对一的关系,博客和博客标签是多对多的关系,博客和用户是多对一的关系,博客和评论是一对多的关系。一般来讲“一”的那方作为关系被维护段需要加上(mappedBy= "xxx")。看到另外一名博主解释的很好:
在一对多或一对一的关系映射中,如果不表明mappedBy属性,默认是由本方维护外键。
但如果两方都由本方来维护的话,会多出一些update语句,性能有一定的损耗。
解决的办法就是在一的一方配置上mappedBy属性,将维护权交给多的一方来维护,
就不会有update语句了。
至于为何要将维护权交给多的一方,可以这样考虑:要想一个国家的领导人记住
所有人民的名字是不可能的,但可以让所有人民记住领导人的名字!
@Data
@Entity
@Table(name = "t_blog")
public class Blog {
@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 commentable;//是否开启评论
private boolean published;//是否发布 保存草稿
private boolean recommende;//是否推荐
//大字段 懒加载 只有在使用的时候才加载
@Basic(fetch = FetchType.LAZY)
@Lob
private String description; //博客描述
@Temporal(TemporalType.TIMESTAMP)
private Date creatTime;
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
@ManyToOne //关系维护端
private Type type;
@ManyToMany
private List<Tag>tags=new ArrayList<>();
@ManyToOne
private User user;
@OneToMany (mappedBy = "blog")
private List<Comment>commentList=new ArrayList<>();
@Data是Lombok中的注解,作用就是不需要再写set/get方法,让代码更加简洁。@Entity注解表示这是一个实体类,@Table(name="t_blog")表示对应的数据库表名。
@Temporal(TemporalType.TIMESTAMP)
实体类字段类型为Date ,数据库中字段类型为Timestamp。需要获得年月日格式用TemporalType.DATE;时分秒格式用TIME;时间戳格式用TIMESTAMP
实现后台登录功能
用户实体类 User
@Data
@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 String type;
@Temporal(TemporalType.TIMESTAMP)
private Date creatTime;
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
@OneToMany(mappedBy = "user")
private List<Blog> blogs=new ArrayList<>();
}
dao层
public interface UserRepository extends JpaRepository<User,Long> {
User findByUsernameAndPassword(String username,String password);
}
定义一个接口继承JpaRepository,其中<User,Long>表示实体类和主键类型。根据用户名和密码确认用户是否存在从而登录。
service层
public interface UserService {
User checkuser(String name,String password);
}
实现类
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Override
public User checkuser(String name, String password) {
User user=userRepository.findByUsernameAndPassword(name,password);
return user;
}
}
@Service注解表示当前类是一个service类,该注解会将当前类自动注入到Spring容器中。
@Autowired表示将UserRepository 注入进来,当前类可以直接调用UserRepository 中的方法对数据库进行操作。
controller层
@Controller
@RequestMapping("/admin")
public class LoginController {
@Autowired
private UserServiceImpl userService;
@GetMapping
public String LoginPage(){
return "admin/login";
}
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password, HttpSession session, RedirectAttributes redirectAttributes){
User user=userService.checkuser(username, MD5Util.code(password));
if(user!=null){
user.setPassword(null);
session.setAttribute("user",user);
return "admin/index";
}
redirectAttributes.addFlashAttribute("message","用户名和密码错误");
return "redirect:/admin";
}
@GetMapping("/loginout")
public String LoginOut(HttpSession session){
session.removeAttribute("user");
return "redirect:/admin";
}
}
@RequestMapping("/admin")定义映射地址,
@GetMapping是@RequestMapping(method = RequestMethod.GET)的缩写。
@PostMapping是@RequestMapping(method = RequestMethod.POST)的缩写。
@RequestParam用于接收普通参数
session用来存储登录成功的用户信息,不会出现刷新网页要重新登录的现象。
return "admin/index"; thymeleaf 用法 目标页面
return "redirect:/admin"; 重定向
实现后台注销功能
直接将用户信息从session中移除就行。
因为是个人博客只有一个用户,所以就没做注册功能。密码通过MD5加密
MD5Util
public class MD5Util {
/**
* MD5加密类
* @param str 要加密的字符串
* @return 加密后的字符串
*/
public static String code(String str){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte[]byteDigest = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < byteDigest.length; offset++) {
i = byteDigest[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
//32位加密
return buf.toString();
// 16位的加密
//return buf.toString().substring(8, 24);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
System.out.println(code("123456"));
}
}
前端核心代码
通过form表单提交数据,根据返回结果显示信息。
<form class="ui large form" method="POST" 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 message"></div>
<div class="ui mini negative message" th:unless="${#strings.isEmpty(message)}" th:text="${message}">
用户名和密码错误
</div>
</form>
<script>
$('.ui.form').form({
fields:{
username:{
identifier: 'username', //和表单里的name值一致
rules: [{
type: 'empty', //非空验证
prompt: '请输入用户名',
}]
},
password:{
identifier: 'password', //和表单里的name值一致
rules: [{
type: 'empty', //非空验证
prompt: '请输入密码',
}]
},
}
})
</script>
登录功能就完成了。
SpringBoot开发一个小而美的个人博客(一) 前端页面(一)_舒克、舒克的博客-CSDN博客_springboot开发一个页面
SpringBoot开发一个小而美的个人博客(二) 前端页面(二)_舒克、舒克的博客-CSDN博客
SpringBoot开发一个小而美的个人博客(三) 框架搭建_舒克、舒克的博客-CSDN博客_springboot开发个人博客
加油加油 冲冲冲!!!