本文主要是以权限管理模块为例来介绍使用springboot+mybatis完成增删改查的功能。
1. 添加Permission实体类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.lvniao.blog.model; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class Permission { 7 8 private Long id; 9 10 private String name; 11 12 private String alias; 13 14 private String description; 15 16 private boolean available; 17 18 private Permission parent; 19 20 private List<Permission> children = new ArrayList<Permission>(); 21 22 public Long getId() { 23 return id; 24 } 25 26 public void setId(Long id) { 27 this.id = id; 28 } 29 30 public String getName() { 31 return name; 32 } 33 34 public void setName(String name) { 35 this.name = name; 36 } 37 38 public String getAlias() { 39 return alias; 40 } 41 42 public void setAlias(String alias) { 43 this.alias = alias; 44 } 45 46 public String getDescription() { 47 return description; 48 } 49 50 public void setDescription(String description) { 51 this.description = description; 52 } 53 54 public boolean isAvailable() { 55 return available; 56 } 57 58 public void setAvailable(boolean available) { 59 this.available = available; 60 } 61 62 public Permission getParent() { 63 return parent; 64 } 65 66 public void setParent(Permission parent) { 67 this.parent = parent; 68 } 69 70 public List<Permission> getChildren() { 71 return children; 72 } 73 74 public void setChildren(List<Permission> children) { 75 this.children = children; 76 } 77 }
2. 添加Mapper类
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.lvniao.blog.mapper; 2 3 import java.util.List; 4 5 import org.apache.ibatis.annotations.Delete; 6 import org.apache.ibatis.annotations.Insert; 7 import org.apache.ibatis.annotations.InsertProvider; 8 import org.apache.ibatis.annotations.Many; 9 import org.apache.ibatis.annotations.One; 10 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Param; 12 import org.apache.ibatis.annotations.Result; 13 import org.apache.ibatis.annotations.Results; 14 import org.apache.ibatis.annotations.Select; 15 import org.apache.ibatis.annotations.UpdateProvider; 16 import org.apache.ibatis.mapping.FetchType; 17 18 import com.lvniao.blog.model.Permission; 19 20 @Mapper 21 public interface PermissionMapper { 22 23 @InsertProvider(type=PermissionProvider.class, method="insert") 24 public void insert(Permission permission); 25 26 @UpdateProvider(type=PermissionProvider.class, method="update") 27 public void update(Permission permission); 28 29 @Delete("delete from permissions where id=#{id}") 30 public void delete(@Param("id") Long id); 31 32 @Select("select count(id) count from permissions where name like '%${query}%'") 33 public int getCountByQuery(@Param("query") String query); 34 35 @Select("select count(id) count from permissions where parentid is null") 36 public int getParentCount(); 37 38 @Select("select id, name, alias, description, available, parentid from permissions where name like '%${query}%' limit #{start}, #{total}") 39 @Results({ 40 @Result(id=true, column="id", property="id"), 41 @Result(column="name", property="name"), 42 @Result(column="alias", property="alias"), 43 @Result(column="description", property="description"), 44 @Result(column="available", property="available"), 45 @Result(column="parentid", property="parent", 46 one=@One(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionById", fetchType=FetchType.EAGER)) 47 }) 48 public List<Permission> getPermissionByPage(@Param("start") int start, @Param("total") int total, @Param("query") String query); 49 50 @Select("select id, name, alias, description, available, parentid from permissions where parentid is null limit #{start}, #{total}") 51 @Results({ 52 @Result(id=true, column="id", property="id"), 53 @Result(column="name", property="name"), 54 @Result(column="alias", property="alias"), 55 @Result(column="description", property="description"), 56 @Result(column="available", property="available"), 57 @Result(column="id", property="children", 58 many=@Many(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionByParent", fetchType=FetchType.EAGER)), 59 @Result(column="parentid", property="parent", 60 one=@One(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionById", fetchType=FetchType.EAGER)) 61 }) 62 public List<Permission> getParentPermissionByPage(@Param("start") int start, @Param("total") int total); 63 64 @Select("select id, name, alias, description, available, parentid from permissions where parentid is null") 65 @Results({ 66 @Result(id=true, column="id", property="id"), 67 @Result(column="name", property="name"), 68 @Result(column="alias", property="alias"), 69 @Result(column="description", property="description"), 70 @Result(column="available", property="available"), 71 @Result(column="id", property="children", 72 many=@Many(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionByParent", fetchType=FetchType.EAGER)), 73 @Result(column="parentid", property="parent", 74 one=@One(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionById", fetchType=FetchType.EAGER)) 75 }) 76 public List<Permission> getParentPermission(); 77 78 @Select("select id, name, alias, description, available, parentid from permissions where parentid is null") 79 public List<Permission> getParent(); 80 81 @Select("select id, name, alias, description, available, parentid from permissions where parentid=#{id}") 82 @Results({ 83 @Result(id=true, column="id", property="id"), 84 @Result(column="name", property="name"), 85 @Result(column="alias", property="alias"), 86 @Result(column="description", property="description"), 87 @Result(column="available", property="available"), 88 @Result(column="parentid", property="parent", 89 one=@One(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionById", fetchType=FetchType.EAGER)) 90 }) 91 public List<Permission> getPermissionByParent(Long id); 92 93 @Select("select id, name, alias, description, available, parentid from permissions where id=#{id}") 94 @Results({ 95 @Result(id=true, column="id", property="id"), 96 @Result(column="name", property="name"), 97 @Result(column="alias", property="alias"), 98 @Result(column="description", property="description"), 99 @Result(column="available", property="available"), 100 @Result(column="parentid", property="parent", 101 one=@One(select="com.lvniao.blog.mapper.PermissionMapper.getPermissionById", fetchType=FetchType.EAGER)) 102 }) 103 public Permission getPermissionById(@Param("id") Long id); 104 } 105 因为对数据进行插入或更新的时候要根据Permission.parent是否为空来执行不同的sql,所以这儿使用了provider来动态拼接sql,provider代码如下: 106 package com.lvniao.blog.mapper; 107 108 import org.apache.ibatis.jdbc.SQL; 109 110 import com.lvniao.blog.model.Permission; 111 import com.lvniao.blog.util.StringUtil; 112 113 public class PermissionProvider { 114 115 private static final String table = "permissions"; 116 117 public String insert(Permission permission) { 118 SQL sql = new SQL().INSERT_INTO(table).INTO_COLUMNS("name", "alias", "description", "available", "parentid"); 119 sql.INTO_VALUES("#{name}", "#{alias}", "#{description}", "#{available}"); 120 if(permission.getParent() != null) { 121 sql.INTO_VALUES("#{parent.id}"); 122 } else { 123 sql.INTO_VALUES("null"); 124 } 125 return sql.toString(); 126 } 127 128 public String update(Permission permission) { 129 SQL sql = new SQL().UPDATE(table); 130 sql.SET("name=#{name}"); 131 sql.SET("alias=#{alias}"); 132 if(permission.isAvailable() != null){ 133 sql.SET("available=#{available}"); 134 } 135 if(!StringUtil.isNullOrEmpty(permission.getDescription())){ 136 sql.SET("description=#{description}"); 137 } 138 if(permission.getParent() != null && permission.getParent().getId() != null){ 139 sql.SET("parentid=#{parent.id}"); 140 } 141 sql.WHERE("id=#{id}"); 142 return sql.toString(); 143 } 144 }
3. 添加Controller
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.lvniao.blog.admin.controller; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Controller; 8 import org.springframework.ui.Model; 9 import org.springframework.web.bind.annotation.PathVariable; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.ResponseBody; 12 13 import com.lvniao.blog.mapper.PermissionMapper; 14 import com.lvniao.blog.model.Permission; 15 import com.lvniao.blog.util.Constant; 16 import com.lvniao.blog.util.JsonUtil; 17 import com.lvniao.blog.util.StringUtil; 18 import com.lvniao.blog.vmodel.PageModel; 19 20 @Controller 21 @RequestMapping("/permission") 22 public class PermissionController { 23 24 @Autowired 25 private PermissionMapper permissionMapper; 26 27 @RequestMapping("/") 28 public String index(Model model) { 29 return "permission/index"; 30 } 31 32 @RequestMapping("/list") 33 @ResponseBody 34 public String list(Integer page, Integer rows, String query) { 35 PageModel pagemodel = new PageModel(); 36 if(StringUtil.isNullOrEmpty(query)) { 37 pagemodel = new PageModel(permissionMapper.getParentCount(), 38 permissionMapper.getParentPermissionByPage((page-1)*rows, rows)); 39 } else { 40 pagemodel = new PageModel(permissionMapper.getCountByQuery(query), 41 permissionMapper.getPermissionByPage((page-1)*rows, rows, query)); 42 } 43 return JsonUtil.toJson(pagemodel); 44 } 45 46 @RequestMapping("/getparent") 47 @ResponseBody 48 public String getParentPermission() { 49 return JsonUtil.toJson(permissionMapper.getParent()); 50 } 51 52 @RequestMapping("/add") 53 public String add() { 54 return "permission/add"; 55 } 56 57 @RequestMapping("/addmodel") 58 @ResponseBody 59 public String addModel(Permission permission) { 60 permissionMapper.insert(permission); 61 return JsonUtil.toMsgJson(Constant.SUCCESS); 62 } 63 64 @RequestMapping("/modify/{id}") 65 public String modify(@PathVariable Long id, Model model) { 66 model.addAttribute("permission", permissionMapper.getPermissionById(id)); 67 return "permission/modify"; 68 } 69 70 @RequestMapping("/modifymodel") 71 @ResponseBody 72 public String modifyModel(Permission permission) { 73 permissionMapper.update(permission); 74 return JsonUtil.toMsgJson(Constant.SUCCESS); 75 } 76 77 @RequestMapping("/delete/{id}") 78 @ResponseBody 79 public String delete(@PathVariable Long id) { 80 permissionMapper.delete(id); 81 return JsonUtil.toMsgJson(Constant.SUCCESS); 82 } 83 }
在controller如果方法返回的是视图,则直接返回视图名即可;如果方法是供ajax调用的,这样就要添加@ResponseBody,以注明是用于返回json字符串;可以使用@PathVariable来绑定uri中的片段。
4. 添加index视图
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"/> 5 <title></title> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 7 <link rel="stylesheet" th:href="@{/css/page.css}"/> 8 <link rel="stylesheet" type="text/css" th:href="@{/easyui/themes/default/easyui.css}"/> 9 <link rel="stylesheet" type="text/css" th:href="@{/easyui/themes/icon.css}"/> 10 <link rel="stylesheet" type="text/css" th:href="@{/layui/css/layui.css}"/> 11 <link rel="stylesheet" type="text/css" th:href="@{/css/grid.css}"/> 12 <script type="text/javascript" th:src="@{/easyui/jquery.min.js}"></script> 13 <script type="text/javascript" th:src="@{/easyui/jquery.easyui.min.js}"></script> 14 <script type="text/javascript" th:src="@{/layui/layui.js}"></script> 15 <script type="text/javascript" th:src="@{/layui/layui.all.js}"></script> 16 <script type="text/javascript" th:src="@{/js/form.js}"></script> 17 <script> 18 $(function(){ 19 $("#grid").treegrid({url: '/permission/list', 20 method: 'get', 21 rownumbers: true, 22 idField: 'id', 23 fit:true, 24 treeField: 'name', 25 pagination: true, 26 pageSize: 10, 27 pageList: [10, 50, 100]}); 28 $("#btnSearch").click(function(){ 29 $("#grid").treegrid({queryParams:form2Json("query")}); 30 }); 31 32 $(".lv-btn-group .lv-btn").click(function(){ 33 var type = $(this).attr("type"); 34 var addr = $(this).attr("addr"); 35 if(type == "refresh"){ 36 $(".lv-txtSearch").val(""); 37 $("#grid").treegrid({queryParams:form2Json("query")}); 38 return; 39 } 40 if(type == "add"){ 41 layer.open({ 42 type: 2, 43 title: $(this).attr("title"), 44 shadeClose: true, 45 shade: 0.8, 46 area: ['330px', '270px'], 47 content: addr, 48 success:function(layero){ 49 $("#grid").treegrid({queryParams:form2Json("query")}); 50 } 51 }); 52 return; 53 } 54 55 56 var row = $("#grid").treegrid("getSelected"); 57 if(row == null){ 58 layer.alert("请选择待操作的数据"); 59 return; 60 } 61 if(row.parent === undefined){ 62 layer.alert("顶级菜单不能修改"); 63 return; 64 } 65 if(type == "modify"){ 66 layer.open({ 67 type: 2, 68 title: $(this).attr("title"), 69 shadeClose: true, 70 shade: 0.8, 71 area: ['330px', '270px'], 72 content: addr + "/" + row.id, 73 success:function(layero){ 74 $("#grid").treegrid({queryParams:form2Json("query")}); 75 } 76 }); 77 return; 78 } 79 if(type == "delete"){ 80 $.ajax({ 81 url:addr + "/" + row.id, 82 type:"get", 83 success:function(data){ 84 $("#grid").treegrid({queryParams:form2Json("query")}); 85 } 86 }); 87 return; 88 } 89 90 }); 91 }); 92 </script> 93 </head> 94 <body> 95 <div class="lv-option-container"> 96 <form id="query"> 97 <input type="text" class="lv-txtSearch" name="query"/><div class="lv-btnSearch" id="btnSearch">查询</div> 98 </form> 99 100 <div class="lv-btn-group"> 101 <div class="lv-btn" type="refresh">刷新</div> 102 <div class="lv-btn" type="add" addr="/permission/add" title="添加">添加</div> 103 <div class="lv-btn" type="modify" addr="/permission/modify" title="修改">修改</div> 104 <div class="lv-btn" type="delete" addr="/permission/delete" title="删除">删除</div> 105 </div> 106 </div> 107 <div class="lv-grid-container"> 108 <table id="grid"> 109 <thead> 110 <tr> 111 <th data-options="field:'name'" width="220">权限名</th> 112 <th data-options="field:'alias'" width="220">权限别名</th> 113 <th data-options="field:'description'" width="220">描述</th> 114 <th data-options="field:'available', formatter:booleanFormat" width="220">是否可用</th> 115 </tr> 116 </thead> 117 </table> 118 </div> 119 </body> 120 </html>
5. 添加add视图
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"/> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <title></title> 7 <link rel="stylesheet" th:href="@{/css/page.css}"/> 8 <link rel="stylesheet" type="text/css" th:href="@{/easyui/themes/default/easyui.css}"/> 9 <link rel="stylesheet" type="text/css" th:href="@{/easyui/themes/icon.css}"/> 10 <script type="text/javascript" th:src="@{/js/form.js}"></script> 11 <script type="text/javascript" th:src="@{/easyui/jquery.min.js}"></script> 12 <script type="text/javascript" th:src="@{/easyui/jquery.easyui.min.js}"></script> 13 <link rel="stylesheet" th:href="@{/css/form.css}"/> 14 <script> 15 $(function(){ 16 $("#parent").combobox({ 17 url:'/permission/getparent', 18 textField:'name', 19 valueField:'id', 20 panelHeight:100 21 }); 22 $("#btnCancel").click(function(){ 23 close(); 24 }); 25 $("#btnOk").click(function(){ 26 $.ajax({ 27 url:'/permission/addmodel', 28 type:"post", 29 dataType:'html', 30 data:getData(), 31 success:function(data){ 32 close(); 33 } 34 }) 35 }) 36 }); 37 38 function getData(){ 39 var res = {}; 40 if($("#name").val().length > 0){ 41 res.name = $("#name").val(); 42 } 43 if($("#alias").val().length > 0){ 44 res.alias = $("#alias").val(); 45 } 46 if($("#description").val().length > 0){ 47 res.description = $("#description").val(); 48 } 49 var radio = $("input[name='available']:checked"); 50 if(radio.length > 0){ 51 res.available = $("input[name='available']:checked").val(); 52 } else { 53 res.available = false; 54 } 55 if($("#parent").combotree("getValue").length > 0){ 56 res["parent.id"]= $("#parent").combotree("getValue"); 57 } 58 return res; 59 } 60 </script> 61 </head> 62 <body> 63 <form id="form" class="lv-form-container"> 64 <div class="lv-control-row"> 65 <div class="lv-label">权限名称</div> 66 <input type="text" id="name" class="lv-control"/> 67 </div> 68 <div class="lv-control-row"> 69 <div class="lv-label">权限别名</div> 70 <input type="text" id="alias" class="lv-control"/> 71 </div> 72 <div class="lv-control-row"> 73 <div class="lv-label">父权限</div> 74 <select class="lv-control" id="parent"> 75 </select> 76 </div> 77 <div class="lv-control-row"> 78 <div class="lv-label">描述</div> 79 <input type="text" id="description" class="lv-control"/> 80 </div> 81 <div class="lv-control-row"> 82 <div class="lv-label">可用性</div> 83 <input type="radio" name="available" class="lv-control" style="width:25px;" value="true"/><span>可用</span> 84 <input type="radio" name="available" class="lv-control" style="width:25px;" value="false"/><span>禁用</span> 85 </div> 86 <div class="lv-control-row"> 87 <div class="lv-btn" id="btnCancel">取消</div> 88 <div class="lv-btn" id="btnOk">确定</div> 89 </div> 90 </form> 91 </body> 92 </html>
6. 添加modify视图
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"/> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <title></title> 7 <link rel="stylesheet" th:href="@{/css/page.css}"/> 8 <link rel="stylesheet" type="text/css" th:href="@{/easyui/themes/default/easyui.css}"/> 9 <link rel="stylesheet" type="text/css" th:href="@{/easyui/themes/icon.css}"/> 10 <script type="text/javascript" th:src="@{/js/form.js}"></script> 11 <script type="text/javascript" th:src="@{/easyui/jquery.min.js}"></script> 12 <script type="text/javascript" th:src="@{/easyui/jquery.easyui.min.js}"></script> 13 <link rel="stylesheet" th:href="@{/css/form.css}"/> 14 <script th:inline="javascript"> 15 $(function(){ 16 $("#id").val([[${permission.id}]]); 17 $("#name").val([[${permission.name}]]); 18 $("#alias").val([[${permission.alias}]]); 19 $("#description").val([[${permission.description}]]); 20 var available = eval([[${permission.available}]]); 21 if(available){ 22 $("input[name='available']:first").attr("checked", "checked"); 23 } else { 24 $("input[name='available']:last").attr("checked", "checked"); 25 } 26 $("#parent").combobox({ 27 url:'/permission/getparent', 28 textField:'name', 29 valueField:'id', 30 panelHeight:100, 31 onLoadSuccess:function(){ 32 $("#parent").combobox("setValue", [[${permission.parent.id}]]); 33 } 34 }); 35 $("#btnCancel").click(function(){ 36 close(); 37 }); 38 $("#btnOk").click(function(){ 39 $.ajax({ 40 url:'/permission/modifymodel', 41 type:"post", 42 dataType:'html', 43 data:getData(), 44 success:function(data){ 45 close(); 46 } 47 }) 48 }) 49 }); 50 function getData(){ 51 var res = {}; 52 res.id = $("#id").val(); 53 if($("#name").val().length > 0){ 54 res.name = $("#name").val(); 55 } 56 if($("#alias").val().length > 0){ 57 res.alias = $("#alias").val(); 58 } 59 if($("#description").val().length > 0){ 60 res.description = $("#description").val(); 61 } 62 var radio = $("input[name='available']:checked"); 63 if(radio.length > 0){ 64 res.available = $("input[name='available']:checked").val(); 65 } else { 66 res.available = false; 67 } 68 if($("#parent").combotree("getValue").length > 0){ 69 res["parent.id"]= $("#parent").combotree("getValue"); 70 } 71 return res; 72 } 73 </script> 74 </head> 75 <body> 76 <form id="form" class="lv-form-container"> 77 <input type="hidden" id="id"/> 78 <div class="lv-control-row"> 79 <div class="lv-label">权限名称</div> 80 <input type="text" id="name" class="lv-control"/> 81 </div> 82 <div class="lv-control-row"> 83 <div class="lv-label">权限别名</div> 84 <input type="text" id="alias" class="lv-control"/> 85 </div> 86 <div class="lv-control-row"> 87 <div class="lv-label">父权限</div> 88 <select class="lv-control" id="parent"> 89 </select> 90 </div> 91 <div class="lv-control-row"> 92 <div class="lv-label">描述</div> 93 <input type="text" id="description" class="lv-control"/> 94 </div> 95 <div class="lv-control-row"> 96 <div class="lv-label">可用性</div> 97 <input type="radio" name="available" class="lv-control" style="width:25px;" value="true"/><span>可用</span> 98 <input type="radio" name="available" class="lv-control" style="width:25px;" value="false"/><span>禁用</span> 99 </div> 100 <div class="lv-control-row"> 101 <div class="lv-btn" id="btnCancel">取消</div> 102 <div class="lv-btn" id="btnOk">确定</div> 103 </div> 104 </form> 105 </body> 106 </html>
注意在js中使用绑定的时候要现在script中添加th:inline="javascript",然后使用[[${xx}]]来绑定数据。
如上面这些过程后就完成了权限模块的增删改查,用同样的方式完成角色、用户这些功能,后面将引入shiro来添加粗粒度的权限管理功能。
如果视图模板中js部分中如逻辑运算符或关系运算符中报错的话,就用/*<![CDATA[*/和/*]]>*/将报错部分括起来即可。
由于是初学java,springboot也只是看了个皮毛,这个项目也只是练手,所以有些地方做的不好,如果发现错误请指正。
现阶段代码下载地址:https://pan.baidu.com/s/1M8estpu41YlLsUlKjrrSEg, 密码:veh7