源码地址:https://codechina.csdn.net/wwwzhouzy/springboot-ssm
先看看项目启动,访问页面的效果图:
需要注意的地方 :
1、引入layui相关资源文件时注意路径,尤其是引用Thymeleaf标签时
静态资源默认从static目录下查找
2、注意json传送数据的编码问题,不然会有乱码
继承WebMvcConfigurationSupport类,重写方法:
@Bean
public HttpMessageConverter<String> responseBodyConverter() {
return new StringHttpMessageConverter(Charset.forName("UTF-8"));
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
converters.add(responseBodyConverter());
}
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
// 解决controller返回普通文本中文乱码问题
if (converter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
}
// 解决controller返回json对象中文乱码问题
if (converter instanceof MappingJackson2HttpMessageConverter) {
((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
}
}
}
3、我用的mysql5.0版本,所以springboot采用了2.0.5
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
一、项目架构
二、核心代码
1、pom引包
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>com.zhouzy.ssm</groupId>
<artifactId>zhouzySsm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zhouzySsm</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<!--修改jdk版本号-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>
<dependencies>
<!-- web模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thmeleaf模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</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>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.30</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、配置文件
application.yml
server:
port: 8080
spring:
application:
mame: ssm
thymeleaf:
prefix: classpath:/templates/
cache: false
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/zhouzy?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
type-aliases-package: com.zhouzy.ssm.model
#showSql
logging:
level:
com:
example:
mapper : debug
3、html文件
userList.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>layout 后台大布局 - Layui</title>
<link rel="stylesheet" href="/css/layui.css">
<script src="/layui.js" type="text/javascript"></script>
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">layui 后台布局</div>
<!-- 头部区域(可配合layui已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<li class="layui-nav-item"><a href="">用户</a></li>
<li class="layui-nav-item"><a href="">控制台</a></li>
<li class="layui-nav-item"><a href="">商品管理</a></li>
<li class="layui-nav-item">
<a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<dd><a href="">邮件管理</a></dd>
<dd><a href="">消息管理</a></dd>
<dd><a href="">授权管理</a></dd>
</dl>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<img src="https://profile.csdnimg.cn/6/D/2/0_wwwzhouzy" class="layui-nav-img">
wwwzhouzy
</a>
<dl class="layui-nav-child">
<dd><a href="">基本资料</a></dd>
<dd><a href="">安全设置</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">用户列表</a>
</li>
<li class="layui-nav-item">
<a href="javascript:;">解决方案</a>
</li>
<li class="layui-nav-item"><a href="">云市场</a></li>
<li class="layui-nav-item"><a href="">发布商品</a></li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<table class="layui-hide" id="userList" lay-filter="userList"></table>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
© layui.com - 底部固定区域
</div>
</div>
<script type="text/javascript" th:inline="none">
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#userList'
,url:'/user/listData'
,cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
,cols: [[
{field:'id', width:80, title: 'ID', sort: true}
,{field:'name', width:80, title: '用户名'}
,{field:'sex', width:80, title: '性别', sort: true,templet: function (d){
var sex = d.sex;
if(sex == 0){
return '男';
}else if(sex == 0){
return '女';
}else{
return '未知';
}
}}
,{field:'address', width:80, title: '地址'}
,{field:'mobile', title: '手机号', width: '30%', minWidth: 100} //minWidth:局部定义当前单元格的最小宽度,layui 2.2.1 新增
,{field:'age', title: '年龄', sort: true}
,{field:'createTime', title: '创建时间', sort: true,templet : "<div>{{layui.util.toDateString(d.createTime, 'yyyy年-MM月-dd日 HH:mm:ss')}}</div>"}
]]
});
});
</script>
</body>
</html>
4、mybatis映射文件
<?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.zhouzy.ssm.mapper.UserInfoMapper">
<resultMap id="BaseResultMap" type="com.zhouzy.ssm.model.UserInfo" >
<result column="id" property="id" />
<result column="name" property="name" />
<result column="age" property="age" />
<result column="sex" property="sex" />
<result column="address" property="address" />
<result column="mobile" property="mobile" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
id,
name,
age,
sex,
address,
mobile,
create_time,
update_time
</sql>
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id" parameterType="com.zhouzy.ssm.model.UserInfo">
INSERT INTO t_user_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="null != name and '' != name">
name,
</if>
<if test="null != age and '' != age">
age,
</if>
<if test="null != sex and '' != sex">
sex,
</if>
<if test="null != address and '' != address">
address,
</if>
<if test="null != mobile and '' != mobile">
mobile,
</if>
<if test="null != createTime and '' != createTime">
create_time,
</if>
<if test="null != updateTime and '' != updateTime">
update_time
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="null != name and '' != name">
#{name},
</if>
<if test="null != age and '' != age">
#{age},
</if>
<if test="null != sex and '' != sex">
#{sex},
</if>
<if test="null != address and '' != address">
#{address},
</if>
<if test="null != mobile and '' != mobile">
#{mobile},
</if>
<if test="null != createTime and '' != createTime">
#{createTime},
</if>
<if test="null != updateTime and '' != updateTime">
#{updateTime}
</if>
</trim>
</insert>
<delete id="delete" >
DELETE FROM t_user_info
WHERE id = #{id}
</delete>
<update id="update" parameterType="com.zhouzy.ssm.model.UserInfo">
UPDATE t_user_info
<set>
<if test="null != name and '' != name">name = #{name},</if>
<if test="null != age and '' != age">age = #{age},</if>
<if test="null != sex and '' != sex">sex = #{sex},</if>
<if test="null != address and '' != address">address = #{address},</if>
<if test="null != mobile and '' != mobile">mobile = #{mobile},</if>
<if test="null != createTime and '' != createTime">create_time = #{createTime},</if>
<if test="null != updateTime and '' != updateTime">update_time = #{updateTime}</if>
</set>
WHERE id = #{id}
</update>
<select id="load" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM t_user_info
WHERE id = #{id}
</select>
<select id="pageList" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM t_user_info
LIMIT #{offset}, #{pageSize}
</select>
<select id="pageListCount" resultType="java.lang.Integer">
SELECT count(1)
FROM t_user_info
</select>
</mapper>
5、mvc配置类
package com.zhouzy.ssm.config;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
//通过重写配置方法覆盖
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mapper/**").addResourceLocations("classpath:/mapper/");//mapper.xml
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/templates/");
super.addResourceHandlers(registry);
}
@Bean
public HttpMessageConverter<String> responseBodyConverter() {
return new StringHttpMessageConverter(Charset.forName("UTF-8"));
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
converters.add(responseBodyConverter());
}
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
// 解决controller返回普通文本中文乱码问题
if (converter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
}
// 解决controller返回json对象中文乱码问题
if (converter instanceof MappingJackson2HttpMessageConverter) {
((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
}
}
}
}
6、启动类
package com.zhouzy.ssm;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.zhouzy.ssm.mapper") //扫描的mapper
@SpringBootApplication
public class Webapplication {
public static void main(String[] args) {
SpringApplication.run(Webapplication.class, args);
}
}
7、控制层
package com.zhouzy.ssm.controller;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.zhouzy.ssm.model.DataGrid;
import com.zhouzy.ssm.model.PageInfo;
import com.zhouzy.ssm.model.UserInfo;
import com.zhouzy.ssm.service.UserInfoService;
@Controller
@RequestMapping("/user")
public class UserInfoController {
@Resource
private UserInfoService userInfoService;
/**
* 新增
* @author zhouzhiyao
* @date 2021/08/03
**/
@RequestMapping("/insert")
public void insert(UserInfo userInfo){
userInfoService.insert(userInfo);
}
/**
* 刪除
* @author zhouzhiyao
* @date 2021/08/03
**/
@RequestMapping("/delete")
public void delete(int id){
userInfoService.delete(id);
}
/**
* 更新
* @author zhouzhiyao
* @date 2021/08/03
**/
@RequestMapping("/update")
public void update(UserInfo userInfo){
userInfoService.update(userInfo);
}
/**
* 查询 根据主键 id 查询
* @author zhouzhiyao
* @date 2021/08/03
**/
@RequestMapping("/load")
public Object load(int id){
return userInfoService.load(id);
}
/**
* 查询 分页查询
* @author zhouzhiyao
* @date 2021/08/03
**/
@RequestMapping("/list")
public String pageList() {
return "user/userList";
}
/**
* 查询 分页查询
* @author zhouzhiyao
* @date 2021/08/03
**/
@SuppressWarnings("unchecked")
@RequestMapping("/listData")
@ResponseBody
public String listData(PageInfo page) {
int pageNum = page.getPage();
int size = page.getLimit();
Map<String,Object> map = userInfoService.pageList((pageNum-1)*size, size);
List<UserInfo> data = (List<UserInfo>)map.get("data");
int count = (Integer)map.get("count");
DataGrid<UserInfo> grid = new DataGrid<UserInfo>(data,count,0,null);
return JSONObject.toJSONString(grid);
}
}
8、service层
package com.zhouzy.ssm.service;
import java.util.Map;
import com.zhouzy.ssm.model.UserInfo;
/**
* @description 用户信息表
* @author zhouzhiyao
* @date 2021-08-03
*/
public interface UserInfoService {
/**
* 新增
*/
public void insert(UserInfo userInfo);
/**
* 删除
*/
public void delete(int id);
/**
* 更新
*/
public void update(UserInfo userInfo);
/**
* 根据主键 id 查询
*/
public UserInfo load(int id);
/**
* 分页查询
*/
public Map<String,Object> pageList(int offset, int pagesize);
}
package com.zhouzy.ssm.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.zhouzy.ssm.mapper.UserInfoMapper;
import com.zhouzy.ssm.model.UserInfo;
import com.zhouzy.ssm.service.UserInfoService;
/**
* @description 用户信息表
* @author zhouzhiyao
* @date 2021-08-03
*/
@Service
public class UserInfoServiceImpl implements UserInfoService {
@Resource
private UserInfoMapper userInfoMapper;
public void insert(UserInfo userInfo) {
userInfoMapper.insert(userInfo);
}
public void delete(int id) {
userInfoMapper.delete(id);
}
public void update(UserInfo userInfo) {
userInfoMapper.update(userInfo);
}
public UserInfo load(int id) {
return userInfoMapper.load(id);
}
public Map<String,Object> pageList(int offset, int pagesize) {
List<UserInfo> pageList = userInfoMapper.pageList(offset, pagesize);
int totalCount = userInfoMapper.pageListCount();
// result
Map<String, Object> result = new HashMap<String, Object>();
result.put("data", pageList);
result.put("count", totalCount);
return result;
}
}
9、mapper层
package com.zhouzy.ssm.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.zhouzy.ssm.model.UserInfo;
/**
* @description 用户信息表
* @author zhouzhiyao
* @date 2021-08-03
*/
@Repository
public interface UserInfoMapper {
/**
* 新增
* @author zhouzhiyao
* @date 2021/08/03
**/
int insert(UserInfo userInfo);
/**
* 刪除
* @author zhouzhiyao
* @date 2021/08/03
**/
int delete(int id);
/**
* 更新
* @author zhouzhiyao
* @date 2021/08/03
**/
int update(UserInfo userInfo);
/**
* 查询 根据主键 id 查询
* @author zhouzhiyao
* @date 2021/08/03
**/
UserInfo load(int id);
/**
* 查询 分页查询
* @author zhouzhiyao
* @date 2021/08/03
**/
List<UserInfo> pageList(@Param("offset")int offset,@Param("pageSize")int pageSize);
/**
* 查询 分页查询 count
* @author zhouzhiyao
* @date 2021/08/03
**/
int pageListCount();
}
10、mdelo对象
实体类
package com.zhouzy.ssm.model;
import java.io.Serializable;
import java.util.Date;
/**
* @description 用户信息表
* @author zhouzhiyao
* @date 2021-08-03
*/
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
* 姓名
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 年龄
*/
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
/**
* 性别:0:男 1:女
*/
private Integer sex;
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
/**
* 地址
*/
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
/**
* 手机号
*/
private String mobile;
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
/**
* 创建时间
*/
private Date createTime;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 更新时间
*/
private Date updateTime;
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public UserInfo() {}
}
layui表格对应的对象类
package com.zhouzy.ssm.model;
import java.io.Serializable;
import java.util.List;
public class DataGrid<T> implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int code;
private String msg;
private List<T> data;
private int count;
public DataGrid(){
}
public DataGrid(List<T> data,int count,int code,String msg){
this.data = data;
this.count = count;
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
package com.zhouzy.ssm.model;
public class PageInfo {
private int page = 1;
private int limit = 20;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}
11、layui文件
需要从layui官网下载对应的资源文件 ,放入resources/static目录下