Developing enterprise applications based on SpringBoot

1. Set up the enterprise application development environment

  • Application architecture: MVC architecture
  • Vue realization of front desk development (focus on data display, overall [US])
  • Background: SpringBoot (focusing on providing API interface for data access)
  • ORM framework: MyBatis Plus
  • Data source framework: Druid
  • Unit tests: junit
  • Build tool: Maven
  • The JDK: 1.8
  • Runnable package: JAR

2.SpringBoot develops enterprise applications

2.1 New Construction project

2.2 Complete configuration files

pom.xml

Maven does not download dependencies (occasionally)

Reconfigure the remote warehouse in the poM file of the current project


      
<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 - the SNAPSHOT</version>
    <name>bjmarket</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <! Maven repository = maven repository = maven repository = maven repository = maven repository
    <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>
    <! -- Configure project dependencies -->
    <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 template - >
        <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>

        <! Add constructor /setter/getter to entity class runtime -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <! Json object support -->
        <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 driver -->
        <! -- 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>

        <! -- Use freemarker in code generator -->
        <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 Unit Test -->
        <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>

Copy the code

Change application.properties from the resource file to Application.yml

The 8080 port can be modified by default
server:
  port: 8081
spring:
# alias
  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
      # initialize the number of connections allocated
      initial-size: 10
      Retract the connection after 10s with no operation
      min-idle: 10
      It can hold up to 200 connections at a time
      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:
The package name must be the same as the package name under 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
# config log
logging:
  config:
    classpath: logback.xml


Copy the code

Create the log configuration file logback.xml in the resources folder


      
<configuration>
    <! -- Log format -->
    <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>
Copy the code

2.3 Importing the Database to Linux

  • XFTP upload
  • Creating an empty database
  • The source command initializes the script

2.4 Use automatic code generation tools

CodeGenerator

Add dependencies and write configurations

Website: baomidou.com/guide/gener…

