Spring Boot CMS 开发实践
前言
在实际工作中入手,如何快速的开发一个后台管理系统呢?技术选型是啥?作为 Java 程序员,Spring Boot 使用者可以一起交流下这块如何整合?如何搭建?如何使用?
我们这篇 Chat 的中心是把实战经验给大家分享一下。主要是实际操作,完成整体认识。先介绍下技术选型:
具体开发步骤如下:
- 配置依赖
- 整合 Layui
- 整合 Mybatis
- 编写案例代码
- 实现 OSS 文件上传
配置依赖
不懂创建 Spring Boot ,没有入门的看这个 《Spring Boot 2.0 的快速入门(图文教程)》http://gitbook.cn/gitchat/activity/5a4c47bf31d9b852d33dec90。恩,还有这个《Spring Boot 2.0 的配置详解(图文教程)》http://gitbook.cn/gitchat/activity/5a69a12f0b172b546f92f26c
打开一个基本的 pom.xml 配置,增加依赖配置如下:
<dependencies>
<!-- Spring Boot Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Test 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot Mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- MyBatis 分页 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<!-- MySQL 连接驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Lombok 插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- FastJson 插件 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.7</version>
</dependency>
<!-- OSS 文件 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
配置如下:
- spring-boot-starter-web 是用来编写 web 项目
- mybatis-spring-boot-starter Mybatis 依赖和 pagehelper-spring-boot-starter Mybatis 分页依赖,可以快速的实现数据的 ORM 操作
- spring-boot-starter-thymeleaf 前端模板引擎
- Lombok 插件、FastJson 插件 、OSS 文件 SDK 就不详细介绍了
在 resources 增加 generatorConfig.xml 文件,配置参考:http://www.mybatis.org/generator/running/runningWithMaven.html
mybatis-generator-maven-plugin 可以利用 Maven 插件快速生产 ORM 需要的实体类和操作接口。如图:
整合 Layui
在 static 目录新增如下目录,并添加对应的 js。如图:
对应的 js 下载地址如下:
- jquery 我就不说了,自己找
- layui http://www.layui.com/
- treegrid http://fly.layui.com/jie/11172/
还有待会要写的 userDeliveryList.js ,待会再说。最后需要添加一些公共的 HTML ,引用这些 JS 依赖。在 templates 目录添加如下文件,如图:
head.html 就是顶部和左侧菜单的封装,因为本次后台的实现是基于 fragment 的。所以菜单的定义需要在这里实现。
footer.html 代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<footer th:fragment="footer">
<div class="layui-footer">
<!-- 底部固定区域 -->
<a href="http://gitbook.cn/">Copyright © gitbook.cn 2018</a>
</div>
</footer>
</body>
</html>
userDeliveryList.html 是案例代码,后面会讲到
整合 Mybatis
整合 Mybatis 需要新建一个库表: demo,然后新增表 user_delivery 用户收获地址:
CREATE TABLE `user_delivery` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '收货地址id',
`user_id` int(11) DEFAULT NULL COMMENT '用户id',
`contact` varchar(255) DEFAULT '' COMMENT '收货人姓名',
`tel` varchar(255) DEFAULT '' COMMENT '收货人电话',
`id_card_num` varchar(100) NOT NULL DEFAULT '' COMMENT '身份证号',
`province` varchar(255) DEFAULT '' COMMENT '收货地址:省',
`city` varchar(255) DEFAULT '' COMMENT '收货地址:城市',
`county` varchar(255) DEFAULT '' COMMENT '收货地址:县/区',
`address` varchar(255) DEFAULT '' COMMENT '收货地址 详细地址',
`default_status` tinyint(4) DEFAULT '0' COMMENT '默认收货地址标志 0 否 1 是',
`status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '是否标记删除 0:否 1:是',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户收货地址表'
在 application.properties 配置如下:
## 静态资源
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/
## 数据源配置
spring.datasource.url=jdbc:mysql:// 数据库地址
spring.datasource.username=数据库登录名
spring.datasource.password=数据库登录密码
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
## MyBatis 配置
mybatis.typeAliasesPackage=xxxxx 包名
mybatis.mapperLocations=classpath:mapper/*.xml
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
然后利用 mybatis-generator-maven-plugin 插件在对应的包目录,生成如下。
resouces/mapper 目录生成了 UserDeliveryMapper.xml
对应的 包换下。然后对应的包下会生成 三个类,UserDelivery 对象、 UserDeliveryExample 查询对象和 UserDeliveryMapper 操作接口类。
编写案例代码
自动的工作带来很大的便捷,下面实现这个 CRUD 分页。实现非常简单,三步走:
- 编写 userDeliveryList.html 对应的页面
- 编写 userDeliveryList.js 对应的 JS
- 编写 UserDeliveryController 和 UserDeliveryService 控制层和逻辑层
编写 userDeliveryList.html 对应的页面。
这里实现了 搜索 和 列表、并隐藏了一个 id 为 editUserDelivery 的 DIV 用于弹框显示编辑页面。
编写 userDeliveryList.js 对应的 JS。
利用 layui.table 实现了带搜索的分页,监听栏实现编辑表单和删除。代码分块清晰简单。最后看看 java 逻辑的实现。
编写 UserDeliveryController 和 UserDeliveryService 控制层和逻辑层,代码如下:
public class BaseController {
public static final String SUCCESS = "200";
public static final String ERROR = "操作出错,请您稍后再试";
public static final Integer SUCCESS_CODE = 200;
public static final Integer ERROR_CODE = 500;
}
@Controller
@RequestMapping("/userDelivery")
public class UserDeliveryController extends BaseController {
@Autowired
private UserDeliveryService userDeliveryService;
@GetMapping(value = "/list")
public ModelAndView listView() {
ModelAndView mav = new ModelAndView("user/userDeliveryList");
return mav;
}
@GetMapping(value = "/page")
@ResponseBody
public PageInfo<UserDelivery> page(
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "15") Integer pageSize,
UserDelivery userDeliverySearch) {
PageInfo<UserDelivery> pageInfo = new PageInfo<UserDelivery>();
try {
pageInfo = userDeliveryService.page(pageNum, pageSize, userDeliverySearch);
pageInfo.setPages(SUCCESS_CODE);
return pageInfo;
} catch (Exception e) {
e.printStackTrace();
}
pageInfo.setPages(ERROR_CODE);
return pageInfo;
}
@GetMapping(value = "/get")
@ResponseBody
public UserDelivery get(@RequestParam("id") Integer id) {
try {
UserDelivery userDelivery = userDeliveryService.getById(id);
return userDelivery;
} catch (Exception e) {
}
return new UserDelivery();
}
@PostMapping(value = "/edit")
@ResponseBody
public String edit(UserDelivery userDelivery) {
try {
userDeliveryService.edit(userDelivery);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
}
return ERROR;
}
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public String delete(@RequestParam("id") Integer id) {
try {
userDeliveryService.delete(id);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
}
return ERROR;
}
}
/list 是页面入口
/page 实现了搜索分页查询
/get 、 /edit 、 /delete 顾名思义
逻辑层代码如下:
@Service
public class UserDeliveryService {
@Autowired
private UserDeliveryMapper userDeliveryMapper;
public PageInfo<UserDelivery> page(Integer pageNum, Integer pageSize, UserDelivery userDeliverySearch) {
UserDeliveryExample userDeliveryExample = new UserDeliveryExample();
userDeliveryExample.setOrderByClause("id DESC");
UserDeliveryExample.Criteria criteria = userDeliveryExample.createCriteria();
if (!StringUtils.isEmpty(userDeliverySearch.getContact())) {
criteria.andContactLike("%" + userDeliverySearch.getContact() + "%");
}
criteria.andStatusEqualTo((byte) 0);
// 第几页, 多少条数据
PageHelper.startPage(pageNum, pageSize);
List<UserDelivery> userDeliveryList = userDeliveryMapper.selectByExample(userDeliveryExample);
PageInfo pageInfo = new PageInfo(userDeliveryList);
return pageInfo;
}
public UserDelivery getById(Integer id) {
return userDeliveryMapper.selectByPrimaryKey(id);
}
public void edit(UserDelivery userDelivery) {
// 保存或更新
if (userDelivery.getId().equals(0)) {
userDelivery.setStatus((byte) 0);
userDelivery.setCreateTime(new Date());
userDelivery.setUpdateTime(new Date());
userDeliveryMapper.insertSelective(userDelivery);
} else {
userDeliveryMapper.updateByPrimaryKeySelective(userDelivery);
}
}
public void delete(Integer id) {
userDeliveryMapper.deleteByPrimaryKey(id);
}
}
运行工程方式很简单,使用 IDEA 右侧工具栏,点击 Maven Project Tab ,点击使用下 Maven 插件的 install
命令。或者使用命令行的形式,在工程根目录下,执行 Maven 清理和安装工程的指令:
cd xxx 工程目录
mvn clean install
在控制台中看到成功的输出:
... 省略
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:30 min
[INFO] Finished at: 2017-10-15T10:00:54+08:00
[INFO] Final Memory: 31M/174M
[INFO] ------------------------------------------------------------------------
运行工程
在 IDEA 中执行 Application
类启动,任意正常模式或者 Debug 模式。可以在控制台看到成功运行的输出:
... 省略
2018-04-10 08:43:39.932 INFO 2052 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext : Started HttpServer on /0:0:0:0:0:0:0:0:8080
2018-04-10 08:43:39.935 INFO 2052 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
2018-04-10 08:43:39.960 INFO 2052 --- [ main] org.spring.springboot.Application : Started Application in 6.547 seconds (JVM running for 9.851)
访问 http://localhost:8080/userDelivery/list ,可以看到如下页面:
点击创建,如图:
实现 OSS 文件上传
文件上传其实原理很简单,配合 uploadFile.js 工具,我们只需要在对应的 HTML 写上,对应的代码即可:
<div class="layui-form-item" id="couponBlockHide2">
<label class="layui-form-label">图片</label>
<div class="layui-input-inline">
<button type="button" class="layui-btn" id="upload">
<i class="layui-icon"></i>选择文件
</button>
<div class="layui-row" align="center" style="margin-top: 30px;">
<div class="layui-upload-list" id="imageView"></div>
<input id="image" name="image" type="hidden"/>
</div>
</div>
</div>
文件控制器代码很简单:
@Controller
@RequestMapping("file")
public class FileController {
@Autowired
private FileService fileService;
@PostMapping(value = "/upload")
@ResponseBody
public FileResult uploadUEditorFile(
@RequestParam(value = "upFile") MultipartFile multipartFile) {
return fileService.uploadFile(multipartFile);
}
}
OSS 封装参考其 SDK
总结
这里,探讨了后端开发 CMS 管理系统技术选型
- Spring Boot - 内嵌 Web 容器,启动部署方便
- Thymleaf - 推荐模板引擎
- Layui - 后台管理系统模板框架(JQ、UEditor、treegrid )
- MySQL
- MyBatis - 外加两个神器分页插件和自动生成代码
- FastJson
- 云服务:七牛、OSS 随便挑
有些朋友告诉我使用 Spring Data REST 依赖会更快的实现 CRUD,确实如此。但是我认为那个版本还是很低,建议还是自己实现 ORM DAL 层。
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击