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且待下回分享。
相关文章
暂无评论...
