SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD

一、前言

一直在探索自己最喜欢(最简单)的 CRUD+分页,前面写过很多了,代码基本都是由前面进化而来的,而且也是越来越简单,JS 代码也是越来越规范简洁

1、Servlet+EasyUI+MySQL

2、Spring+SpringMVC+MyBatis+pageHelper

下面来个

3、SpringBoot+EasyUI+MySQL

二、CRUD功能演示

1、分页

SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD_第1张图片

2、增加

SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD_第2张图片

3、查找

SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD_第3张图片

4、修改

SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD_第4张图片

5、删除

SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD_第5张图片

三、代码实现

1、代码关系结构:

由于比较简单

①entity、②dao、③service、④controller 四层中省略了 ③service 层

SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD_第6张图片

2、entity 层

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;
	}
}

3、dao 层

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>{
	

}

4、controller 层

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";
	}

}

5、工具

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;
		}
	}

}

6、界面

① html

<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>
② js
/* 这个 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()
	});
}

7、pom


<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>

8、application.yml

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>

你可能感兴趣的:(SpringBoot+JPA+EasyUI+MySQL+thymeleaf 基本 CURD)