Spring 通用框架模板

一、Spring Boot + MyBatis 基本框架

1. 相关依赖

<parent>
  <!-- 该 maven 工程管理着我们 springboot 相关的 jar 包和插件 -->
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.5.RELEASE</version>
</parent>

<dependencies>

  <!-- 支持 web 环境,不用写版本号 -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  
  <!-- 数据库的 jar 包 -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <!-- SpringBoot2.2.5 的版本中 Mysql 是 mysql8.0 的,8 以下的版本需要手动导入 -->
    <!-- <version>5.1.38</version> -->
  </dependency>
  
  <!-- mybatis 与 springboot 的整合包 -->
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
  </dependency>

  <!-- druid 连接池(可选:德鲁伊-阿里巴巴的)-->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
  </dependency>

  <!-- lombok(可选:用于自动生成实体类 get、set 等方法) -->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
  
</dependencies>

2. 配置信息

2.1 启动类

package nep.akina;

// 声明当前类是一个 SpringBoot 项目的启动类
@SpringBootApplication
// 扫描 Mapper 接口的包下所有的 Mapper 接口,生成这些接口的代理对象,供业务 Service 注入使用
@MapperScan("nep.akina.mapper") 
public class DemoApplication {
    public static void main(String[] args) {
        // 使用启动类去启动或运行 Spring 程序
        SpringApplication.run(DemoApplication.class,args);
    }
}

2.2 application.yml项目主配置

# 可选:设置端口号(默认 8080)、配置上下文
server:
  port: 8080
  servlet:
    context-path: /
    
# 必选:数据库连接配置
spring:
  datasource:
    # 8.0+ 版本驱动,8.0 以下启动包 com.mysql.jdbc.Driver 
    driver-class-name: com.mysql.cj.jdbc.Driver 
    url: jdbc:mysql:///demo?serverTimezone=Asia/Shanghai&useSSL=false&characterEncoding=utf-8
    username: root
    password: 123456
    
    # 可选:配置连接池(默认的就可以了)springboot 2.02 默认使用 HikariCP,此处要替换成 Druid
    type: com.alibaba.druid.pool.DruidDataSource 
    # 可选:德鲁伊,可能会用到的配置
    druid: 
      # 初始化时建立物理连接的个数
      initial-size: 5 
      # 最小连接池连接数量,最小空闲数量
      min-idle: 5 
      # 最大连接池连接数量,最大活跃连接数
      max-active: 20 
      # 配置获取连接等待超时的时间
      max-wait: 60000 
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1
      testWhileIdle: true
      testOnBorrow: true
      testOnReturn: false
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      filters: stat,wall
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 德鲁伊连接池,内置提供一个 web 版的性能监控配置
      stat-view-servlet: 
     	# 允许哪些IP访问 druid 监控界面,多个 IP 以逗号分隔
        allow: 0.0.0.0 
        # 设置登录帐号
        login-username: admin 
        # 设置登录密码
        login-password: 123456 
        # 是否允许重置数据
        reset-enable: false 
        # 默认访问根路径是:/druid/;也可以自定义设置
        # url-pattern: /database/* 
        
# 可选:mybatis 配置
mybatis:
  configuration:
    # 开启驼峰字段转换,自动映射时将有下划线的字段的数据映射给驼峰字段
    map-underscore-to-camel-case: true 
  # 扫描实体类所在的包
  type-aliases-package: nep.akina.domain 
  
# 可选:日志打印级别
logging:
  level:
    nep.akina: trace

3. Mapper模板

// 如果配置了包扫描(@MapperScan)可以不加 @Mapper
@Mapper
public interface IDemoMapper {

    int insert(Entity entity);
    
    int update(Entity entity);
    
    int delete(Long id);
    
    int batchDel(List<Long> ids);
    
    List<Entity> list(Entity entity);
    
    int queryCount(EntityQuery entityQuery);
    
    List<Entity> queryList(EntityQuery entityQuery);
    
}

4. Mapper.xml模板

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="nep.akina.mapper.DemoMapper">

    <resultMap id="BaseResultMap" type="nep.akina.domain.Entity">
        <id column="id" property="id"/>
        <result column="field" property="field"/>
        <!-- 其他属性 -->
    </resultMap>
    
    <sql id="whereSql">
        <where>
            <if test="keyword != null and keyword != ''">
                and (name like concat('%',#{keyword},'%'))
            </if>
        </where>
    </sql>
    
    <insert id="insert" parameterType="classType?" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into tbl_table (field, ...) values(#{field}, ...)
    </insert>
    
    <update id="update" parameterType="entity?">
        update tbl_table 
            set field = #{field}, ...
        where id = #{id}
    </update>
    
    <delete id="delete" parameterType="long">
		delete from tbl_table where id = #{id}
    </delete>
    
    <delete id="batchDel" parameterType="arraylist">
        delete from tbl_table where id in
        <foreach collection="list" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>
    
    <select id="list" resultMap="BaseResultMap">
        select * from tbl_table
    </select>

    <select id="queryCount" parameterType="entityQuery?" resultType="long">
        select count(*) from tbl_table
        <include refid="whereSql"/>
    </select>

    <select id="queryList" parameterType="entityQuery?" resultMap="BaseResultMap">
        select * from tbl_table
        <include refid="whereSql"/>
        limit #{begin},#{pageSize}
    </select>

</mapper>

5. Service模板

5.1 接口

public interface IDemoService {

    int insert(Entity entity);
    
    int update(Entity entity);
    
    int delete(Long id);
    
    int batchDel(List<Long> ids);
    
    List<Entity> list(Entity entity);
    
    int queryCount(EntityQuery entityQuery);
    
    List<Entity> queryList(EntityQuery entityQuery);
    
}

5.2 服务

@Service
public class DemoService extends implements IDemoService {

    @Autowired
    private DemoMapper demoMapper;
    
    @Override
    public void insert(Entity entity) {
        demoMapper.insert(entity);
    }

    @Override
    public void update(Entity entity) {
        demoMapper.update(entity);
    }

    @Override
    public void delete(Long id) {
        demoMapper.delete(id);
    }

    @Override
    public void batchDel(List<Long> ids) {
        demoMapper.batchDel(ids);
    }
    
    @Override
    public List<Entity> list() {
        return demoMapper.list();
    }

    @Override
    public PageList<Entity> queryList(EntityQuery entityQuery) {
        PageList<Entity> res = new PageList<>();
        Integer total = baseMapper.queryCount(entityQuery);
        res.setTotal(total);
        List<Entity> list = baseMapper.queryList(entityQuery);
        res.setList(list);
        return res;
    }
    
}

6. Controller.java模板

@RestController
@RequestMapping("/demo")
public class DemoController {

    @Autowire
    private DemoService demoService;
    
    // 接口等相关代码
}

7. 加入自定义分页

7.1 分页查询基类

public class BaseQuery {
    /** 页 */
    private Integer pageIndex = 1;
    /** 数 */
    private Integer pageSize = 5;
    /** 查询关键字 */
    private String keyword;

    /**
     * 计算分页
     * @return 返回起始位置
     */
    public Integer getBegin() {
        return (this.pageIndex - 1) * pageSize;
    }
    /** get、set等方法 */
}

7.2 查询类

public class EntityQuery extends BaseQuery {
    /** 自定义查询参数 */
    private String customField;
    
    /** 其他查询参数 */
}

7.3 分页结果类

public class PageList<T> {
    /** 总数 */
    private Integer total;
    /** 数据 */
    private List<T> list;
}

二、Spring Cloud 基本框架(待续)