The configured file given by the teacher: Put it in the Util bag

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 {

    /** * 

* read the console contents *

*/
public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("Please enter" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotBlank(ipt)) { returnipt; }}throw new MybatisPlusException("Please enter the correct one" + tip + "!"); } public static void main(String[] args) { // Code generator AutoGenerator mpg = new AutoGenerator(); // Global configuration 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); // Data source configuration 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); / / package configuration PackageConfig pc = new PackageConfig(); pc.setModuleName(scanner("Please enter the module name")); pc.setParent("cn.com.chinahitech.bjmarket"); mpg.setPackageInfo(pc); // Custom configuration InjectionConfig cfg = new InjectionConfig() { @Override public void initMap(a) { // to do nothing}};// If the template engine is freemarker String templatePath = "/templates/mapper.xml.ftl"; // Customize the output configuration List<FileOutConfig> focList = new ArrayList<>(); // Custom configurations are printed first focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // Customize the output file name. If your Entity has a prefix or suffix, note that the XML name will change accordingly!! return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/" + tableInfo.getEntityName() + "Mapper"+ StringPool.DOT_XML; }}); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg);// Configure the template TemplateConfig templateConfig = new TemplateConfig(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // Policy configuration 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("Table name, separated by multiple Commas").split(",")); strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix("t_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(newFreemarkerTemplateEngine()); mpg.execute(); }}Copy the code

After the execution:

The module name refers to the name of the automatically generated folder.

Table names refer to the database tables involved.

Generally speaking, a module is generated for each table

Automatic generation:

The Mapper layer is the Dao layer

3. Statistics on the proportion of big data jobs in major cities

The t_PIE table above is the table placed in SQL after big data analysis

Our goal is to export this data in JSON format from the background for the foreground to call and display.

Through the above code generation and a series of operations, we have set up the background framework, the rest of the time to improve the code.

3.1 Not front and background separation

There are both front and back ends in the same project

The background

The Entity and Mapper layers are nicely generated and we don’t need to move them.

What we need to improve is the Service layer and the Controller layer.

The Controller layer calls the Service layer, which calls the Mapper layer, which accesses the database

The service layer

The Service layer calls the Mapper layer.

“Interface”

public interface IPieService extends IService<Pie> {
    /** * Query all big data job information *@return* /
    List<Pie> getCityDatas(a);

}
Copy the code

“Implementation”

@Service
public class PieServiceImpl extends ServiceImpl<PieMapper.Pie> implements IPieService {
    @Resource
    private PieMapper pieMapper;

    @Override
    // Access the database to execute the query
    public List<Pie> getCityDatas(a) {
        //1 encapsulates the QueryWrapper object
        QueryWrapper<Pie> wrapper=new QueryWrapper<>();
        //2 Perform query
        List<Pie> pieList=pieMapper.selectList(wrapper);
        returnpieList; }}Copy the code

The controller layer

The Controller layer calls the Service layer

@RestController
@RequestMapping("/pie")
public class PieController {
    @Resource
    private IPieService pieService;
    
    @RequestMapping(value = "/getCityData")
    @ResponseBody
    public String getCityData(a){
        Map<String,Object> map=new HashMap<>();
        try {
            // 1 calls the service layer to perform the query
            List<Pie> cityDatas = pieService.getCityDatas();
            
            //2 Data is encapsulated successfully
            map.put("status"."200");
            map.put("data",cityDatas);
        }catch (Exception e){
            //2 Failed to encapsulate data
            map.put("status"."500");
            map.put("errorMsg"."Error:"+e.getMessage());
        }
        
        // Return the package as Jason data
        returnJSON.toJSONString(map); }}Copy the code

Modify the main class

The main class is now:

@SpringBootApplication
@MapperScan("cn.com.chinahitech.bjmarket.*.mapper")// To add a packet sweep declaration, scan all mapper, namely the DAO package
public class BjmarketApplication {

    public static void main(String[] args) { SpringApplication.run(BjmarketApplication.class, args); }}Copy the code

run

The port is 8081. The goal behind the scenes is to get json data

As I provide an address: http://localhost:8081/pie/getCityData (interface)

You can call this address and get the corresponding JSON data

The front desk to show

Template page: Place it under Template

It needs to be called by Controller

Configure static js

  • Put pie.html in the template directory

  • Put the js file in the static directory

    Create a new js file in the static directory of the resource directory and put the js file in it

Controller is changed to display page

@Controller
@RequestMapping("/pie")
public class PieController {
    // omit existing code
    @RequestMapping(value="/show")
    public String show(a){
        return "pie"; //pie is the name of the pie.html page}}Copy the code

Delete the target generated last time before testing, otherwise the previous code will be executed. * * * *

Test results:

3.2 Separation of front and background

To separate the front from the back, we do not need the pages in the template directory or the js in the static directory.

That is to say, the above project does not do anything about the foreground, is a pure background, meaning is to give you an address, you can get data from.

So the foreground developer can use WebStorm to create a foreground project.

The final compilation will also result in such a file


  • Backend program: BjMarket (SpringBoot+MyBatis Plus) — IDEA
  • Front-end program: Piesite (Vue based on Ajax implementation) – WebSTORM

Resolve cross-domain access issues

No longer in the same project no cross domain means the same IP and port

Execute pie.html alone

No pie chart appears.

How to solve

Controller in the back end

Add the cross domain access annotation @crossorigin to the Controller class

Exceptions are origin’s problem

@Controller
@RequestMapping("/pie")
@CrossOrigin<----------------- add comments -------->public class PieController {
    @Resource
    private IPieService pieService;

    @RequestMapping(value = "/getCityData")
    @ResponseBody
    public String getCityData(a){
        Map<String,Object> map=new HashMap<>();
        try{...Copy the code

Restarting the service

Note: The port is occupied

Type the command in the command window: netstat – ano | findstr searches, 8080 (8080 into their occupied ports),

Then enter the command to stop the process: Taskkill/PID 14076 /f To stop the process one by one. This method is more troublesome, the following is simple.

The test results

The deployment of

SpringBoot daemon package –jar

Double click package (you may want to delete the Java files in the test folder before packaging, otherwise it may make an error)