Getting started with springboot is simple to use

1. The SpringBoot project creates and configures the mysql database

create project

Development environment: idea

Use Spring Initializer to quickly generate Spring Boot applications

First click on the upper left corner, File - New - Project

image-20230511110042756

Fill in the project information, note: Java version 8 should be selected, and then click Next

image-20230511110427609

Note: Plugins that need to be installed

Developer Tools选项下的Spring Boot DevTools和Lombok
Web选项下的Spring Web
SQL选项下的MySQL Driver

image-20230511111212840

After you see that there is no progress bar in the lower left corner and lower right corner to initialize the project, and the upper right corner has recognized that it is a Springboot project, the project is created successfully

image-20230511111518062

At this point, start the project and check whether it is normal. If the following words are prompted, it can be started normally (port: 8080)

image-20230511111613762

Use a browser to open the URL, and the following interface can be displayed

localhost:8080

image-20230511111707686

Write Controller tests

Create a new class and put it under TestControllerthe subpackagecontroller

image-20230511112047982

image-20230511112122798

After creating a new one, write and add the following code in it

Original code:

package com.example.mini_program_yln.controller;

public class TestController {
    
    
   
}

after modification

package com.example.mini_program_yln.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

//将数据以json格式返回给前端
@RestController
public class TestController {
    
    
    @GetMapping("/test")
    public String test() {
    
    
        return "Hello world!";
    }
}

Restart the next project, visit

localhost:8080/test

image-20230511112530389

configuration database

application.ymlCreate a new file in the resource directory

image-20230511112755564

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 111111

explain:

Generally, the database name, mysql account, and mysql password need to be modified.

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/数据库名字?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: mysql的账号
    password: mysql的密码

Here you need to use navicat to create a new database in advance

image-20230511113449360

2. SpringBoot integrates mybatis-plus

Official website: https://www.baomidou.com/

mybatis-plus is a persistence layer framework for operating databases

Initialize the database

According to the official website: Operation

https://www.baomidou.com/pages/226c21/#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B7%A5%E7%A8%8B

Open navicat (you can also use idea to connect to mysql, or use other tools such as hedisql to connect), click query, and select the database you just created

Paste the code below and click Run

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

image-20230511115825061

At this point, the user table is automatically created and several pieces of sample data are inserted

image-20230511115935174

Install mybatis-plus

1. Introduce dependencies in the pom.xml file

<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>

image-20230511120143287

2. In order to prevent malicious full table update and deletion, configure the anti-full table update and delete plug-in

For update and delete statements: prevent malicious full table update and delete

Create a new package under the following path: config

image-20230511120420530

Created as shown

image-20230511120503979

MybatisPlusConfig Then create a new class under the config package

Then add the following code and import related classes

@Configuration
public class MybatisPlusConfig {
    
    
  @Bean
  public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
    return interceptor;
  }
}

Add a successful example

package com.example.mini_program_yln.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
* 针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除
* */
@Configuration
public class MybatisPlusConfig {
    
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        return interceptor;
    }
}

It is also possible to add pagination configuration here in the future

Display the database data through the interface through mybatis-plus

Create a new entity subpackage in the following directory

image-20230511121028366

Then create a new User class under the entity package and add the following code

package com.example.mini_program_yln.entity;

import lombok.Data;

@Data
public class User {
    
    
    //表示id是主键,且插入数据时自增
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}


Create a new mapper subpackage

image-20230511123445106

Create a new UserMapper interface to inherit from BaseMapper

package com.example.mini_program_yln.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mini_program_yln.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    
    



}

image-20230511123633482

Let's go to the TestController.java file to test the mapper

package com.example.mini_program_yln.controller;

import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//将数据以json格式返回给前端
@RestController
public class TestController {
    
    
    @Autowired
    private UserMapper userMapper;

    @GetMapping("/testList")
    public List<User> testList() {
    
    
        return userMapper.selectList(null);
    }
}

Access http://localhost:8080/testList, all data in the database User table is returned

image-20230511124201282

3. SpringBoot three-tier architecture Controller, Service, Dao

image-20230511124751071

Now our project is still poor and the service has not been created

image-20230511124922074

