上一篇文章 手撸的一个快递查询系统,竟然阅读量过1.8w 分享了我手撸自助快递单的项目。这周我对这个快递查询想做一下优化。开发一个后台内容管理系统,将快递信息在后台进行统一管理。搜寻了2个小时找到一款比较契合的瀑布内容管理系统项目 pb-cms
。这个项目适合搭建博客、企业网站,后台是对内容管理。关键一点作者说项目一直在更新。那就开始本地搭建。
git clone https://gitee.com/LinZhaoguan/pb-cms.git 复制代码
修改配置文件
配置文件在项目根目录 resources
下,主要配置文件如下:
application-dev.yml #dev(开发版)配置文件 application-prd.yml #prd(生产版)配置文件 application.yml #主配置文件 logback-spring.xml #日志配置文件 复制代码
这里修改一下 application-dev.yml
,内容如下:
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/pb-cms-base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true username: root password: 123456 redis: host: 127.0.0.1 port: 6379 password: 123456 timeout: 5000 jedis: pool: max-idle: 8 min-idle: 0 max-active: 8 max-wait: -1 server: servlet: context-path:/cms 复制代码
这里注意修改一下 mysql
数据库 url
(链接)、 username
(用户名)、 password
(和密码)。修改一下 redis
的 host
(服务器地址)、 port
(端口)、 password
(密码),如果相同就不需要修改了。
导入数据库脚本
使用数据库可视化工具 Navicat
工具,先创建数据库 pb-cms-base
,如下图:
然后导入数据库脚本,数据库脚本文件在 docs/db/pb_cms_base.sql
,数据导入如下图:
运行项目
打开 com.puboot.SpringbootApplication
,运行 main
方法即可:
Debug
模式启动的。当然如果你的项目已经开发完成,想部署让他人使用,可以将项目打包成
jar
包来独立运行。
java -jar pb-cms.jar #本地jar包运行 nohup java -jar pb-cms.jar > pb-cms.log & #linux服务器运行 复制代码
项目运行前端运行效果:
项目运行后端运行效果:
注: 我的 idea
的主题是 Material Theme UI
。
pom.xml配置
这里引入了 hutools
工具,因为它封装了很多工具类,直接使用就可以了。项目 pom.xml
添加如下依赖:
<!-- hutools--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.3.0</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.12.0</version> </dependency> 复制代码
工具类ExcelUtils
创建工具类,代码如下
/** * @author wangzg * @date 2020/4/13 */ public class ExcelUtils { /** * 获取第一个sheet页的内容 * @param inputStream * @return */ public static List<KuaiDi> getKuaiDiList(InputStream inputStream) { List<KuaiDi> kuaiDiList = new ArrayList<>(); if(Objects.nonNull(inputStream)){ ExcelReader excelReader = ExcelUtil.getReader(inputStream); //表头添加别名,主要是将中文名转为数据库对应的字段 excelReader.addHeaderAlias("快递单号","kuaidiNo"); excelReader.addHeaderAlias("用户名","userName"); excelReader.addHeaderAlias("电话","phone"); excelReader.addHeaderAlias("快递公司","company"); List<Map<String, Object>> rowList = excelReader.readAll(); if(CollectionUtil.isNotEmpty(rowList)){ rowList.stream().forEach(r->{ KuaiDi kuaiDi = new KuaiDi(); try { populate(kuaiDi,r); kuaiDi.setCreateTime(new Date()); kuaiDiList.add(kuaiDi); } catch (Exception e) { e.printStackTrace(); } }); } } return kuaiDiList; } public static void main(String[] args) { List<KuaiDi> kuaiDiList = getKuaiDiList(ResourceUtil.getStream("D://快递.xls")); kuaiDiList.stream().forEach(System.out::println); } } 复制代码
service调用
service
层就比较简单了,获取上传的 multipartFile
文件对象,将输入流传给 ExcelUtils.getKuaiDiList
,就可以返回对象的集合 kuaiDiList
,代码如下:
@Override public void importData(MultipartFile multipartFile) throws Exception { List<KuaiDi> kuaiDiList = ExcelUtils.getKuaiDiList(multipartFile.getInputStream()); if(CollectionUtil.isNotEmpty(kuaiDiList)){ //批量插入 this.saveBatch(kuaiDiList); } } 复制代码
3.1 项目集成 Mybatis
是否可以不指定 type-aliases-package
属性?
答案是肯定的。为什么会单独说这个问题呢?因为我发现项目报配置文件配置文件中配置了下面内容:
mybatis-plus: global-config: db-config: id-type: auto mapper-locations: classpath:mapper/*.xml type-aliases-package: com.puboot.model 复制代码
com.puboot.model
包路径项目是没有的,难道是 type-aliases-package
支持模糊匹配?一直没想过作者写错的问题。最后本地测试,并查了 Mybitas Plus
,最终的解释是这样的:
typeAliasesPackage:MyBaits 别名包扫描路径,通过该属性可以给包中的类注册别名,注册后在 Mapper 对应的 XML 文件中可以直接使用类名,而不用使用全限定的类名(即 XML 中调用的时候不用包含包名。 看了部分的源码也发现一个小知识点: type-aliases-package
是支持多个包的别名定义的。
/** * Packages to search type aliases. (Package delimiters are ",; /t/n") */ private String typeAliasesPackage; 复制代码
因为本项目集成了 spring-boot-starter-thymeleaf
,可以通过 thymeleaf
开发我们的前端页面。学过 Struts2
的同步应该知道是怎么开发 Web
项目的。前端请求进入到后台控制器的业务处理方法,处理方法绑定数据到上下文,然后让方法返回一个字符串,字符串会匹配到返回前端的生成好的页面。但是有时又需要方法直接返回响应数据的 json
数据。所以两者的区别显而易见。
@RestController: 这个注解相当于 @Controller + @ResponseBody。
3.3 controller 如何注入 service
?
我们常用的方式可能是这样,使用 @Autowired
注入我们要到的 service
,代码如下:
@RequestMapping("kuaidi") @Controller public class KuaiDiController { @Autowired private KuaiDiService kuaiDiService; } 复制代码
在此项目中我发现了一种写法,代码如下:
@Controller @RequestMapping("article") @AllArgsConstructor public class ArticleController { private final BizArticleService articleService; private final BizArticleTagsService articleTagsService; private final BizCategoryService categoryService; private final BizTagsService tagsService; private final SysConfigService configService; } 复制代码
这种方式其实就是构造方法注入, @AllArgsConstructor
是 lombok
插件的一个注解,插件会自动生成全参数的构造方法。
开源项目让我们很容易就可以获取并学别人的源码。我自己也在优化 自助快递
查询的功能。不为别的,只为时间不浪费;每完成一个功能都有一定的成就感,让我乐在其中!