SpringBoot+Thymeleaf+MyBatis 实现RESTful API

1.项目结构

2.创建数据库表

这里使用MySQL5.7。

CREATE TABLE `user` (
  `id` int(13) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(33) DEFAULT NULL COMMENT '姓名',
  `age` int(3) DEFAULT NULL COMMENT '年龄',
  `createTime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3.代码详解

引入Thymeleaf、SpringBoot整合mybatis的jar包、mysql的驱动包。

<!-- pom.xml -->
<!-- ... -->
<dependencies>
    <!-- ... -->
	
    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>1.3.2</version>
    </dependency>
    <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.38</version><!--$NO-MVN-MAN-VER$-->
    </dependency>
</dependencies>
<!-- ... -->
# application.properties
server.port=8081
server.servlet.context-path=/restful-demo
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.check-template-location=true
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
spring.datasource.url=jdbc:mysql://localhost:3306/restful_sql?useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.mvc.hiddenmethod.filter.enabled=true
mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath:mapper-mapping/*.xml
logging.level.com.example.demo.mapper=debug

spring.thymeleaf.*是Thymeleaf相关的配置,spring.datasource.*是连接数据库相关的配置。
spring.mvc.hiddenmethod.filter.enabled=true启用HiddenHttpMethodFilter,以允许PUT请求或者DELETE请求。
mybatis.config-location=classpath:mybatis-config.xml指定mybatis的配置文件。
mybatis.mapper-locations=classpath:mapper-mapping/*.xml指定mybatis的映射文件。
logging.level.com.example.demo.mapper=debug配置打印包com.example.demo.mapper的日志。

实体类:

package com.example.demo.model;

import java.time.LocalDateTime;

import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.annotation.JsonFormat;

public class User {
    private Integer id;
    private String name;
    private int age;
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private LocalDateTime createTime;
    
    // setter and getter
    
}

Controller:

package com.example.demo.controller;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.example.demo.model.User;
import com.example.demo.service.UserService;

@Controller
public class UserController {
    @Autowired
    private UserService userService;
	
    @ModelAttribute
    public void getUserById(@RequestParam(value="id",required=false) Integer id, Model model){
          if (id != null) {
                User user = userService.getUserById(id);
                if(user != null) {
                      model.addAttribute("user", user);
                }
          }
    }

    // ...
	
    @RequestMapping("/index2")
    public ModelAndView index2(){
          ModelAndView modelAndView = new ModelAndView("user/index2");
          // modelAndView.addObject("users", userService.findAll());
          return modelAndView;
    }
	
    @ResponseBody
    @RequestMapping("/getUsers")
    public Map<String, Object> getUsers(HttpServletRequest request){
          int pageNO = Integer.parseInt(request.getParameter("page"));// 当前页
          int pageSize = Integer.parseInt(request.getParameter("rows"));// 每页行数
          Map<String, Object> params = new HashMap<>();
          params.put("name", request.getParameter("name"));
          return userService.getUsers(pageNO, pageSize, params);
    }
	
    /*
     ** Restful API设计
        /user          POST	保存
        /user/{id}     PUT      更新
        /user/{id}     GET      查询
        /user/{id}     DELETE	删除
    */
    @ResponseBody
    @RequestMapping(value="/user", method=RequestMethod.POST)
    public String saveUser(User user){
          user.setCreateTime(LocalDateTime.now());
          userService.saveUser(user);
          return "success";
    }
	
    @ResponseBody
    @RequestMapping(value="/user/{id}", method=RequestMethod.PUT)
    public String updateByPrimaryKey(@PathVariable("id") Integer id, @ModelAttribute("user") User user){
          // 参数中的id值已经封装到User对象里面,而且这里借助@ModelAttribute使得修改不会影响User对象的其他字段值,而只修改表单中提交的字段值。
          userService.updateByPrimaryKey(user);
          return "success";
    }
	
    @ResponseBody
    @RequestMapping(value="/user/{id}", method=RequestMethod.GET)
    public User getUserById(@PathVariable("id") Integer id){
          return userService.getUserById(id);
    }
	
    @ResponseBody
    @RequestMapping(value="/user/{id}", method=RequestMethod.DELETE)
    public String deleteUserById(@PathVariable("id") Integer id){
          userService.deleteByPrimaryKey(id);
          return "success";
    }
}

Service:

package com.example.demo.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.mapper.UserMapper;
import com.example.demo.mapper.UserMapper2;
import com.example.demo.model.User;

@Transactional
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserMapper2 userMapper2;
	
    // ...

    public Map<String, Object> getUsers(int pageNO, int pageSize, Map<String, Object> params) {
          List<User> users = userMapper2.getUsers(params);
          int count = 0;
          if(users.size()>=1){
                count = users.size();
                int fromIndex = (pageNO-1)*pageSize;
                int toIndex = pageNO*pageSize;
                users = users.subList(fromIndex, count>toIndex?toIndex:count); // 分页
          }
          Map<String, Object> map = new HashMap<>();
          map.put("rows", users);
          map.put("total", count);
          return map;
    }

    public User getUserById(Integer id) {
          return userMapper.getUserById(id);
    }

    public void saveUser(User user) {
          userMapper2.insert(user);
    }

    public void updateByPrimaryKey(User user) {
          userMapper2.updateByPrimaryKey(user);
    }

    public void deleteByPrimaryKey(Integer id) {
          userMapper2.deleteByPrimaryKey(id);
    }
	
}

Mapper:

@Mapper
public interface UserMapper2 {
    List<User> getUsers(Map<String, Object> params);

    void insert(User user);

    void updateByPrimaryKey(User user);

    void deleteByPrimaryKey(Integer id);

    @Select("SELECT * FROM User u WHERE u.id = #{id}")
    User getUserById(@Param("id") Integer id);

}

注解@Mapper标注的类可以被其他类通过@Autowired注入。
可以直接在接口上面通过注解@Select来写SQL,也可以通过映射文件来写SQL。
mybatis映射文件:

<!-- UserMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.mapper.UserMapper2">
    <select id="getUsers" parameterType="Map" resultType="com.example.demo.model.User">
          select * from user u where 1=1
          <if test="name!=null">
                and u.name like concat('%',#{name},'%')
          </if>
    </select>
	
    <insert id="insert" parameterType="com.example.demo.model.User" >
          insert into user (name, age, createTime) values (#{name}, #{age}, #{createTime})
    </insert>
    <update id="updateByPrimaryKey" parameterType="com.example.demo.model.User" >
          update user set name = #{name}, age = #{age} where id = #{id}
    </update>
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
          delete from user where id = #{id}
    </delete>
</mapper>

HTML页面:

<!-- index2.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<script th:src="@{/jquery-easyui/jquery.min.js}"></script>
<script th:src="@{/jquery-easyui/jquery.easyui.min.js}"></script>
<script th:src="@{/jquery-easyui/locale/easyui-lang-zh_CN.js}"></script>
<link rel="stylesheet" type="text/css" th:href="@{/jquery-easyui/themes/default/easyui.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/jquery-easyui/themes/icon.css}" />
<style>
    input[class^="easyui-"] {
          width: 160px;
    }
    #toolbar,
    .userForm {
          font-size:1rem;
    }
    #toolbar>p {
          margin:0;
          margin-top:1em;
          margin-left:1em;
          margin-bottom:.5em;
    }
    #toolbar>p label,
    .userForm label {
          margin-right:1em;
    }
    .userForm p {
          width:50%;
          margin-left:auto;
          margin-right:auto;
    }
    #toolbar .button {
          margin-left:1em;
          margin-bottom:.5em;
    }
    .saveButton {
          text-align:center;
          margin-top:1em;
          margin-bottom:1em;
    }
</style>
<title>User Index</title>
</head>
<body>
<table id="users"></table>
<div id="toolbar">
    <p><label for="name_s">名称</label><input class="easyui-searchbox" id="name_s" /></p>
    <div class="button">
          <a class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true" onclick="addUser()">添加</a>
          <a class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true" onclick="editUser()">修改</a>
          <a class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true" onclick="removeUser()">删除</a>
    </div>
</div>
<div class="easyui-dialog" data-options="closed:true,modal:true" id="userDialog" style="width:450px;">
<div class="userForm">
    <form id="userForm" method="post">
          <input id="id" name="id" type="hidden" />
          <p><label for="name">名称</label><input class="easyui-textbox" id="name" name="name" data-options="required:true" /></p>
          <p><label for="age">年龄</label><input class="easyui-numberbox" id="age" name="age" data-options="required:true,min:0" /></p>
    </form>
    <div class="saveButton">
          <a class="easyui-linkbutton" data-options="iconCls:'icon-save'" onclick="saveUser()" id="save">保存</a>
    </div>
</div>
</div>
<script th:inline="javascript">
    var basePath = /*[[${#request.getContextPath()}]]*/ "http://localhost:8081/restful-demo";
</script>
<!-- 下面使用"th:inline='none'",避免报错! -->
<script th:inline="none">
$(function(){
    $('#users').datagrid({
          url:basePath+'/getUsers',
          rownumbers:true,
          pagination:true,
          singleSelect:true,
          pageNumber:1,
          pageSize:5,
          pageList:[5,10,15],
          toolbar : '#toolbar',
          columns:[[
                {
                      field:'id',
                      title:'ID',
                      width:100
                },
                {
                      field:'name',
                      title:'名称',
                      width:100
                },
                {
                      field:'age',
                      title:'年龄',
                      width:100
                },
                {
                      field:'createTime',
                      title:'创建时间',
                      width:150,
                      align:'center',
                      formatter:function (value) {
                            return value?`<span title="${value}">${value}</span>`:'';
                      }
                },
                ]]
          });
	
          $('#name_s').searchbox({
                searcher:function(value){
                      $('#users').datagrid('load',{
                            name: value,
                      });
                }
          });
	
          $('#userForm').form({
                onLoadSuccess: function(data){
                      if(data){
                            // 当加载完表单数据后,才启用保存按钮。
                            $('#save').linkbutton('enable');
                }
          }
    });
});

function addUser(){
    $('#userDialog').panel('setTitle', '添加用户').dialog('center').dialog('open');
}

async function editUser(){
    var row = $("#users").datagrid('getSelected');
    if(row){
          $('#save').linkbutton('disable');
          var user = await $.get(basePath+'/user/'+row.id);
          $('#userForm').form('load', user);
          $('#userDialog').panel('setTitle', '修改用户').dialog('center').dialog('open');
    } else {
          $.messager.alert('警告操作!', '请选择一条记录!', 'info');
    }
}

function removeUser(){
    var row = $("#users").datagrid('getSelected');
    if(row){
          $.messager.confirm('确认操作', "确定要删除选中的记录?", function (flag) {
                if(flag){
                      $.post(basePath+'/user/'+row.id,{_method:'DELETE'},function (data) {
                            if(data==="success"){
                                  $.messager.alert('提示信息', '删除成功!','info');
                                  $('#users').datagrid('reload');
                            } else {
                                  $.messager.alert('提示信息','删除失败!','info');
                            }
                      });
                }
          });
    } else {
        $.messager.alert('警告操作!', '请选择一条记录!', 'info');
    }
}

function saveUser(){
    var url = basePath+'/user';
    var id = $('#id').val();
    if(id){
          url += "/"+id;
    }
    $('#userForm').form('submit',{
          url: url,
          onSubmit: function(param){
                if(id){
                      param._method='PUT';
                }
                return $(this).form('enableValidation').form('validate');
          },
          success: function(data){
                if(data==="success"){
                      clearForm();
                      $("#users").datagrid('reload');
                      $.messager.alert('提示信息','保存成功!','info');
                }
          }
    });
}

function clearForm(){
    $('#userForm').form('clear');
    $('#userDialog').dialog('close');
}
</script>
</body>
</html>

HTML页面使用了Thymeleaf的语法和EasyUI框架。
展示页面:



示例代码下载地址:https://pan.baidu.com/s/17Kq4gUrUh160jr3fLTSjKg(提取码:r14t)

posted @ 2020-09-02 14:55  gzhjj  阅读(1396)  评论(0编辑  收藏  举报