开发流程

这里用一个简单的案例,描述了如何开发一个模块。

1. 了解需求

通过如下途径了解需求

  • 用例描述
  • 制作原型
  • 询问与讨论

2. 撰写 Sql

2.1 基本约定

  • 定义主键
    • 要加上表明
    • 预计记录超过 1 亿,那么组建用 BIGINT
  • 新加与变更字段
    • gmt_create
    • gmt_modified
  • 定义唯一索引(可选)
  • 定义索引(可选)
  • 所有索引必须加上表名

示例

DROP TABLE IF EXISTS wk_student;
create table wk_student (
student_id BIGINT unsigned NOT NULL AUTO_INCREMENT COMMENT '学生id',
student_name varchar(255) NOT NULL COMMENT '学生姓名',
student_age int COMMENT '学生年龄',
student_sex int COMMENT '学生性别',
gmt_create DATETIME DEFAULT CURRENT_TIMESTAMP NULL COMMENT '记录创建时间',
gmt_modified DATETIME DEFAULT CURRENT_TIMESTAMP NULL COMMENT '记录修改时间',
PRIMARY KEY (student_id),
UNIQUE KEY `wk_student_unique` (`student_name`)
) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COMMENT='学生表';

2.2 进行测试

先在一个测试库上测试一下是否有语法错误。

2.3 追加 flyway

如果在项目中使用了 flyway 的版本控制,那么还要麻烦一点。文件需要放在 db/migration 目录下

V1__Create_student_table.sql

  • V 为固定前缀分隔符,代表数据库版本化;
  • 21 为 SQL 脚本版本,’’ 翻译为小数点,2_1 即为 2.1 版本;
  • __为两个下划线,代表中间分隔符;
  • init_request 为 SQL 脚本名,概述本脚本要进行的操作;
  • .sql 为固定后缀。

3. 生成代码

使用步骤如下

3.1 修改配置文件

修改config.properties,主要修改的内容如下:

  • 要连接的数据库
  • 要生成的表
  • 要生成的包

3.2 执行生成

idea的Terminal中执行:

#执行下面的命令
./gradlew gen2

生成的文件在log,系统会先删除上次生成的代码,避免重复生成。

生成完毕后,建议去log目录中检查一下代码。

生成的代码有:

  • model
  • dao
  • service
  • constroller
  • test (可选)
  • mock.json (可选)

3.3 测试代码

将生成的代码复制到项目中,执行build,在代码中有自带的单元测试脚本,如果通过就表示脚本没有问题。

4. 追加新功能

尽量不要修改自动生成的代码

4.1 复杂 Sql 查询

  • 动态 Sql 语句
  • 修改mapper中的dao

4.2 其他注意事项

建议每追加一个 controller 的函数,就追加了测试方法,提高测试覆盖率。

5. 代码归档

commit 代码,并且 push 到服务器上。

对于比较复杂的代码,使用stopBug进行代码检查。

6. 功能描述

6.1 代码生成器

plugin中修改config.properties,然后执行genCodes来生成代码,生成的代码放在/log

生成的代码有:model、dao、service、controller、test,可以只用一部分,也可以全用。

6.2 Mybatis 增强

① lambda 的 Sql 语法

Mybatis 推出新的方法,效率提高了很多,就像写 Sql 语句一样,在 Java 中自由撰写。

代码生成器生成了基本的添加、删除、查询,还可以在这个基础进行灵活编码。

private boolean checkRoleIds(Integer[] roleIds){
Long ren = roleDao.count(c-> c.where(roleId,isIn(roleIds)));
if(roleIds.length>0 && ren.intValue()==roleIds.length){
return true;
}
throw new BusinessException("角色编号在数据库中没有找到:"+ Arrays.toString(roleIds));
}

② 分布式主键

为了提高系统效率,使用了数据库读写分离,系统中会对应多个 mysql 数据库。这样就要求分布式主键生成器。

下面的代码,就可以得到一个雪花分布式主键

Long snowId=IdUtil.getSnowId();

③ 自动填充字段

可以在配置文件中配置,当更新一条记录时,会自动将更新时间记录到相应的字段中。

例如:gmt_modified

wukong:
auto-fill-date-column:
enabled: true
columns: gmt_modified,gmt_test

④ 自动拼装 Sql

根据前台参数,自动拼接 Sql。

前台一般会有这样的查询界面,按照一定规则,能动态形成查询的 Sql 语句。例子见:DynamicSqlController

⑤ 通用 Mapper

正常情况下,Mybatis 撰写 Sql 操作,要实现 Model,Mapper 操作,这里提供了一个通用 Mapper: selectMapper

大大极化了 Sql 操作,只用写 Sql 语句就可以了,就可以把结果传递给前台。

@RequestMapping("/selectUser")
public List<Map> selectUser(){
String sql="select * from user where userid=123";
return selectMapper.select(sql);
}

⑥ 防止 Sql 注入

使用SqlSafeUtil类就可以。

6.3 集成安全框架

集成了 JWT 安全框架。可以直接使用。

① 实现了基本功能

登陆、注册、分配权限、删除用户等基本功能。

② 不受限配置

有些路径不需要权限认证,可以通过配置文件来配置。

6.4 代码测试

① 静态代码检查

静态代码检查在build/reports/spotbugs

② TestNG 单元测试

可以看例子代码

6.5 自动化文档

① API 接口文档

使用了 spring doc 来输出文档。

② 数据库文档

6.6 例子代码

wukong-examples里面的例子里面有一些参考的代码:

  • 不同 API 撰写
  • 权限认证
  • 动态 Sql
  • 文件上传下载