一直在探索自己最喜欢(最简单)的 CRUD+分页,前面写过很多了,代码基本都是由前面进化而来的,而且也是越来越简单,JS 代码也是越来越规范简洁
1、Servlet+EasyUI+MySQL
2、Spring+SpringMVC+MyBatis+pageHelper
下面来个
3、SpringBoot+EasyUI+MySQL
由于比较简单
①entity、②dao、③service、④controller 四层中省略了 ③service 层
package com.cun.bean;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue
private Integer id;
@Column(length = 50)
private String name;
@Column(length = 50)
private String word;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
}
package com.cun.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.cun.bean.User;
/**
* 继承后面的接口,只是为了能进行搜索
* @author linhongcun
*
*/
public interface UserDao extends JpaRepository<User, Integer>,JpaSpecificationExecutor<User>{
}
package com.cun.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cun.bean.User;
import com.cun.dao.UserDao;
import com.cun.util.StringUtil;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserDao userDao;// 由于比较简单,省略了 service 层
/**
* 4、删除
* @param ids
* @return
*/
@ResponseBody
@RequestMapping("/delete")
public Map<String, Object> delete(@RequestParam(value = "ids") String ids) {
Map<String, Object> resultMap = new HashMap<String, Object>();
String[] idsStr = ids.split(",");
//for (int i = 0; i < ids.length; i++) {
for (int i = 0; i < idsStr.length(); i++) { // 2018.7.25 根据网友意见做出正确修改
userDao.delete(Integer.parseInt(idsStr[i]));
}
resultMap.put("success", true);
return resultMap;
}
/**
* 3、添加、修改
* @param user
* @return
*/
@ResponseBody
@RequestMapping("/save")
public Map<String, Object> save(User user) {
Map<String, Object> resultMap = new HashMap<String, Object>();
userDao.save(user);
resultMap.put("success", true);
return resultMap;
}
/**
* 2、显示
* @param page
* @param rows
* @return
*/
@ResponseBody
@RequestMapping("/list")
public Map<String, Object> list(User user, @RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "rows", required = false) Integer rows) {
Pageable pageable = new PageRequest(page-1, rows, Sort.Direction.ASC, "id");
Page<User> pageUser = userDao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// TODO Auto-generated method stub
Predicate predicate = cb.conjunction();
if (user != null) {
if (StringUtil.isNotEmpty(user.getName())) {
predicate.getExpressions().add(cb.like(root.get("name"), "%" + user.getName().trim() + "%"));
}
if (StringUtil.isNotEmpty(user.getWord())) {
predicate.getExpressions().add(cb.like(root.get("word"), "%" + user.getWord().trim() + "%"));
}
}
return predicate;
}
}, pageable);
// ①获取rows
List<User> list = pageUser.getContent();
// ②获取count
Long count = userDao.count(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// TODO Auto-generated method stub
Predicate predicate = cb.conjunction();
if (user != null) {
if (StringUtil.isNotEmpty(user.getName())) {
predicate.getExpressions().add(cb.like(root.get("name"), "%" + user.getName().trim() + "%"));
}
if (StringUtil.isNotEmpty(user.getWord())) {
predicate.getExpressions().add(cb.like(root.get("word"), "%" + user.getWord().trim() + "%"));
}
}
return predicate;
}
});
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("rows", list);
resultMap.put("total", count);
resultMap.put("success", true);
return resultMap;
}
/**
* 1、进入增删改查界面
* @return
*/
@RequestMapping("/crud")
public String crud() {
return "crud";
}
}
package com.cun.util;
/**
* 字符串工具类
* @author
*
*/
public class StringUtil {
/**
* 判断是否是空
* @param str
* @return
*/
public static boolean isEmpty(String str) {
if (str == null || "".equals(str.trim())) {
return true;
} else {
return false;
}
}
/**
* 判断是否不是空
* @param str
* @return
*/
public static boolean isNotEmpty(String str) {
if ((str != null) && !"".equals(str.trim())) {
return true;
} else {
return false;
}
}
}
<html>
<head>
<meta charset="UTF-8">meta>
<title>CRUDtitle>
<link rel="stylesheet" type="text/css" href="../jquery-easyui-1.3.3/themes/default/easyui.css" />
<link rel="stylesheet" type="text/css" href="../jquery-easyui-1.3.3/themes/icon.css" />
<script type="text/javascript" src="../jquery-easyui-1.3.3/jquery.min.js">script>
<script type="text/javascript" src="../jquery-easyui-1.3.3/jquery.easyui.min.js">script>
<script type="text/javascript" src="../jquery-easyui-1.3.3/locale/easyui-lang-zh_CN.js">script>
<script type="text/javascript" src="../my.js">script>
head>
<body>
<table id="dg" title="用户 CRUD 管理" class="easyui-datagrid" fitColumns="true" pagination="true" rownumbers="true" url="/user/list" fit="true" toolbar="#tb">
<thead>
<tr>
<th field="cb" checkbox="true" align="center">th>
<th field="id" width="100" align="center">编号th>
<th field="name" width="200" align="center">用户名th>
<th field="word" width="200" align="center">密码th>
tr>
thead>
table>
<div id="tb">
<div>
<a href="javascript:openLinkAddDialog()" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加a>
<a href="javascript:openLinkModifyDialog()" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改a>
<a href="javascript:deleteLink()" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除a>
div>
<div>
用户名: <input type="text" id="s_name" size="20" onkeydown="if(event.keyCode==13) searchWebSite()" /> 密码:
<input type="text" id="s_word" size="20" onkeydown="if(event.keyCode==13) searchWebSite()" />
<a href="javascript:searchWebSite()" class="easyui-linkbutton" iconCls="icon-search" plain="true">搜索a>
div>
div>
<div id="dlg" class="easyui-dialog" style="width: 500px;height: 200px;padding: 10px 20px" closed="true" buttons="#dlg-buttons">
<form id="fm" method="post">
<table cellspacing="8px">
<tr>
<td>用户名:td>
<td>
<input type="text" id="name" name="name" class="easyui-validatebox" required="true" />
td>
tr>
<tr>
<td>密码:td>
<td>
<input type="text" id="word" name="word" class="easyui-validatebox" required="true" />
td>
tr>
table>
form>
div>
<div id="dlg-buttons">
<a href="javascript:saveLink()" class="easyui-linkbutton" iconCls="icon-ok">保存a>
<a href="javascript:closeLinkDialog()" class="easyui-linkbutton" iconCls="icon-cancel">关闭a>
div>
body>
html>
/* 这个 url 经常要用到:add 中的 save,edit 中的 save,独立出来共享 */
var url;
/* 1、添加用户 */
function openLinkAddDialog() {
$("#dlg").dialog("open").dialog("setTitle", "添加友情链接信息");
url = "/user/save";
}
/* 2、修改用户 */
function openLinkModifyDialog() {
var selectedRows = $("#dg").datagrid("getSelections");
if(selectedRows.length != 1) {
$.messager.alert("系统提示", "请选择一条要编辑的数据!");
return;
}
var row = selectedRows[0];
/*EasyUI 回显信息*/
$("#fm").form("load", row);
$("#dlg").dialog("open").dialog("setTitle", "编辑友情链接信息");
url = "/user/save?id=" + row.id;
}
/* 3、删除用户 */
function deleteLink() {
var selectedRows = $("#dg").datagrid("getSelections");
if(selectedRows.length == 0) {
$.messager.alert("系统提示", "请选择要删除的数据!");
return;
}
var strIds = [];
/*SpringBoot 小于号要求*/
for(var i = 0; i < selectedRows.length; i++) {
strIds.push(selectedRows[i].id);
}
/* 转化 "1,2,3" 这种格式 */
var ids = strIds.join(",");
$.messager.confirm("系统提示", "您确定要删除这" + selectedRows.length + "条数据吗?", function(r) {
if(r) {
$.post("/user/delete", {
ids: ids
}, function(result) {
/* 后台传来一个true */
if(result.success) {
$.messager.alert("系统提示", "数据已成功删除!");
/*数据变动,需要重新加载数据,作用类似刷新网页*/
$("#dg").datagrid("reload");
} else {
$.messager.alert("系统提示", "数据删除失败,请联系管理员!");
}
}, "json");
}
});
}
/* save 保存操作,位于 add、edit 中 */
function saveLink() {
$("#fm").form("submit", {
url: url,
onSubmit: function() {
/*前端验证,再次使用EasyUI 提供的校验 class*/
return $(this).form("validate");
},
success: function(result) {
var result = eval('(' + result + ')');
/* 后台传来一个true */
if(result.success) {
$.messager.alert("系统提示", "保存成功!");
resetValue();
$("#dlg").dialog("close");
/*数据变动,需要重新加载数据,作用类似刷新网页*/
$("#dg").datagrid("reload");
}
}
});
}
/* 清空表单数据 */
function resetValue() {
$("#name").val("");
$("#word").val("");
}
/* 关闭对话框 */
function closeLinkDialog() {
resetValue();
$("#dlg").dialog("close");
}
/* 4、增加搜索 */
function searchWebSite() {
$("#dg").datagrid("load", {
"name": $("#s_name").val(),
"word": $("#s_word").val()
});
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.cungroupId>
<artifactId>SpringBootPagesartifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>warpackaging>
<name>SpringBootPagesname>
<description>Demo project for Spring Bootdescription>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.10.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
server:
port: 80 #为了以后访问项目不用写端口号
context-path: / #为了以后访问项目不用写项目名
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot
username: root
password: 123
jpa:
hibernate:
ddl-auto: update #数据同步代码
show-sql: true #数据库操作时,显示sql语句
1、在 SpringBoot 中使用 thymeleaf 常见的问题
① mata 标签没有后缀
② js 代码 的 <号、>号不能用
③ 拼接字符串如 "class=btn"
必须改为 "class='btn'"
④ 等等
2、为了避免 css、js 代码出现的问题,建议把 css、js 分别写成外部的 style、script 标签引入,这样就可以把它们放入 static 中,在里边不会被按照 html5 严格检查,减少不必要的报错,否则一不留神就报错。
3、降低 JS 格式要求,在 /* 和
/*]]>*/
中编写 JS
代码
<script type="text/javascript">
/*
xxxxxxxxxxxxxxxxx
/*]]>*/
script>
4、使用高版本的 thymeleaf、thymeleaf-layout
写一下版本号即可
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleafartifactId>
<version>3.0.9.RELEASEversion>
dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleafgroupId>
<artifactId>thymeleaf-layout-dialectartifactId>
<version>2.3.0version>
dependency>