after creation

image-20230511125006504

Create a new interface under the service package IUserServiceand add the following code

image-20230511125032285

package com.example.mini_program_yln.servicce;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mini_program_yln.entity.User;

public interface IUserService extends IService<User> {
    
    
}

UserServiceImplThen create a new impl subpackage under the service package, and create a new class under the impl package

image-20230511125228789

Add the following code

Need to inherit ServiceImpl and implement custom IUserService

package com.example.mini_program_yln.servicce.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import com.example.mini_program_yln.servicce.IUserService;

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    
    
}

4. SpringBoot integrates Mabatis-plus to write addition, deletion, modification and query interfaces

Write the code in IUserService.java, define several interfaces

package com.example.mini_program_yln.servicce;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mini_program_yln.entity.User;

import java.util.List;

public interface IUserService extends IService<User> {
    
    

    Page<User> page(Integer current, Integer size, String username);

    boolean saveOrUpdateById(User user);

    boolean deleteBatchIds(List<Integer> ids);

}

UserServiceImpl.javaImplement a few interfaces in

Put the mouse on the line of the red wavy line, click 实现方法it, and the method body will be automatically generated

image-20230511131319493

package com.example.mini_program_yln.servicce.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import com.example.mini_program_yln.servicce.IUserService;

import java.util.List;

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    
    
    @Override
    public Page<User> page(Integer current, Integer size, String username) {
    
    
        return null;
    }

    @Override
    public boolean saveOrUpdateById(User user) {
    
    
        return false;
    }

    @Override
    public boolean deleteBatchIds(List<Integer> ids) {
    
    
        return false;
    }
}

Write a concrete implementation of the logic

package com.example.mini_program_yln.servicce.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.DeleteBatchByIds;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import com.example.mini_program_yln.servicce.IUserService;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    
    
    @Override
    public Page<User> page(Integer current, Integer size, String username) {
    
    
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        if (!"".equals(username)) {
    
    
            //不为空
            //精确查询
            //wrapper.eq(User::getName,username);

            //模糊查询
            wrapper.like(User::getName, username);
        }
        Page<User> page = page(new Page<>(current, size), wrapper);
        return page;
    }

    @Override
    public boolean saveOrUpdateById(User user) {
    
    
        if (user.getId() != null) {
    
    
            //更新
            return updateById(user);
        } else {
    
    
            //新增
            return save(user);
        }
    }

    @Override
    public boolean deleteBatchIds(List<Integer> ids) {
    
    
        return removeByIds(ids);
    }
}

Then create a new UserController.java class under the controller package

package com.example.mini_program_yln.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.servicce.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
    
    

    @Autowired
    private UserServiceImpl userService;

    @GetMapping("/page")
    @Description("分页列表-模糊查询")
    public Page<User> page(@RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
    
    
        return userService.page(current, size, username);
    }

    @PostMapping("/save")
    @Description("新增或更新")
    public boolean save(@RequestBody User user) {
    
    
        return userService.saveOrUpdateById(user);
    }

    @PostMapping("/delete")
    @Description("删除")
    public boolean delete(@RequestBody List<Integer> ids) {
    
    
        return userService.deleteBatchIds(ids);
    }

}

We also need to MybatisPlusConfig.javaadd a pagination configuration item in , add the following line

public class MybatisPlusConfig {
    
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());


        //分页配置
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));


        return interceptor;
    }
}

At this point you can use postman to test the interface

other

Hot deployment integration

For example, if we modify the code from the left picture to the right picture, we need to compile and restart, which is a waste of resources and time-consuming, which requires hot deployment

image-20230511113951599

1. First click on the upper left corner: File - Settings

Find 构建、执行、部署, click on the compiler, check自动构建项目

image-20230511114143135

2. Then turn on the dynamic automatic compilation of idea (some will be turned on automatically, so no operation is required)

image-20230511114411355

3. Enable idea hot deployment strategy

Click on the item in the upper right corner - edit configuration

image-20230511114527757

Click on edit option

image-20230511114619574

will 执行更新操作时be changed to更新类和资源

image-20230511114646267

4. Add the plugin to the pom file

<plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <configuration>
      <fork>true</fork>
              <addResources>true</addResources>
     </configuration>
</plugin>

image-20230511115105471

At this time, when the idea loses focus for five seconds, the resources will be automatically updated, and the hot deployment is completed.

mybatis-plus log printing

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志

image-20230511135132103

Cross domain problem solving

Method 1: Add annotations to the Controller class

@CrossOrigin("*")
image-20230511135642302

Sometimes Gradle projects need to use this

@CrossOrigin(value = "*",allowCredentials = "true")

Method 2: Create a new cross-domain configuration item to solve

CorsConfigCreate a new class under the config package

package com.example.mini_program_yln.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration // 一定不能忽略此注解
public class CorsConfig {
    
    
    @Bean
    public CorsFilter corsFilter() {
    
    
        // 1.创建 CORS 配置对象
        CorsConfiguration config = new CorsConfiguration();
        // 支持域
        config.addAllowedOriginPattern("*");
        // 是否发送 Cookie
        config.setAllowCredentials(true);
        // 支持请求方式
        config.addAllowedMethod("*");
        // 允许的原始请求头部信息
        config.addAllowedHeader("*");
        // 暴露的头部信息
        config.addExposedHeader("*");
        // 2.添加地址映射
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", config);
        // 3.返回 CorsFilter 对象
        return new CorsFilter(corsConfigurationSource);
    }
}

SpringBoot project configuration multi-environment

Create two new files in the resources directory: application-local.yamlandapplication-dev.yaml

application.yaml

active indicates the current environment: local indicates the local development environment, and dev indicates the online environment

You can set different mysql account passwords for different environments, etc.

spring:
  profiles:
    active: dev

application-local.yaml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志

application-dev.yaml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 1234567
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志

The results returned by SpringBoot are uniformly encapsulated

When the backend provides a RESTful API to the frontend, it needs to respond to whether the frontend API call is successful:

  • If successful, what is the success data. Subsequently, the front end will render the data to the page
  • If it fails, what is the reason for the failure. Generally, the front end will pop up the reason to the user

Therefore, there needs to be a unified response , rather than each interface defining its own style. Generally speaking, the unified response returns the following information:

  • On success, return successful status code + data
  • When it fails, return the failed status code + error message

Create a new common subpackage

image-20230511150107275

Create classes under commonsubpackagesCommonResult

package com.example.mini_program_yln.common;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult<T> {
    
    
    /**
     * 错误码
     */
    private Integer code;
    /**
     * 返回数据
     */
    private T data;
    /**
     * 错误提示,用户可阅读
     */
    private String msg;


    public static <T> CommonResult<T> success(T data) {
    
    
        CommonResult<T> result = new CommonResult<>();
        result.code = 0;
        result.data = data;
        result.msg = "";
        return result;
    }


    public static <T> CommonResult<T> error(Integer code, String message) {
    
    
        CommonResult<T> result = new CommonResult<>();
        result.code = code;
        result.msg = message;
        return result;
    }

    public static <T> CommonResult<T> error() {
    
    
        CommonResult<T> result = new CommonResult<>();
        result.code = 1;
        result.msg = "系统错误,请联系管理员";
        return result;
    }

}

have a test

package com.example.mini_program_yln.controller;

import com.example.mini_program_yln.common.CommonResult;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//将数据以json格式返回给前端
@RestController
public class TestController {
    
    
    @Autowired
    private UserMapper userMapper;


    @Description("测试统一返回-成功")
    @GetMapping("/testResultSuccess")
    public CommonResult<List<User>> testResultSuccess() {
    
    
        return CommonResult.success(userMapper.selectList(null));
    }

    @Description("测试统一返回-失败")
    @GetMapping("/testResultError")
    public CommonResult<List<User>> testResultError() {
    
    
        return CommonResult.error(400, "失败了");
    }
}

paging wrapper

Create a new PageParam.java class under the common package

image-20230511152152629
package com.example.mini_program_yln.common;

import lombok.Data;

import java.io.Serializable;

@Data
public class PageParam implements Serializable {
    
    

    private static final Integer PAGE_NO = 1;
    private static final Integer PAGE_SIZE = 10;

