【原】无脑操作:IDEA + maven + SpringBoot + JPA + EasyUI实现CRUD及分页
背景:上一篇文章的界面太丑、没有条件查询功能。所以做一些改进,整合EasyUI做实现。(仅以此文纪念表格中出现的这些朋友工作六周年,祭奠一下逝去的青春^_^)
一、开发环境(参照上一篇文章)
补充:EasyUI直接从官网随便下载一个版本即可,本文用的版本是 1.3.3
二、程序结构:java目录下都是服务端代码,resources目录下templates目录存放页面文件,static目录下存放JavaScript文件、CSS文件、图片等资源文件
三、具体实现(Talk is cheap.Show your my code.该写的注释都在代码中^_^)
1、pom.xml(同上一篇)
2、resources目录下新建application.properties(当然喜欢用yaml的可以用yaml)(同上一篇)
3、创建SpringBoot程序启动类SpringbootApplication.java(同上一篇)
4、创建实体类Person.java
1 package cn.temptation.model; 2 3 import javax.persistence.*; 4 5 //建库建表 6 //DROP TABLE person; 7 // 8 //CREATE TABLE person 9 //( 10 //personid INT AUTO_INCREMENT PRIMARY KEY, 11 //personname VARCHAR(10) NOT NULL, 12 //personage INT NOT NULL 13 //); 14 // 15 //INSERT INTO person VALUES 16 //(NULL, '张洋', 21), (NULL, '张兄家', 20), (NULL, '王生杰', 22), 17 //(NULL, '洪自军', 21), (NULL, '吴庆庆', 21), (NULL, '武建昌', 22), (NULL, '叶宇', 18); 18 // 19 //SELECT * FROM person; 20 @Entity 21 @Table(name = "person") 22 public class Person { 23 @Id 24 @GeneratedValue(strategy = GenerationType.IDENTITY) 25 @Column(name = "personid") 26 private Integer personid; 27 @Column(name = "personname") 28 private String personname; 29 @Column(name = "personage") 30 private Integer personage; 31 32 public Person() { 33 } 34 35 public Person(String personname, Integer personage) { 36 this.personname = personname; 37 this.personage = personage; 38 } 39 40 public Integer getPersonid() { 41 return personid; 42 } 43 44 public void setPersonid(Integer personid) { 45 this.personid = personid; 46 } 47 48 public String getPersonname() { 49 return personname; 50 } 51 52 public void setPersonname(String personname) { 53 this.personname = personname; 54 } 55 56 public Integer getPersonage() { 57 return personage; 58 } 59 60 public void setPersonage(Integer personage) { 61 this.personage = personage; 62 } 63 }
5、创建DAO接口PersonDao.java
1 package cn.temptation.dao; 2 3 import cn.temptation.model.Person; 4 import org.springframework.data.jpa.repository.JpaRepository; 5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 6 7 /** 8 * 因为需要使用分页和条件查询,所以从JpaRepository接口 和 JpaSpecificationExecutor接口继承 9 */ 10 public interface PersonDao extends JpaRepository<Person, Integer>, JpaSpecificationExecutor<Person> { 11 12 }
6、创建控制器类PersonController.java
1 package cn.temptation.web; 2 3 import cn.temptation.dao.PersonDao; 4 import cn.temptation.model.Person; 5 import cn.temptation.util.TypeUtil; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.data.domain.Page; 8 import org.springframework.data.domain.PageRequest; 9 import org.springframework.data.domain.Pageable; 10 import org.springframework.data.domain.Sort; 11 import org.springframework.data.jpa.domain.Specification; 12 import org.springframework.stereotype.Controller; 13 import org.springframework.web.bind.annotation.RequestMapping; 14 import org.springframework.web.bind.annotation.RequestParam; 15 import org.springframework.web.bind.annotation.ResponseBody; 16 17 import javax.persistence.criteria.*; 18 import java.util.HashMap; 19 import java.util.List; 20 import java.util.Map; 21 22 @Controller 23 @RequestMapping("/person") 24 public class PersonController { 25 @Autowired 26 private PersonDao personDao; 27 28 /** 29 * 跳转至列表页 30 * 31 * @return 32 */ 33 @RequestMapping("/view") 34 public String view() { 35 // 跳转至列表页 36 return "personlist"; 37 } 38 39 /** 40 * 查询列表信息 41 * 42 * @param searchcondition 查询条件 43 * @param searchcontent 查询内容 44 * @param page 页数 45 * @param rows 每页记录数 46 * @return 47 */ 48 @RequestMapping("/list") 49 @ResponseBody 50 public Map<String, Object> list(@RequestParam(value = "searchcondition", required = false) String searchcondition, 51 @RequestParam(value = "searchcontent", required = false) String searchcontent, 52 @RequestParam(value = "page", required = false) Integer page, 53 @RequestParam(value = "rows", required = false) Integer rows) { 54 // 创建查询规格对象 55 Specification<Person> specification = new Specification<Person>() { 56 @Override 57 public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 58 Predicate predicate = null; 59 Path path = null; 60 61 if (searchcondition != null && !"".equals(searchcondition) 62 && searchcontent != null && !"".equals(searchcontent)) { 63 switch (searchcondition) { 64 case "personname": // 人员名称 65 path = root.get("personname"); 66 predicate = cb.like(path, "%" + searchcontent + "%"); 67 break; 68 case "personage": // 人员年龄 69 path = root.get("personage"); 70 if (TypeUtil.isNum(searchcontent)) { 71 predicate = cb.equal(path, Integer.parseInt(searchcontent)); 72 } 73 break; 74 } 75 } 76 77 return predicate; 78 } 79 }; 80 81 Pageable pageable = new PageRequest(page - 1, rows, Sort.Direction.ASC, "personid"); 82 Page<Person> pagePerson = personDao.findAll(specification, pageable); 83 84 // 获取rows 85 List<Person> list = pagePerson.getContent(); 86 // 获取count 87 Long count = pagePerson.getTotalElements(); 88 89 Map<String, Object> resultMap = new HashMap(); 90 resultMap.put("total", count); 91 resultMap.put("rows", list); 92 resultMap.put("success", true); 93 94 return resultMap; 95 } 96 97 /** 98 * 新增处理 和 修改处理 99 * 100 * @param person 101 * @return 102 */ 103 @RequestMapping("/save") 104 @ResponseBody 105 public Map<String, Object> personsave(Person person) { 106 Map<String, Object> resultMap = new HashMap<String, Object>(); 107 personDao.save(person); 108 resultMap.put("success", true); 109 return resultMap; 110 } 111 112 /** 113 * 删除处理 114 * 115 * @param personid 116 * @return 117 */ 118 @RequestMapping("/delete") 119 @ResponseBody 120 public Map<String, Object> persondelete(@RequestParam("id") String personid) { 121 Map<String, Object> resultMap = new HashMap<String, Object>(); 122 personDao.deleteById(Integer.parseInt(personid)); 123 resultMap.put("success", true); 124 return resultMap; 125 } 126 }
7、创建工具类TypeUtil.java
1 package cn.temptation.util; 2 3 import java.util.regex.Pattern; 4 5 public class TypeUtil { 6 /** 7 * 验证是否整数 8 * 9 * @param str 10 * @return 11 */ 12 public static boolean isNum(String str) { 13 Pattern pattern = Pattern.compile("^-?[0-9]+"); 14 if (pattern.matcher(str).matches()) { 15 return true; 16 } else { 17 return false; 18 } 19 } 20 21 /** 22 * 验证是否小数 23 * 24 * @param str 25 * @return 26 */ 27 public static boolean isNumEx(String str) { 28 Pattern pattern = Pattern.compile("^[-+]?[0-9]+(\\.[0-9]+)?$"); 29 if (pattern.matcher(str).matches()) { 30 return true; 31 } else { 32 return false; 33 } 34 } 35 }
8、resources目录下新建templates目录,创建表现层:人员列表页面(personlist.html)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>人员列表</title> 6 <link rel="stylesheet" type="text/css" href="../easyui/themes/default/easyui.css"> 7 <link rel="stylesheet" type="text/css" href="../easyui/themes/icon.css"> 8 <script type="text/javascript" src="../easyui/jquery.min.js"></script> 9 <script type="text/javascript" src="../easyui/jquery.easyui.min.js"></script> 10 <script type="text/javascript" src="../easyui/locale/easyui-lang-zh_CN.js"></script> 11 <script type="text/javascript" src="../biz/person.js"></script> 12 </head> 13 <body> 14 <!-- 表格 --> 15 <table id="dg"> 16 </table> 17 <!-- 工具栏 --> 18 <div id="tb"> 19 <table cellpadding="0" cellspacing="0"> 20 <tr> 21 <td> 22 <a href="javascript:loadAll()" class="easyui-linkbutton" iconCls="Arrowrefresh" plain="true">加载全部</a> 23 </td> 24 <td> 25 <div class="datagrid-btn-separator"></div> 26 </td> 27 <td> 28 检索条件: 29 <select id="searchcondition" class="easyui-combobox" name="searchcondition" style="width:200px;"> 30 <option value="personname">人员名称</option> 31 <option value="personage">人员年龄</option> 32 </select> 33 </td> 34 <td> 35 <input type="text" id="searchcontent" name="searchcontent" size="20" onkeydown="if(event.keyCode==13){ queryAction(); }"/> 36 </td> 37 <td><a href="javascript:queryAction()" class="easyui-linkbutton" iconCls="Magnifier" plain="true">搜索</a></td> 38 <td> 39 <div class="datagrid-btn-separator"></div> 40 </td> 41 <td><a href="javascript:openAddDialog()" class="easyui-linkbutton" iconCls="icon-add" plain="true">新增</a></td> 42 <td> 43 <div class="datagrid-btn-separator"></div> 44 </td> 45 <td><a href="javascript:openModifyDialog()" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改</a></td> 46 <td> 47 <div class="datagrid-btn-separator"></div> 48 </td> 49 <td><a href="javascript:deleteAction()" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除</a></td> 50 </tr> 51 </table> 52 </div> 53 <!-- 弹出新增修改对话框 --> 54 <div id="dlg" class="easyui-dialog" style="width:300px;height:200px;padding: 10px 10px" closed="true" 55 buttons="#dialog-buttons" modal="true"> 56 <form id="fm" method="post"> 57 <table> 58 <tr> 59 <td><label for="personname">人员名称</label></td> 60 <td><input type="text" id="personname" name="personname" class="easyui-validatebox" required="true"/> 61 </td> 62 </tr> 63 <tr> 64 <td><label for="personage">人员年龄</label></td> 65 <td><input type="text" id="personage" name="personage" class="easyui-validatebox" required="true"/> 66 </td> 67 </tr> 68 </table> 69 </form> 70 </div> 71 <!-- 对话框按钮 --> 72 <div id="dialog-buttons"> 73 <a href="javascript:saveAction()" class="easyui-linkbutton" iconCls="icon-ok">保存</a> 74 <a href="javascript:closeDialog()" class="easyui-linkbutton" iconCls="icon-cancel">关闭</a> 75 </div> 76 </body> 77 </html>
9、resources目录下新建static目录,创建表现层:人员管理用脚本文件(person.js)
1 var url; 2 3 // 页面加载 4 $(function () { 5 $("#dg").datagrid({ 6 url: 'list', 7 queryParams: {}, 8 title: "人员列表", 9 rownumbers: true, 10 fit: true, 11 toolbar: "#tb", 12 collapsible: true, 13 pagination: true, 14 pageSize: 5, 15 pageList: [5, 10], 16 columns: [[ 17 {field: 'personid', title: '人员编号', width: 50, align: 'center', halign: 'center', hidden: 'true'}, 18 {field: 'personname', title: '人员名称', width: 200, align: 'center', halign: 'center'}, 19 {field: 'personage', title: '人员年龄', width: 200, align: 'right', halign: 'center'} 20 ]] 21 }); 22 }); 23 24 // 【加载全部】按钮押下处理 25 var loadAll = function () { 26 // 查询条件还原为默认状态 27 $('#searchcondition').combobox('setValue', 'personname'); 28 $('#searchcontent').val(""); 29 30 // 表格重新加载 31 var param = {}; 32 $("#dg").datagrid('load', param); 33 }; 34 35 // 【搜索】按钮押下处理 36 var queryAction = function () { 37 var param = { 38 searchcondition: $('#searchcondition').combobox('getValue'), 39 searchcontent: $('#searchcontent').val() 40 }; 41 42 $("#dg").datagrid('load', param); 43 }; 44 45 // 重置表单内容 46 var resetValue = function () { 47 $('#fm')[0].reset(); 48 }; 49 50 // 打开添加对话框 51 var openAddDialog = function () { 52 resetValue(); 53 $('#dlg').dialog({ 54 modal: true, 55 title: '添加人员信息' 56 }); 57 $('#dlg').dialog("open"); 58 url = "save"; 59 }; 60 61 // 新增处理 62 var saveAction = function () { 63 $("#fm").form("submit", { 64 url: url, 65 onSubmit: function () { 66 return $(this).form("validate"); 67 }, 68 success: function (result) { 69 var result = eval('(' + result + ')'); 70 if (result.success) { 71 $.messager.alert("系统提示", "保存成功!"); 72 resetValue(); 73 $("#dlg").dialog("close"); 74 $("#dg").datagrid("reload"); 75 } else { 76 $.messager.alert("系统提示", "保存失败!"); 77 return; 78 } 79 } 80 }); 81 }; 82 83 // 关闭对话框 84 var closeDialog = function () { 85 $("#dlg").dialog("close"); 86 resetValue(); 87 }; 88 89 // 打开编辑对话框 90 var openModifyDialog = function () { 91 var selectedRows = $("#dg").datagrid("getSelections"); 92 93 if (selectedRows.length != 1) { 94 $.messager.alert("系统提示", "请选择一条要编辑的数据!"); 95 return; 96 } 97 98 var row = selectedRows[0]; 99 $("#dlg").dialog("open").dialog("setTitle", "编辑人员信息"); 100 $("#fm").form("load", row); 101 url = "save?personid=" + row.personid; 102 }; 103 104 // 删除处理 105 var deleteAction = function () { 106 var selectedRows = $("#dg").datagrid("getSelections"); 107 108 if (selectedRows.length == 0) { 109 $.messager.alert("系统提示", "请选择要删除的数据"); 110 return; 111 } 112 113 $.messager.confirm("系统提示", "您确定要删除这<font color=red>" + selectedRows.length + "</font>条数据吗?", function (r) { 114 if (r) { 115 $.post("delete", { 116 id: selectedRows[0].personid 117 }, function (result) { 118 if (result.success) { 119 $.messager.alert("系统提示", "数据已成功删除!"); 120 $("#dg").datagrid("reload"); 121 } else { 122 $.messager.alert("系统提示", "数据删除失败,请联系工作人员!"); 123 } 124 }, "json"); 125 } 126 }); 127 };
四、启动项目,运行效果如下