Blog System有关删除的问题
一 Jpa级联删除
1. 删除blog时同时删除db中的comments
- 两个表(Object): Blog ---- Comment 一对多
import org.hibernate.annotations.Cascade;
public class Blog{
@OneToMany(mappedBy = "blog")
@Cascade(org.hibernate.annotations.CascadeType.DELETE)
private List<Comment> commentList = new ArrayList<>();
}
public class Comment{
//relationship
@ManyToOne
private Blog blog;
}
总结:用@Cascade(org.hibernate.annotations.CascadeType.DELETE)
实现一对多的级联删除;
2. 删除comments
问题的引出:级联删除,但是再次使用1中的删除注解,删除子评论时也会把父评论和同级评论给删除。
- 中插一个说明(来源于别人的观点):
@Cascade(org.hibernate.annotations.CascadeType.REMOVE)
@Cascade(org.hibernate.annotations.CascadeType.DELETE)
没有区别;它们是同义词。
但如果你看看AnnotationBinder.getCascadeStrategy()源代码,你会发现两者都被转换成Hibernate的"delete“级联类型。
两者都存在的原因是因为Hibernate内核一直使用"DELETE“作为级联类型,但JPA的CascadeType将"REMOVE”指定为常量。Hibernate注解的CascadeType,作为Hibernate的JPA扩展的一部分,因此具有两者的完整性/一致性。
以前上课的时候老师就讲过,级联删除要谨慎使用,因为它的破坏性太大了。
Jpa级联删除的是对象实体
- 举个更简单的例子:学校和学生是一对多的关系,使用
@Column(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
删除一个学生,会直接把他所对应的学校给删了,当然其他所有学生的数据也全没了…(这显然不是我们想要的); - 所以更加要注意对注解
CascadeType.ALL
的使用,想清楚逻辑关系后再使用;
回归我的需求:
- 只删除子评论(可以理解为二叉树的叶子节点即没有子评论的评论);
- 级联删除父评论下的所有子评论;
这里只能采用循环遍历的方式,自己写代码删除;
再补充一个判断list空遇到的问题:
isEmpty和null有什么区别
二 Semantic前端框架删除前确认的提示框
先贴一个整体的 html+js 代码例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Comfirm</title>
<link rel="stylesheet" href="../static/css/semantic.min.css">
</head>
<body>
<div class="ui container">
<div class="ui secondary segment form">
<input type="hidden" name="page" >
<div class="inline fields">
<div class="field">
<input type="text" name="title" placeholder="Title">
</div>
<div class="field">
<div class="ui labeled action input">
<div class="ui type selection dropdown">
<input type="hidden" name="categoryId">
<i class="dropdown icon"></i>
<div class="default text">Category</div>
<div class="menu">
<div th:each="category : ${categories}" class="item" data-value="1" th:data-value="${category.id}" th:text="${category.name}">Error Log</div>
<!--/*-->
<div class="item" data-value="2">Developer's manual</div>
<!--*/-->
</div>
</div>
<button id="clear-btn" class="ui compact button">clear</button>
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" id="recommend" name="recommend">
<label for="recommend">Recommend</label>
</div>
</div>
<div class="field">
<button type="button" id="search-btn" class="ui mini teal basic button"><i class="search icon"></i>Search</button>
</div>
</div>
</div>
<div class="ui success message" th:unless="${#strings.isEmpty(message)}">
<i class="close icon"></i>
<div class="header">Prompt:</div>
<p th:text="${message}">Congratulations, the operation succeeded</p>
</div>
<div class="ui modal">
<div class="header title">确定删除吗?</div>
<div class="content">
确定删除这个博客吗?
</div>
<div class="actions">
<button class="ui negative button">否</button>
<button class="ui positive button">是</button>
</div>
</div>
</div>
<script type="text/javascript" src="../static/js/jquery.min.js"></script>
<script type="text/javascript" src="../static/js/semantic.min.js"></script>
<script>
$(".ui.modal")
.modal({ //各种回调方法
onShow: function () {
console.log("正在显示");
},
onVisible: function () {
console.log("完全显示");
},
onHide: function () {
console.log("开始隐藏");
},
onHidden: function () {
console.log("完全隐藏");
},
onApprove:function () { //单击确认按钮
console.log("确认")
},
onDeny:function () { //单击取消按钮
console.log("拒绝")
}
})
.modal("show");
</script>
</body>
</html>
- 使用的class是
ui modal
- 我这边的操作流程是点击Delete按钮,系统会先提示是否确认要删除,点击Yes后才会删除。因此,要先在删除按钮的节点内加一个点击事件:
参考博文Semantic UI 之 对话框 modal 应用:操作前判断
<a onclick="go(this)" th:attr="data-url=${blog.id}" class="ui mini red basic button">Delete</a>
function go(obj) {
// /*<![CDATA[*/
var url= "[[@{/admin/blogs/}]]"+$(obj).data("url")+"/delete";
// /*]]>*/
$(".ui.modal").modal({ //各种回调方法
onApprove:function () { //单击确认按钮
console.log("Confirm");
window.location.href=url;
},
onDeny:function () { //单击取消按钮
console.log("Reject")
}
}).modal("show");
return false;
}