    private Integer pageNo = PAGE_NO;

    private Integer pageSize = PAGE_SIZE;

}

The previous way of writing pagination

@GetMapping("/page")
@Description("分页列表-模糊查询")
public Page<User> page(@RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
    
    
    return userService.page(current, size, username);
}

current way of writing

@PostMapping("/pageFZ")
@Description("分页列表-分页封装")
public CommonResult<Page<User>> page(@RequestBody PageParam pageInfo) {
    
    
    Page<User> page = userService.page(
            new Page<>(pageInfo.getPageNo(), pageInfo.getPageSize())
    );
    return CommonResult.success(page);
}

Parameter check

For example, in the paging package above, our pageSize needs a range, not infinite

Introduce dependencies in the pom file

image-20230511154928859
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Then modify the PageParam.java file

pageNo The minimum page number is 1

The minimum pageSize is 1 and the maximum is 100

package com.example.mini_program_yln.common;

import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

@Data
public class PageParam implements Serializable {

    private static final Integer PAGE_NO = 1;
    private static final Integer PAGE_SIZE = 10;

    @NotNull(message = "页码不能为空")
    @Min(value = 1, message = "页码最小值为 1")
    private Integer pageNo = PAGE_NO;

    @NotNull(message = "每页条数不能为空")
    @Min(value = 1, message = "每页条数最小值为 1")
    @Max(value = 100, message = "每页条数最大值为 100")
    private Integer pageSize = PAGE_SIZE;

}

The test interface found that it can be verified, but it will return a bunch of stack information, which is not good, and global exception capture can be performed

image-20230511155102959

Custom exception and global exception capture

Create exceptionsubpackages and GlobalExceptionHandler.javaclasses

image-20230511155258021

package com.example.mini_program_yln.exception;

import com.example.mini_program_yln.common.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    
    

    /*
     *
     * 运行时异常
     * */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public CommonResult<?> ExceptionHandler() {
    
    
        return CommonResult.error();
    }


    /*
     *
     * 自定义异常
     * */
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public CommonResult<?> CustomExceptionHandler(CustomException e) {
    
    

        return CommonResult.error(400, e.getMessage());
    }

    /**
     * 处理 SpringMVC 参数校验不正确
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public CommonResult<?> methodArgumentNotValidExceptionExceptionHandler(MethodArgumentNotValidException ex) {
    
    
        FieldError fieldError = ex.getBindingResult().getFieldError();

        assert fieldError != null; // 断言,避免告警
        return CommonResult.error(400, String.format("请求参数不正确:%s:%s", fieldError.getField(), fieldError.getDefaultMessage()));
    }

    /**
     * 处理系统异常,兜底处理所有的一切
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public CommonResult<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
    
    
        // 返回 ERROR CommonResult
        return CommonResult.error(400, "未知异常,请联系管理员");
    }
}

At this time, the paging parameter is passed incorrectly, and it can be captured normally

image-20230511162052981

custom exception

Create the CustomException.java class under exception

package com.example.mini_program_yln.exception;

import lombok.Getter;

@Getter
public class CustomException extends RuntimeException {
    
    
    private Integer code;

    public CustomException(Integer code, String msg) {
    
    
        super(msg);
        this.code = code;
    }

    public CustomException( String msg) {
    
    
        super(msg);
        this.code = 400;
    }
}

code used in

@GetMapping("/page")
    @Description("分页列表-模糊查询")
    public Page<User> page(@RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
    
    
        throw new CustomException(404,"aaa");
//        return userService.page(current, size, username);
    }

image-20230511162226132

Automatically generate entity entity classes

Create a new SqlHelper class under the utils package

image-20230511163031279

Generally need to modify packageOutPath, tablename, URL, NAME, PASS before use

package com.example.mini_program_yln.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 从数据库表反射出实体类,自动生成实体类
 *
 * @author xxxx
 */
