基于SpringBoot开发企业应用
1.搭建企业应用开发环境
- 应用架构:MVC架构
- Vue实现前台开发 (侧重数据的展示,整体【美】)
- 后台: SpringBoot(侧重提供数据访问的API接口)
- ORM框架: MyBatis Plus
- 数据源框架: Druid
- 单元测试: junit
- 构建工具: maven
- JDK: 1.8
- 可运行包 : jar
2.SpringBoot开发企业应用
2.1新建工程
2.2 完整的配置文件
pom.xml
注:令配maven出现无法下载依赖的情况(偶尔出现)
在当前工程的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.com.chinahitech</groupId>
<artifactId>bjmarket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>bjmarket</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- 配置国内maven仓库源 -->
<repositories>
<repository>
<id>ali-maven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<!--配置项目依赖-->
<dependencies>
<!-- spring-boot-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--thymeleaf模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- lombok 实现实体类运行时添加构造器/setter/getter -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- json object对象支持 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!-- mybatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<!-- MySQL驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- 数据连接池 druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
<!-- 代码生成器中使用freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- 代码自动生成工具 mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.0</version>
</dependency>
<!-- junit单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
把资源文件中的application.properties改成application.yml
#默认时8080 可以修改端口
server:
port: 8081
spring:
#别名
application:
name: market
aop:
proxy-target-class: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.104:3306/market?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: ROOTroot_1
druid:
validation-query: SELECT 1 FROM DUAL
#初始化分配连接数量
initial-size: 10
#10s后无操作就收回该连接
min-idle: 10
#同时最高能容纳200个连接
max-active: 200
min-evictable-idle-time-millis: 300000
test-on-borrow: false
test-while-idle: true
time-between-eviction-runs-millis: 30000
pool-prepared-statements: true
max-open-prepared-statements: 100
mybatis-plus:
#要与java下的包名一致
type-aliases-package: cn.com.chinahitech.bjmarket.*.entity
global-config:
db-config:
id-type: auto
logic-delete-field: flag
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
jdbc-type-for-null: 'null'
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#配置日志
logging:
config:
classpath: logback.xml
在资源文件夹中新建日志配置文件logback.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!--日志格式-->
<property name="LOG_PATTERN"
value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n" />
<property name="LOG_LEVEL" value="INFO"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${LOG_LEVEL}</level>
</filter>
</appender>
<root level="${LOG_LEVEL}">
<appender-ref ref="STDOUT" />
</root>
</configuration>
2.3 将数据库导入linux
- xftp上传
- 新建空数据库
- source命令初始化脚本
2.4使用代码自动生成工具
CodeGenerator
添加依赖、编写配置
老师给的配置好的文件:放进util包里
package cn.com.chinahitech.bjmarket.util;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CodeGenerator {
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("sunjie");
gc.setOpen(false);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://192.168.0.104:3306/market?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("ROOTroot_1");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("请输入模块名"));
pc.setParent("cn.com.chinahitech.bjmarket");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix("t_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
执行后:
模块名是指自动生成的文件夹的名字。
表名是指涉及到的数据库表。
一般来说是一张表对应生成一个模块
自动生成:
mapper层就是之前的Dao层
3.统计各大城市大数据工作岗位占比
以上这张t_pie表,就是大数据分析完之后放在sql里的表
我们的目的,就是把这些数据,以json的格式从后台输出,供前台调用并展示。
通过以上代码生成等一系列操作,我们已经把后台的框架搭建好,剩下的就时完善代码了。
3.1不是前后台分离
同一个项目里既有前台,又有后台
后台
entity层和mapper层生成的很好,我们不用动。
我们需要完善的就是service层和 controller层。
controller层调用service层,service层调用mapper层,mapper层访问数据库
service层
service层调用mapper层。
【接口】
public interface IPieService extends IService<Pie> {
/**
* 查询各城市所有的大数据岗位信息
* @return
*/
List<Pie> getCityDatas();
}
【实现】
@Service
public class PieServiceImpl extends ServiceImpl<PieMapper, Pie> implements IPieService {
@Resource
private PieMapper pieMapper;
@Override
//访问数据库,执行查询
public List<Pie> getCityDatas() {
//1 封装QueryWrapper对象
QueryWrapper<Pie> wrapper=new QueryWrapper<>();
//2 执行查询
List<Pie> pieList=pieMapper.selectList(wrapper);
return pieList;
}
}
controller层
controller层调用service层
@RestController
@RequestMapping("/pie")
public class PieController {
@Resource
private IPieService pieService;
@RequestMapping(value = "/getCityData")
@ResponseBody
public String getCityData(){
Map<String,Object> map=new HashMap<>();
try {
// 1 调用service层执行查询
List<Pie> cityDatas = pieService.getCityDatas();
//2 执行成功 封装数据
map.put("status","200");
map.put("data",cityDatas);
}catch (Exception e){
//2 执行失败封装数据
map.put("status","500");
map.put("errorMsg","出错:"+e.getMessage());
}
//把刚刚封装好的返回出去,返回成jason数据
return JSON.toJSONString(map);
}
}
修改主类
现在的主类是:
@SpringBootApplication
@MapperScan("cn.com.chinahitech.bjmarket.*.mapper")//要添加扫包声明,扫描所有的mapper,就是dao包
public class BjmarketApplication {
public static void main(String[] args) {
SpringApplication.run(BjmarketApplication.class, args);
}
}
运行
启动成功,端口是8081。后台的目的就是得到json数据
就相当于我提供一个地址:http://localhost:8081/pie/getCityData (接口)
你调用这个地址就能得到相应的json数据
前台展示
模板页面:放到template下
需要通过Controller调用
配置static下的js
-
将pie.html放到template目录下
-
js文件放到static目录下
resource目录下的static目录下新建js,把js文件放进去
controller改为展示页面
@Controller
@RequestMapping("/pie")
public class PieController {
//省略现有代码
@RequestMapping(value="/show")
public String show(){
return "pie"; //pie 是pie.html页面的名字
}
}
测试之前记得先把上次生成的target删一下,不然会执行以前的代码。****
测试结果:
3.2前后台分离
进行前后台分离的话,那么刚才的template目录下的页面、以及static目录下的js都不需要。
就是说上面的项目不做前台有关的任何内容,就是一个纯后台,意义就是给你一个地址,你可以从中得到数据。
那么前台的开发人员就可以用webstorm,创建一个前台项目。
最后编译也会得到这样一个文件
- 后端程序:bjmarket (SpringBoot+MyBatis Plus)——IDEA
- 前端程序:piesite(Vue基于ajax实现)——WebSTORM
解决跨域访问的问题
不再同一个项目里面 不跨域就是同一个ip同一个端口
单独执行pie.html
没有出现饼图。
如何解决
在后端程序的controller解决
在controller类上面添加跨域访问的注解 @CrossOrigin
异常就是origin的问题
@Controller
@RequestMapping("/pie")
@CrossOrigin <-----------------添加注解-------->
public class PieController {
@Resource
private IPieService pieService;
@RequestMapping(value = "/getCityData")
@ResponseBody
public String getCityData(){
Map<String,Object> map=new HashMap<>();
try {
...
重新启动服务
注:关于端口被占用的问题
在命令窗口输入命令:netstat -ano | findstr 8080(8080改成自己被占用的 端口),
然后输入结束进程的命令 :taskkill /pid 14076 /f 一个一个关掉进程。这个方法比较麻烦,下面介绍简单的。
测试结果
部署
SpringBoot后台程序打包--jar
双击package(打包之前可能要把test文件夹里面的java文件删掉,不然可能会出错)