快速上手
配置文件
pom包里面添加jpa和thymeleaf的相关包引用
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
在application.yml中添加配置
spring:
application:
name: crm
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf-8
username: root
password: 12345678
#热部署配置
devtools:
restart:
enabled: true
additional-paths: scr/main/java
jpa:
#显示SQL
show-sql: true
properties:
hibernate:
#配置格式化SQL语句
format_sql: true
database: mysql
generate-ddl: true
server:
servlet:
context-path: /crm
#mybatis-plus:
# mapper-locations: classpath:/com/bdqn/mapper/*.xml
# type-aliases-package: com.bdqn.entity
创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@ToString
@Table(name = "sys_user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "usr_id")
private Long usrId;
@Column(name = "usr_name")
private String usrName;
@Column(name = "usr_password")
private String usrPassword;
@ManyToOne(targetEntity = Role.class)
@JoinColumn(name = "usr_role_id")
private Role role;
@Column(name = "usr_flag")
private Integer usrFlag;
}
继承 JpaRepository 类会自动实现很多内置的方法,包括增删改查。也可以根据方法名来自动生成相关 Sql。
public interface UserRepository extends JpaRepository<User,Long>, JpaSpecificationExecutor<User> {
List<User> findByUsrNameAndUsrPassword(String usrName,String usrPassword);
}
业务层处理
Service 调用 Jpa 实现相关的增删改查,实际项目中 Service 层处理具体的业务代码。
public interface IUserService {
User login(String usrName, String usrPassword);
void saveUser(User user); //适用新增和修改
void deleteUser(Long usrId);
User getUser(Long usrId);
//按条件进行分页查询(动态SQL)
Page<User> findUsers(String usrName, Long roleId, Pageable pageable);
}
Controller 负责接收请求,处理完后将页面内容返回给前端。
@Controller
public class UserController {
@Resource
private IUserService userService;
@Resource
private IRoleService roleService;
@RequestMapping(value = "dologin")
public String dologin(String usrName, String usrPassword, HttpServletRequest request){
User user = userService.login(usrName,usrPassword);
if(user != null){
request.getSession().setAttribute("loginUser",user);
return "main";
}else {
request.setAttribute("message","登录失败,用户名或密码错误!");
return "login";
}
}
@RequestMapping(value = "logout")
public String logout(HttpSession session){
session.removeAttribute("loginUser");
return "login";
}
@RequestMapping(value = "/user/add")
public String add(Model model){
List<Role> roles = roleService.findAllRoles();
model.addAttribute("roles",roles);
return "user/add";
}
@RequestMapping(value = "/user/save")
public String save(User user){
userService.saveUser(user);
return "redirect:/user/list";
}
@RequestMapping(value = "/user/edit")
public String edit(Long usrId, Model model){
User user = userService.getUser(usrId);
List<Role> roles = roleService.findAllRoles();
model.addAttribute("user",user);
model.addAttribute("roles",roles);
return "user/edit";
}
@RequestMapping(value = "/user/del")
@ResponseBody
public Map del(Long usrId){
userService.getUser(usrId);
Map map = new HashMap();
map.put("delResult","true");
return map;
}
@GetMapping(value = "/user/list")
public String list(Model model, String usrName,
@RequestParam(required = false,defaultValue = "0") Long roleId,
@RequestParam(required = false,defaultValue = "1") int pageIndex){
Sort sort = Sort.by(Sort.Direction.ASC,"usrId");
Pageable pageable = PageRequest.of(pageIndex-1,5,sort);
Page<User> userPager = userService.findUsers(usrName,roleId,pageable);
model.addAttribute("userPager",userPager);
model.addAttribute("usrName",usrName);
model.addAttribute("roleId",roleId);
return "user/list";
}
@RequestMapping(value = "/role/json")
@ResponseBody
public List<Role> findAllRoles(){
return roleService.findAllRoles();
}
}
创建Thymeleaf模板
在src/main/resources/templates目录下创建Thymeleaf模板文件
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{main}"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
>
<head>
<title>用户管理</title>
<link th:href="@{/localcss/crmlist.css}" href="../../static/localcss/crmlist.css" rel="stylesheet">
</head>
<body>
<div layout:fragment="content">
<div class="">
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12">
<div class="x_panel">
<div class="x_title">
<h2>
用户管理 <i class="fa fa-user"></i>
<small>
- 您可以通过搜索或者其他的筛选项对用户的信息进行编辑、删除等管理操作。^_^
</small>
</h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<form method="post" action="/user/list" th:action="@{/user/list}">
<input type="hidden" name="pageIndex" value="1" />
<ul>
<li>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12">用户名称</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<input name="usrName" type="text" th:value="${usrName}"
class="form-control col-md-6 col-xs-12" value="">
</div>
</div>
</li>
<li>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12">角色</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<select name="roleId" id="roleId" class="form-control">
<option value="0">--请选择--</option>
<option th:selected="${role.roleId eq roleId}" th:each="role : ${roles}"
th:value="${role.roleId}" th:text="${role.roleName}" value="">
角色1
</option>
</select>
</div>
</div>
</li>
<li>
<button type="submit" class="btn btn-primary"> 查 询
</button>
</li>
</ul>
</form>
</div>
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_content">
<p class="text-muted font-13 m-b-30"></p>
<div id="datatable-responsive_wrapper"
class="dataTables_wrapper form-inline dt-bootstrap no-footer">
<div class="row">
<div class="col-sm-12">
<!-- <a href="/user/add" th:href="@{/user/add}" shiro:hasPermission="用户添加" class="btn btn-success btn-sm">新增用户信息</a> -->
<a href="/user/add" th:href="@{/user/add}" class="btn btn-success btn-sm">新增用户信息</a>
<table id="datatable-responsive"
class="table table-striped table-bordered dt-responsive nowrap dataTable no-footer dtr-inline collapsed"
cellspacing="0" width="100%" role="grid"
aria-describedby="datatable-responsive_info" style="width: 100%;">
<thead>
<tr role="row">
<th class="sorting_asc" tabindex="0"
aria-controls="datatable-responsive" rowspan="1" colspan="1"
aria-label="First name: activate to sort column descending"
aria-sort="ascending">编号
</th>
<th class="sorting" tabindex="0"
aria-controls="datatable-responsive" rowspan="1" colspan="1"
aria-label="Last name: activate to sort column ascending">
用户名
</th>
<th class="sorting" tabindex="0"
aria-controls="datatable-responsive" rowspan="1" colspan="1"
aria-label="Last name: activate to sort column ascending">
角色
</th>
<th class="sorting" tabindex="0"
aria-controls="datatable-responsive" rowspan="1" colspan="1"
aria-label="Last name: activate to sort column ascending">
操作
</th>
</tr>
</thead>
<tbody>
<tr role="row" class="odd" th:each="user : ${userPager.records}">
<td tabindex="0" class="sorting_1" th:text="${user.usrId}">usrId</td>
<td th:text="${user.usrName}">usrName</td>
<td th:text="${user.role.roleName}">roleName</td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-danger">点击操作</button>
<button type="button" class="btn btn-danger dropdown-toggle"
data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a class="editInfo"
href="/user/edit?usrId=1"
th:href="@{/user/edit(usrId=${user.usrId})}"
data-toggle="tooltip"
data-placement="top" title=""
data-original-title="编辑">编辑</a>
</li>
<li><a class="delInfo" id="del" href="#"
th:onclick="|doDel(this,${user.usrId})|"
data-toggle="tooltip" data-placement="top" title=""
data-original-title="删除">删除</a></li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-5">
<div class="dataTables_info" id="datatable-responsive_info"
role="status" aria-live="polite">共<span th:text="${userPager.total }">1</span>条记录
<span th:text="${userPager.current }">1</span>/<span
th:text="${userPager.pages }">1</span>页
</div>
</div>
<div class="col-sm-7">
<div class="dataTables_paginate paging_simple_numbers"
id="datatable-responsive_paginate">
<ul class="pagination">
<li class="paginate_button previous" th:if="${userPager.current gt 0}"><a
href="javascript:page_nav(document.forms[0],1);"
aria-controls="datatable-responsive" data-dt-idx="0"
tabindex="0">首页</a>
</li>
<li class="paginate_button" th:if="${userPager.current gt 1}"><a href="#"
th:onclick="'javascript:page_nav(document.forms[0],'+${userPager.current - 1 }+');'"
aria-controls="datatable-responsive"
data-dt-idx="1"
tabindex="0">上一页</a>
</li>
<li class="paginate_button "
th:if="${(userPager.current) lt userPager.pages}"><a
href="#"
th:onclick="'javascript:page_nav(document.forms[0],'+${userPager.current + 1 }+');'"
aria-controls="datatable-responsive" data-dt-idx="1"
tabindex="0">下一页</a>
</li>
<li class="paginate_button next"
th:if="${(userPager.current) lt userPager.total}"><a
href="#"
th:onclick="'javascript:page_nav(document.forms[0],'+${userPager.pages }+');'"
aria-controls="datatable-responsive" data-dt-idx="7"
tabindex="0">最后一页</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script layout:fragment="js" th:inline="javascript">
// 获取项目路径
/*<![CDATA[*/
var ctxPath = /*[[@{/}]]*/ '';
/*]]>*/
function doDel(obj, usrId) {
if (confirm("你确定需要删除该用户信息吗?")) {
$.ajax({
type: "POST",
url: ctxPath + "user/del/" + usrId,
/*data: {
"usrId": usrId
},*/
dataType: "json",
success: function (data) {
// alert(JSON.stringify(data)); // {"result":"true"}
if (data.result === "true") { // 删除成功:移除删除行
alert("删除成功!");
$(obj).parents("tr").remove();
// window.location.href = project_name() + "/user/list";
}
},
error: function (data) {
alert("对不起,删除失败!");
}
});
}
}
/*$(document).ready(function(){
$.ajax({
type:"GET",
url:"${pageContext.request.contextPath}/role/json",
dataType:"json",
success:function(data){
$.each(data, function(i, tmp) {
$("#roleId").append(
"<option value='"+tmp.roleId+"'>" + tmp.roleName + "</option>");
});
},
error:function(data){
alert("对不起,获取数据失败!");
}
});
});*/
</script>
</html>