public class SqlHelper {
    
    
    //基本数据配置
    private String packageOutPath = "com.example.mini_program_yln.entity";// 指定实体生成所在包的路径,要修改
    private String authorName = "xxxx";// 作者名字
    private String tablename = "news";// 表名,要修改
    private String[] colnames; // 列名数组
    private String[] colTypes; // 列名类型数组
    private String version = "V0.01"; // 版本
    private int[] colSizes; // 列名大小数组
    private boolean f_util = false; // 是否需要导入包java.util.*
    private boolean f_sql = false; // 是否需要导入包java.sql.*
    private boolean f_lang = false; // 是否需要导入包java.sql.*
    private String defaultPath = "/src/main/java/";
    // 数据库连接
    private static final String URL = "jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";//要修改
    private static final String NAME = "root";//要修改
    private static final String PASS = "123456";//要修改
    private static final String DRIVER = "com.mysql.jdbc.Driver";

    /*
     * 构造函数
     */
    public SqlHelper() {
    
    
        // 创建连接
        Connection con;
        // 查要生成实体类的表
        String sql = "select * from " + tablename;
        PreparedStatement pStemt = null;
        try {
    
    
            try {
    
    
                Class.forName(DRIVER);
            } catch (ClassNotFoundException e1) {
    
    
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            con = DriverManager.getConnection(URL, NAME, PASS);
            pStemt = con.prepareStatement(sql);
            ResultSetMetaData rsmd = pStemt.getMetaData();
            int size = rsmd.getColumnCount(); // 统计列
            colnames = new String[size];
            colTypes = new String[size];
            colSizes = new int[size];
            for (int i = 0; i < size; i++) {
    
    

                colnames[i] = rsmd.getColumnName(i + 1);
                colTypes[i] = rsmd.getColumnTypeName(i + 1);
                //自动生成包配置


                // if (colTypes[i].equalsIgnoreCase("datetime")) {
    
    
                // f_util = true;
                // }
                if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")
                        || colTypes[i].equalsIgnoreCase("datetime") || colTypes[i].equalsIgnoreCase("time")
                        || colTypes[i].equalsIgnoreCase("date") || colTypes[i].equalsIgnoreCase("datetime2")) {
    
    
                    f_sql = true;
                }
                // if (colTypes[i].equalsIgnoreCase("int")) {
    
    
                // f_lang = true;
                // }
                colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
            }

            String content = parse(colnames, colTypes, colSizes);

            try {
    
    
                File directory = new File("");

                String path = this.getClass().getResource("").getPath();

                System.out.println(path);

                String outputPath = directory.getAbsolutePath() + this.defaultPath
                        + this.packageOutPath.replace(".", "/") + "/" + initcap(underlineToHump(tablename)) + ".java";
                System.out.println("执行完毕,生成路径为:" + outputPath);
                FileWriter fw = new FileWriter(outputPath);
                PrintWriter pw = new PrintWriter(fw);
                pw.println(content);
                pw.flush();
                pw.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }

        } catch (SQLException e) {
    
    
            e.printStackTrace();
        } finally {
    
    

        }
    }

    /**
     * 功能:生成实体类主体代码
     *
     * @param colnames
     * @param colTypes
     * @param colSizes
     * @return
     */
    private String parse(String[] colnames, String[] colTypes, int[] colSizes) {
    
    
        StringBuffer sb = new StringBuffer();
        // 生成package包路径
        sb.append("package " + this.packageOutPath + ";\r\n");
        // 判断是否导入工具包
        if (f_util) {
    
    
            sb.append("import java.util.Date;\r\n");
        }
        if (f_sql) {
    
    
            sb.append("import java.sql.*;\r\n");
        }
        if (f_lang) {
    
    
            sb.append("import java.lang.*;\r\n");
        }
        sb.append("import lombok.Data;\r\n");

        sb.append("\r\n");
        // 注释部分
        sb.append("   /**\r\n");
        sb.append("    * @文件名称:" + initcap(underlineToHump(this.tablename)) + ".java\r\n");
        sb.append("    * @创建时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\r\n");
        sb.append("    * @创  建  人:" + this.authorName + " \r\n");
        sb.append("    * @文件描述:" + tablename + " 实体类\r\n");
        sb.append("    * @文件版本:" + this.version + " \r\n");
        sb.append("    */ \r\n");
        sb.append("\n\r\n@Data");
        // 实体部分
        sb.append("\npublic class " + initcap(underlineToHump(tablename)) + "{\r\n");
        processAllAttrs(sb);// 属性
//        processAllMethod(sb);// get set方法
        sb.append("}\r\n");

        // System.out.println(sb.toString());
        return sb.toString();
    }

