Spring Boot(5)一个极简且完整的后台框架
一个完整的极简后台框架,方便做小项目的时候可以快速开发。
这里面多贴图片和代码,做个参考吧,代码可以下载下来自己看看,里面这套后台模板不错,喜欢的拿去。
先放几张图
项目介绍
SpringBoot,我也是第一次用,实现了一个极简单的后台框架,希望有不太合理的地方大家给个建议。
项目配置
maven配置pox.xml
<?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.moxi</groupId><artifactId>moxi</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>moxi</name><description>mox</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.2.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!-- mybatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.2.0</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--thymeleaf --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--commons-io --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
项目配置文件application.properties
#DataBase start
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/moxi?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=Shu1shu2
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#DataBase end#thymeleaf start
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
#thymeleaf end#uploadFileSize start
spring.http.multipart.maxFileSize=10Mb
spring.http.multipart.maxRequestSize=100Mb
#uploadFileSize end
项目分层
Controller层,追求极简,分页自己进行了一个简单封装
package com.moxi.controller;import java.io.File;import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;import javax.servlet.http.HttpSession;import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import com.moxi.model.NewsCategory;
import com.moxi.service.NewsCategoryService;
import com.moxi.util.PageUtil;@Controller
@RequestMapping("/admin")
public class NewsController {@Autowiredprivate NewsCategoryService newsCategoryService;@RequestMapping("/newsManage_{pageCurrent}_{pageSize}_{pageCount}")public String newsManage(@PathVariable Integer pageCurrent,@PathVariable Integer pageSize,@PathVariable Integer pageCount, Model model) {return "/news/newsManage";}/*** 文章分类列表* @param newsCategory* @param pageCurrent* @param pageSize* @param pageCount* @param model* @return*/@RequestMapping("/newsCategoryManage_{pageCurrent}_{pageSize}_{pageCount}")public String newsCategoryManage(NewsCategory newsCategory,@PathVariable Integer pageCurrent,@PathVariable Integer pageSize,@PathVariable Integer pageCount, Model model) {//判断if(pageSize == 0) pageSize = 10;if(pageCurrent == 0) pageCurrent = 1;int rows = newsCategoryService.count(newsCategory);if(pageCount == 0) pageCount = rows%pageSize == 0 ? (rows/pageSize) : (rows/pageSize) + 1;//查询newsCategory.setStart((pageCurrent - 1)*pageSize);newsCategory.setEnd(pageSize);List<NewsCategory> list = newsCategoryService.list(newsCategory);//输出model.addAttribute("list", list);String pageHTML = PageUtil.getPageContent("newsCategoryManage_{pageCurrent}_{pageSize}_{pageCount}?name="+newsCategory.getName(), pageCurrent, pageSize, pageCount);model.addAttribute("pageHTML",pageHTML);model.addAttribute("newsCategory",newsCategory);return "/news/newsCategoryManage";}/*** 文章分类新增、修改跳转* @param model* @param newsCategory* @return*/@GetMapping("newsCategoryEdit")public String newsCategoryEditGet(Model model,NewsCategory newsCategory) {if(newsCategory.getId()!=0){NewsCategory newsCategoryT = newsCategoryService.findById(newsCategory);model.addAttribute("newsCategory",newsCategoryT);}return "/news/newsCategoryEdit";}/*** 文章分类新增、修改提交* @param model* @param newsCategory* @param imageFile* @param httpSession* @return*/@PostMapping("newsCategoryEdit")public String newsCategoryEditPost(Model model,NewsCategory newsCategory, @RequestParam MultipartFile[] imageFile,HttpSession httpSession) {for (MultipartFile file : imageFile) {if (file.isEmpty()) {System.out.println("文件未上传");} else {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");Date date = new java.util.Date();String strDate = sdf.format(date);String fileName = strDate + file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."),file.getOriginalFilename().length());String realPath = httpSession.getServletContext().getRealPath("/userfiles");System.out.println("realPath : "+realPath);try {FileUtils.copyInputStreamToFile(file.getInputStream(),new File(realPath, fileName));newsCategory.setImage("/userfiles/"+fileName);} catch (IOException e) {e.printStackTrace();}}}if(newsCategory.getId()!=0){newsCategoryService.update(newsCategory);} else {newsCategoryService.insert(newsCategory);}return "redirect:newsCategoryManage_0_0_0";}}
Model层(pure类)
package com.moxi.model;import java.sql.Date;public class NewsCategory extends BaseObject {private long id;private String name;private String description;private String image;private Date addDate;private int state;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getImage() {return image;}public void setImage(String image) {this.image = image;}public Date getAddDate() {return addDate;}public void setAddDate(Date addDate) {this.addDate = addDate;}public int getState() {return state;}public void setState(int state) {this.state = state;}}
Service层,一切追求极简,所以这里Mybatis用得是注解,我觉得注解也挺好用的。
package com.moxi.service;import java.util.List;import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.moxi.model.NewsCategory;@Mapper
public interface NewsCategoryService {@Select("SELECT * FROM `moxi`.`news_category` where id = #{id};")NewsCategory findById(NewsCategory newsCategory);@Select({"<script>","SELECT * FROM `moxi`.`news_category`","WHERE state = 0","<when test='name!=null'>","AND name LIKE CONCAT('%',#{name},'%')","</when>","order by addDate desc limit #{start},#{end}","</script>"})List<NewsCategory> list(NewsCategory newsCategory);@Select({"<script>","SELECT count(*) FROM `moxi`.`news_category`","WHERE state = 0","<when test='name!=null'>","AND name LIKE CONCAT('%',#{name},'%')","</when>","</script>"})int count(NewsCategory newsCategory);@Insert("INSERT INTO `moxi`.`news_category` (`id`, `name`, `description`, `image`, `addDate`, `state`) VALUES (null, #{name}, #{description}, #{image}, now(), 0);")int insert(NewsCategory newsCategory);@Update("UPDATE `moxi`.`news_category`SET `name` = #{name}, `description` = #{description}, `image` = #{image}, `state` = #{state} WHERE `id` = #{id};")int update(NewsCategory newsCategory);}
View层,使用的thymeleaf的标签,挺好用的,本来打算全站用ajax,不过开发效率稍微慢了些。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>MOXI</title><link th:href="@{/css/bootstrap.min.css}" rel="stylesheet" />
<link th:href="@{/font-awesome/css/font-awesome.css}" rel="stylesheet" />
<link th:href="@{/css/style.css}" rel="stylesheet" /><link th:href="@{/css/plugins/iCheck/custom.css}" rel="stylesheet"/>
<link th:href="@{/css/plugins/footable/footable.core.css}" rel="stylesheet"/></head><body><div id="wrapper"><nav class="navbar-default navbar-static-side" role="navigation" th:include="nav :: navigation"></nav><div id="page-wrapper" class="gray-bg"><div class="border-bottom" th:include="header :: headerTop"></div><div class="row wrapper border-bottom white-bg page-heading" th:fragment="headerNav"><div class="col-lg-10"><h2>文章分类</h2><ol class="breadcrumb"><li><a href="#">首页</a></li><li><a>内容管理</a></li><li class="active"><strong>文章分类</strong></li></ol></div><div class="col-lg-2"></div></div><div class="wrapper wrapper-content animated fadeInRight"><div class="row"><div class="col-lg-12"><div class="ibox float-e-margins"><div class="ibox-title"><h5>搜索</h5><div class="ibox-tools"><a class="collapse-link"><i class="fa fa-chevron-up"></i></a></div></div><div class="ibox-content" style="display: block;"><form action="newsCategoryManage_0_0_0"><div class="row"><div class="col-sm-3 m-b-xs"><input name="name" value="" th:value="${newsCategory.name}" placeholder="分类名称" class="form-control" type="text"/></div><div class="col-sm-1 m-b-xs"><button id="submitButton" class="btn btn-primary btn-block" type="submit"><i class="fa fa-search"></i> <strong>搜索</strong></button></div></div></form><div class="row"><div class="col-sm-6 m-b-xs"><a th:href="@{newsCategoryEdit}" class="btn btn-white btn-sm" data-toggle="tooltip" data-placement="left" title="" data-original-title="Refresh inbox"><i class="fa fa-plus"></i> 新增分类 </a></div><div class="col-sm-6 m-b-xs"></div></div></div></div></div><div class="col-lg-12"><div class="ibox float-e-margins"><div class="ibox-title"><h5>文章列表</h5><div class="ibox-tools"><a class="collapse-link"><i class="fa fa-chevron-up"></i></a></div></div><div class="ibox-content"><div class="table-responsive"><table class=" table table-hover" data-page-size="10"><thead><tr><th width="5%">ID</th><th width="30%">名称 </th><th width="40%">描述 </th><th width="10%">添加时间</th><th>操作</th></tr></thead><tbody><tr th:each="nc : ${list}"><td th:text="${nc.id}">Onions</td><td th:text="${nc.name}">Onions</td><td th:text="${nc.description}">Onions</td><td th:text="${nc.addDate}">Onions</td><td><a th:href="@{'newsCategoryEdit?id='+${nc.id}}" title="修改"><i class="fa fa-edit text-navy"></i></a><a th:href="@{'newsCategoryEdit?id='+${nc.id}}" title="修改"><i class="fa fa-trash-o text-navy"></i></a></td></tr></tbody><tfoot><tr><td colspan="7"><ul id="pageHTML" class="pagination pull-right"></ul></td></tr></tfoot></table></div></div></div></div></div></div><div class="footer" th:include="footer :: copyright"></div></div></div><!-- Mainly scripts --><script th:src="@{/js/jquery-2.1.1.js}"></script><script th:src="@{/js/bootstrap.min.js}"></script><script th:src="@{/js/plugins/metisMenu/jquery.metisMenu.js}"></script><script th:src="@{/js/plugins/slimscroll/jquery.slimscroll.min.js}"></script><!-- Peity --><script th:src="@{/js/plugins/peity/jquery.peity.min.js}"></script><!-- Custom and plugin javascript --><script th:src="@{/js/inspinia.js}"></script><script th:src="@{/js/plugins/pace/pace.min.js}"></script><!-- iCheck --><script th:src="@{/js/plugins/iCheck/icheck.min.js}"></script><!-- Peity --><script th:src="@{/js/demo/peity-demo.js}"></script><!-- FooTable --><script th:src="@{/js/plugins/footable/footable.all.min.js}"></script><!-- common --><script th:src="@{/js/common.js}"></script><script th:inline="javascript">var pageHTML = [[${pageHTML}]];$(document).ready(function () {$("#pageHTML").html(pageHTML);});</script>
</body></html>
分页封装,一切为了极简,做了个util类
package com.moxi.util;public class PageUtil {public static String getPageContent(String url,int pageCurrent,int pageSize,int pageCount){if (pageCount == 0) {return "";}String urlNew = url.replace("{pageSize}", pageSize+"").replace("{pageCount}", pageCount+"");String first = urlNew.replace("{pageCurrent}", 1+"");String prev = urlNew.replace("{pageCurrent}", (pageCurrent - 1)+"");String next = urlNew.replace("{pageCurrent}", (pageCurrent + 1)+"");String last = urlNew.replace("{pageCurrent}", pageCount+"");StringBuffer html = new StringBuffer();html.append("<li class=\"footable-page-arrow"+(pageCurrent<=1?" disabled":"")+"\"><a href=\""+(pageCurrent<=1?"#":first)+"\">«</a></li>");html.append("<li class=\"footable-page-arrow"+(pageCurrent<=1?" disabled":"")+"\"><a href=\""+(pageCurrent<=1?"#":prev)+"\">‹</a></li>");for(int i = 0 ;i < pageCount; i++){String urlItem = urlNew.replace("{pageCurrent}", (i+1)+"");html.append("<li class=\"footable-page"+(((i+1) == pageCurrent)?" active":"")+"\"><a href=\""+urlItem+"\">"+(i+1)+"</a></li>");}html.append("<li class=\"footable-page-arrow"+(pageCurrent==pageCount?" disabled":"")+"\"><a href=\""+(pageCurrent==pageCount?"#":next)+"\">›</a></li>");html.append("<li class=\"footable-page-arrow"+(pageCurrent==pageCount?" disabled":"")+"\"><a href=\""+(pageCurrent==pageCount?"#":last)+"\">»</a></li>");return html.toString().replaceAll("null", "");}}
项目下载地址
https://github.com/daleiwang/moxi
就这些,足够简单。包含登录、列表、分页、新增、修改、上传文件等……接下来会不断进行完善。
sql语句放到项目里面了。
Spring Boot(1)工具安装:
http://www.jianshu.com/p/fb6ed37c90eb
Spring Boot(2)新建Spring Boot工程
http://www.jianshu.com/p/00fd73f515f6
Spring Boot(3)整合Mybatis
http://www.jianshu.com/p/8401e9304fa0
Spring Boot(4)整合thymeleaf
http://www.jianshu.com/p/8d2cc7207fb2
Spring Boot(5)一个极简且完整的后台框架
http://www.jianshu.com/p/923d26d705ed
Spring Boot(6)jar方式打包发布
http://www.jianshu.com/p/9cf6faa8595e
Spring Boot(7)war方式打包发布
http://www.jianshu.com/p/ae170a58f88c
Spring Boot(5)一个极简且完整的后台框架相关推荐
- Spring Boot 一个极简且完整的后台框架
一个完整的极简后台框架,方便做小项目的时候可以快速开发. 这里面多贴图片和代码,做个参考吧,代码可以下载下来自己看看,里面这套后台模板不错,喜欢的拿去. 先放几张图 image image image ...
- Spring Boot一个极简且完整的后台框架
转载自面皮大师的简书 https://www.jianshu.com/p/923d26d705ed
- 很多小伙伴不太了解ORM框架的底层原理,这不,冰河带你10分钟手撸一个极简版ORM框架(赶快收藏吧)
大家好,我是冰河~~ 最近很多小伙伴对ORM框架的实现很感兴趣,不少读者在冰河的微信上问:冰河,你知道ORM框架是如何实现的吗?比如像MyBatis和Hibernate这种ORM框架,它们是如何实现的 ...
- 一个极简版本的 VUE SSR demo
我本人在刚开始看 VUE SSR 官方文档的时候遇到很多问题,它一开始是建立在你有一个可运行的构建环境的,所以它直接讲代码的实现,但是对于刚接触的开发者来说并没有一个运行环境,所以所有的代码片段都无法 ...
- 极简linux版本,4MLinux 26.0发布,这是一个极简版本
4MLinux 26.0版已经发布,这是一个极简版本,包括桌面版(带有JWM)和服务器版(具有完整的LAMP环境). 该项目的最新稳定版本附带升级包以及对现代图像和视频编码的支持: 4MLinux 2 ...
- 一个极简、高效的秒杀系统-战术实践篇(内附源码)
文章目录 一.前言 二.工程骨架 2.1 DDD概述 2.2 工程结构 三.源码解读 3.1领域层 3.1.1 领域模型 a. 活动 b. 活动商品 c. 库存扣减流水 d. 仓储 3.1.2 领域服 ...
- 用VuePress来搭建一个极简的静态网站
VuePress学习 全局安装前我们需要Git和node这两个软件,关于怎么安装可以我之前hexo的视频教程 假如这两个都没有安装好,那么下面就不需要看了哈,栈友们 全局安装 首先我们先全局安装一下 ...
- spring cloud教程之使用spring boot创建一个应用
<7天学会spring cloud>第一天,熟悉spring boot,并使用spring boot创建一个应用. Spring Boot是Spring团队推出的新框架,它所使用的核心技术 ...
- 使用React和Spring Boot构建一个简单的CRUD应用
"我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. Reac ...
最新文章
- 解决linux mysql命令 bash: mysql: command not found 的方法
- 一上来,就问原理,问上亿(MySQL)大表的索引优化...
- IOS UITableView 加载未知宽高图片的解决方案
- Apache Spark学习:利用Scala语言开发Spark应用程序
- Struts2基础学习总结
- Zend_Feed 的项目实际应用
- 题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?...
- 人工智能python小程序_Python:一个可以套路别人的python小程序
- Virtual Network (1) - How to use it in a guest
- 为什么说 Transformer 就是图神经网络?
- 高等微積分(高木貞治) 1.4節 例2
- growup怎么读_growup..是什么意思
- 使用Excel公式,获取 当前 Excel 文件 的 名字
- SDL2源代码分析2:窗口(SDL_Window)
- idea java jni 调试_使用 IntelliJ IDEA 和 IntelliJ Clion 进行 JNI 开发
- 对apache中并发控制参数prefork理解和调优
- 面试失败总结,这 577 道 LeetCode 题 Java 版答案你值得拥有
- 干货满满!!!盘点交互式甘特图控件VARCHART XGantt用户手册、视频教程!
- 金税盘时钟异常的处理方法及处理流程
- 飞机大战源码php,飞机大战源码 - 丁小未的个人页面 - OSCHINA - 中文开源技术交流社区...
热门文章
- 改善C++程式的效率
- Vue.js 源码分析—— Slots 是如何实现的
- java jsch 调用shell_使用Jsch执行Shell脚本
- Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException:
- php 微信消息,php实现微信公众号回复消息
- 如何使用POI导出excel表格,以及处理浏览器无法识别下载文件的问题
- IPv6与VoIP——ipv6接口标识与VoIP概述
- 在iOS中为ViewController构建自定义过渡
- 在网页中执行本地exe程序的两种方式
- 10、绘图(Graphics)