spring家族的springboot就像航天界冒出的SpaceX,降本增效提质。

hello world 即将成为 hello space。

1.springboot go

1.1 快速搭建springboot项目工程(就类似vue的vue-cli脚手架),next据需选配。

1.2 ​开箱即用

1.3 springboot go !

1.4 profile 环境切换

或者:

 1.5 logback日志(会先于springboot配置文件的加载)

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback</contextName>
    <!--输出到控制台 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss:SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤 INFO-->
            <level>INFO</level>
            <!--匹配到就禁止-->
            <onMatch>ACCEPT</onMatch>
            <!--没有匹配到就允许-->
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>%d{HH:mm:ss:SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!--滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径 -->
            <fileNamePattern>/data/log/demo/logs/demo.%d{yyyyMMddHH}.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>%d{HH:mm:ss:SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!--滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径 -->
            <fileNamePattern>/data/log/demo/logs/demo.error.%d{yyyyMMddHH}.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="fileLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

    <logger name="com.example.demo.mapper" level="DEBUG"/>

</configuration>

2.springboot + mybatis

2.1 maven pom引入mybatis依赖

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <druid-version>1.1.22</druid-version>
    <mybatis.version>3.5.0</mybatis.version>
    <mybatis-spring.version>2.0.0</mybatis-spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--mysql datasource-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid-version}</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>

    <!--mybatis-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>${mybatis.version}</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>${mybatis-spring.version}</version>
    </dependency>

    <!--page helper-->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.2.5</version>
    </dependency>

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

</dependencies>

2.2 yml 文件配置:

#server
server:
  port: 8100
  servlet:
    context-path: /demo

#spring
spring:
  application:
    name: demo

  #datasource
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://192.168.2.9:3306/demo? characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: demo
    password: demo123
    druid:
      initial-size: 2
      min-idle: 2
      max-active: 20
      max-wait: 60000
      remove-abandoned: true
      remove-abandoned-timeout: 60
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 30000
      validation-query: select 1
      test-on-return: true
      test-while-idle: true
      test-on-borrow: true
      # 打开PSCache,并且指定每个连接上PSCache的大小
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      filters: stat,wall,slf4j
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 合并多个DruidDataSource的监控数据 http://localhost:8100/demo/druid/index.html 
      # admin/admin
      useGlobalDataSourceStat: true
#mybatis
mybatis:
  mapper-locations: classpath:mapping/*.xml
  type-aliases-package: com.example.demo.entity.domain

#pagehelper
pagehelper:
  helper-dialect: mysql
  reasonable: false
  support-methods-arguments: true
  params: count=countSql

2.3 扫描mapper映射为DAO

2.4 数据库建表,使用mybatis-generator反向工程自动生成

      domain, mapping, mapper (查看官网教程或私信索要工具类)

创建Domain基类

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.Date;

@Slf4j
@Data
public class Domain implements Serializable {

    protected Integer id;
    protected Date createTime;
    protected Date updateTime;
    protected Byte delFlag;

}

修改自动生成的User 集成自Domain基类

public class User extends Domain {

    private String account;
    private String password;
}

创建BaseMapper

import com.example.demo.domain.Domain;
import com.github.pagehelper.Page;
import org.apache.ibatis.annotations.Param;

public interface BaseMapper<T extends Domain> {

    String PO_KEY = "po";

    int deleteByPrimaryKey(Integer id);

    int insert(T record);

    int insertSelective(T record);

    T selectByPrimaryKey(Integer id);

    int updateByPrimaryKey(T record);

    int updateByPrimaryKeySelective(T record);

    Page<T> queryByExample(@Param(PO_KEY) T record);

}

修改UserMapper 集成 BaseMapper

import com.example.demo.domain.User;
import org.apache.ibatis.annotations.Param;

public interface UserMapper extends BaseMapper<User> {

    User queryUserByAccount(@Param("account") String account);
}

追加扩展UserMapping功能

2.5 service层

BaseService

import com.example.demo.po.PagerRequest;
import com.github.pagehelper.Page;

import java.util.List;

public interface BaseService<T> {

    int insert(T record);

    int insertSelective(T record);

    int deleteByPrimaryKey(Integer id);

    int updateByPrimaryKey(T record);

    int updateByPrimaryKeySelective(T record);

    T selectByPrimaryKey(Integer id);

    Page<T> selectByPage(PagerRequest pagerRequest);

    List<T> queryByExample(T record);

}

BaseServiceImpl

import com.example.demo.domain.Domain;
import com.example.demo.mapper.BaseMapper;
import com.example.demo.po.PagerRequest;
import com.example.demo.service.BaseService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.ParameterizedType;
import java.util.List;

@Slf4j
public abstract class BaseServiceImpl<T extends Domain> implements BaseService<T> {

    @Autowired
    private BaseMapper<T> baseMapper;

    private Class<T> domain;

    public BaseServiceImpl() {
        ParameterizedType parameterizedType = ((ParameterizedType) getClass().getGenericSuperclass());
        domain = (Class<T>) parameterizedType.getActualTypeArguments()[0];
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insert(T record){
        return this.baseMapper.insert(record);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertSelective(T record){
        return this.baseMapper.insertSelective(record);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteByPrimaryKey(Integer id){
        return this.baseMapper.deleteByPrimaryKey(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateByPrimaryKey(T record){
        return this.baseMapper.updateByPrimaryKey(record);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateByPrimaryKeySelective(T record){
        return this.baseMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public T selectByPrimaryKey(Integer id){
        return this.baseMapper.selectByPrimaryKey(id);
    }

    @Override
    public Page<T> selectByPage(PagerRequest pagerRequest){
        try {
            PageHelper.startPage(pagerRequest.getPageNum(), pagerRequest.getPageSize());
            PageHelper.orderBy(pagerRequest.getOrderBy());

            T example = domain.newInstance();

            // 查询参数封装转换 (如分页查询User, 创建UserRequest extends PagerRequest, 
            // UserRequest中的查询参数与User对应的属性保持一致)
            BeanUtils.copyProperties(pagerRequest, example);

            // 在对应的mapping中覆写queryByExample方法
            return this.baseMapper.queryByExample(example);
        } catch (Exception e) {
            log.error("异常信息:{}", e.getMessage());
            throw new RuntimeException("查询参数异常", e);
        }
    }

    @Override
    public List<T> queryByExample(T record){
        return this.baseMapper.queryByExample(record);
    }

}

分页查询参数PagerRequest

@Data
public class PagerRequest {

  private int pageNum = 1;   // mybatis pagerHelper从0开始
    private int pageSize = 10; // 默认10条记录
    private String orderBy = "id desc"; // 默认按id降序
}
@EqualsAndHashCode(callSuper = true)
@Data
public class UserRequest extends PagerRequest {
    private String account;
}

UserService

import com.example.demo.domain.User;

public interface UserService extends BaseService<User> {

    User queryUserByAccount(String account);
}

UserServiceImpl

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User queryUserByAccount(String account) {
        return userMapper.queryUserByAccount(account);
    }

}

BaseService中方法不满足时,可在UserService中扩展实现方法


原本想整理springboot + ORM, mybatis 及 JPA一起搞了的,发现篇幅太长了不宜读,JPA且待下回分享。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