    /**
     * 功能:生成所有属性
     *
     * @param sb
     */
    private void processAllAttrs(StringBuffer sb) {
    
    

        for (int i = 0; i < colnames.length; i++) {
    
    
            sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + this.underlineToHump(colnames[i]) + ";\r\n");
        }

    }

    /**
     * 功能:生成所有方法
     *
     * @param sb
     */
//    private void processAllMethod(StringBuffer sb) {
    
    
//
//        for (int i = 0; i < colnames.length; i++) {
    
    
//            sb.append("\tpublic void set" + initcap(colnames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " "
//                    + colnames[i] + "){\r\n");
//            sb.append("\tthis." + colnames[i] + "=" + colnames[i] + ";\r\n");
//            sb.append("\t}\r\n");
//            sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n");
//            sb.append("\t\treturn " + colnames[i] + ";\r\n");
//            sb.append("\t}\r\n");
//        }
//
//    }

    /**
     * 功能:将输入字符串的首字母改成大写
     *
     * @param str
     * @return
     */
    private String initcap(String str) {
    
    

        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
    
    
            ch[0] = (char) (ch[0] - 32);
        }

        return new String(ch);
    }

    /**
     * 功能:获得列的数据类型
     *
     * @param sqlType
     * @return
     */
    private String sqlType2JavaType(String sqlType) {
    
    

        if (sqlType.equalsIgnoreCase("bit")) {
    
    
            return "Boolean";
        } else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("money")
                || sqlType.equalsIgnoreCase("smallmoney") || sqlType.equalsIgnoreCase("numeric")
                || sqlType.equalsIgnoreCase("bigint")) {
    
    
            return "Long";
        } else if (sqlType.equalsIgnoreCase("float")) {
    
    
            return "Double";
        } else if (sqlType.equalsIgnoreCase("int") || sqlType.equalsIgnoreCase("int identity")) {
    
    
            return "Integer";
        } else if (sqlType.equalsIgnoreCase("image") || sqlType.equalsIgnoreCase("varbinary(max)")
                || sqlType.equalsIgnoreCase("varbinary") || sqlType.equalsIgnoreCase("udt")
                || sqlType.equalsIgnoreCase("binary")) {
    
    
            return "Byte[]";
        } else if (sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("nvarchar(max)")
                || sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nvarchar(ntext)")
                || sqlType.equalsIgnoreCase("uniqueidentifier") || sqlType.equalsIgnoreCase("xml")
                || sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("varchar(max)")
                || sqlType.equalsIgnoreCase("text") || sqlType.equalsIgnoreCase("varchar")) {
    
    
            return "String";
        } else if (sqlType.equalsIgnoreCase("real")) {
    
    
            return "Float";
        } else if (sqlType.equalsIgnoreCase("smallint") || sqlType.equalsIgnoreCase("tinyint")) {
    
    
            return "Short";
        } else if (sqlType.equalsIgnoreCase("date") || sqlType.equalsIgnoreCase("datetime")
                || sqlType.equalsIgnoreCase("time") || sqlType.equalsIgnoreCase("datetime2")
                || sqlType.equalsIgnoreCase("timestamp")) {
    
    
            return "Date";
        } else {
    
    
            System.out.println("数据类型异常,类型为:" + sqlType);
        }

        return null;
    }

    /**
     * 下划线转驼峰
     *
     * @String para
     */
    private String underlineToHump(String para) {
    
    
        StringBuilder result = new StringBuilder();
        String a[] = para.split("_");
        for (String s : a) {
    
    
            if (result.length() == 0) {
    
    
                result.append(s.toLowerCase());
            } else {
    
    
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }


    /**
     * 出口 TODO
     *
     * @param args
     */
    public static void main(String[] args) {
    
    

        new SqlHelper();

    }
}


Guess you like

Origin blog.csdn.net/dzdzdzd12347/article/details/130879045
Recommended