经理:小王,隔壁组要读我们的数据,赶紧把接口程序做一下!
经理:小王,五年前的jsp项目,能不能把商品信息改造一下,做一个数据api?
经理:小王,明天要给可以做一个大屏展示,今天能把数据接口调好吗?、
王小面:我太难了@~@
经理:你还在手工写 RestController?试试 “接口配置服务” 啊
Magic-API 是什么
Magic-API是一个接口框架,可以快速开发服务接口程序,是一个纯Java开源项目。
开发人员只要用magic-api的可视化界面完成,无需Java编码,配置完成后,自动发布为HTTP服务。
什么,你还写controller、dao?这种Java类根本不用写,只要配置脚本,就能完成绝大部分的Restful服务开发。
简化所需Java知识背景,只要会写SQL,直接就能做数据
一、特点
- 支持常规关系型数据库,比如MySQL,Oracle等常见的
- 还支持Redis、MongoDB、ES等非关系型,DataW等同类产品不支持
- 配置数据以文件形式存放,DataW等需要建个数据库存配置
- 支持在线调试
- 支持参数配置,比如必填、格式等等
- 支持Linq,做.net的觉得很好,未来可期
- 支持实现上传下载流的API,而非简单的文本交互
- 支持脚本中混排Java代码
- 支持脚本的版本管理
二、尝试使用
2.1 准备工作
数据库:MySQL
表:用户信息表 t_user
列名 | 含义 | 类型 |
---|---|---|
id | 序号 | integer |
account | 登录名 | varchar |
name | 昵称 | varchar |
gender | 性别 | varchar |
avatar | 头像 | varchar |
2.2 目标
- 不写controller、不写dao、没有orm配置、没有实体类等针对此表的Java代码
- 快速创建针对表CRUD的API
- 实现复杂的查询数据API
- 接口参数控制管理
三、开发步骤
3.1 创建新项目
1.新建SpringBoot项目:magicdemo,包名 com.demo.magic
2.pom.xml加入以下内容
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
3.配置application.yml
简易配置,只需配置以下内容
代码语言:javascript复制magic-api:
resource:
location: d:/cfg/magic-api #配置文件存储位置。当以classpath开头时,为只读模式
web: /magic/web #配置web页面入口
server:
port: 6408
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.2.133:3306/test?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: testuser
password: testpass
type: com.zaxxer.hikari.HikariDataSource
如果需要,可以对magic-api的内容做更复杂的配置,例如:
代码语言:javascript复制magic-api:
resource:
location: d:/cfg/magic-api #配置文件存储位置。当以classpath开头时,为只读模式
web: /magic/web #配置web页面入口
page: # 可不配置, 后续内容全会用默认值
size: size # 页大小的请求参数名称 缺省时为size
page: page # 页码的请求参数名称 缺省时为page
default-page: 1 # 自定义默认首页 缺省时为1
default-size: 10 # 自定义为默认页大小 缺省时为10
response-code: # 可不配置
success: 200 #执行成功的code值
invalid: 400 #参数验证未通过的code值
exception: 500 #执行出现异常的code值
复杂配置可对分页、状态码等内容做自定义,具体可参考官方文档 https://www.ssssssss.org/magic-api
配置完成后,启动boot项目,控制台将会出现以下文字:
代码语言:javascript复制服务启动成功,magic-api已内置启动! Access URLs:
接口本地地址: http://localhost:6408/
接口外部地址: http://192.168.2.133:6408/
接口配置平台: http://192.168.2.133:6408/magic/web/index.html
此时打开配置平台地址就可以使用了,完全不用写业务代码
3.2 配置CRUD的API
本阶段目标:
1.通过配置完成 t_user 表的CRUD功能实现
2.仅在控制台上做脚本配置,不写任何一个java文件
3.2.1 创建分组
点击新建分组
代码语言:javascript复制组名:用户管理
路径:user
3.2.2 创建查询列表
1.右键分组user,新建接口
2.下方接口信息里输入:
代码语言:javascript复制请求方法:get
接口名称:查询全部用户
接口路径:listall
3.右侧的大文本框内,输入以下脚本
代码语言:javascript复制return db.table('t_user').select()
4.点击右上方运行,或者ctrl Q,就会在下方控制台输出响应内容
代码语言:javascript复制{
"code": 200,
"message": "success",
"data": [{
"id": 1,
"account": "xiaoming",
"name": "小明",
"gender": "男",
"avatar": "https://www.qq.com/logo.png"
}, {
"id": 2,
"account": "xiaohong",
"name": "小红",
"gender": "女",
"avatar": "https://www.qq.com/logo2.png"
}],
"timestamp": 1660810934840,
"executeTime": 30
}
我们第一个API就实现完成了。
此时可以使用发布路径调试,在浏览器访问 http://192.168.2.133:6408/user/listall
就会看到和调试相同的结果。
3.2.3 创建保存方法
保存API的实现,我们要求request传入body,为json格式的t_user表内容,然后进行保存
1.右键分组user,新建接口
2.下方接口信息里输入:
代码语言:javascript复制请求方法:post
接口名称:保存新用户
接口路径:save
3.右侧的大文本框内,输入以下脚本
代码语言:javascript复制return db.table('t_user').insert(body)
4.在下方接口信息的请求body里,输入以下内容,t_user表的id由于数据表设为自增,body不赋值
代码语言:javascript复制{
"account": "xiaoling",
"name": "小玲",
"gender": "女",
"avatar": "https://www.qq.com/face.png"
}
点击右上方运行,就会在下方控制台输出响应内容
代码语言:javascript复制{
"code": 200,
"message": "success",
"data": 4,
"timestamp": 1660811763708,
"executeTime": 22
}
5.此时查询数据库,就会看到新插入的记录了
3.2.4 创建更新方法
更新和保存很相似,仍然是通过post,将body内容更新数据表
1.前面步骤类似,创建update接口,脚本内容为:
代码语言:javascript复制# primary表示根据主键id进行更新
return db.table('t_user').primary("id").update(body)
2.测试body如下:
代码语言:javascript复制{
"id": 3,
"account": "xiaoling3",
"name": "小玲3",
"gender": "男",
"avatar": "https://www.qq.com/face3.png"
}
结果提示成果,数据表内容也改了。
3.2.5 saveOrUpdate的实现
经常使用ORM的同学,习惯于用saveOrUpdate的方式,自动决定insert还是update,脚本里可以使用save实现:
代码语言:javascript复制 # 1. 如果body里有id,则是update,否则是insert
db.table('t_good').primary('id').save(body)
# 2. 显式调用insert / update
db.table('t_good').primary('id').insert(body)
db.table('t_good').primary('id').update(body)
3.2.6 创建删除方法
步骤跟前面类似,关键的脚本如下:
代码语言:javascript复制 db.table('t_user')
.where()
.eq("id", id)
.delete()
此时,需要在接口的请求参数里,添加参数
代码语言:javascript复制 id 3 integer
执行时就会删除where id=3的记录。
如果不传,则会认为是 where id is null
以上就是一套单表的简单CRUD接口创建过程
3.3 配置条件查询API
这个环节我们解决几个常见的数据查询用法
1.分页查询
2.手写SQL语句
3.带参查询
4.动态SQL语句
5.MyBatis风格写法
3.3.1 分页查询
简单用法,将原来的语句
代码语言:javascript复制 return db.table('t_user').select()
改成
代码语言:javascript复制 return db.table('t_user').page()
就可以了
此时请求参数,可以增加page和size作为条件
例如输入 page=1, size=5, 都是integer类型, 则会取第1页的5行记录
此处页码从1开始,有的数据库分页是从0开始的,这里统一按照人类习惯从1开始算页数。
3.3.2 手写SQL语句
前面的例子,都是针对单个表的查询,但我们经常需要对多个表进行联查,或者写一些特定的SQL语句,可以采用以下方法:
代码语言:javascript复制 var sql="""
select * from t_user order by id desc
"""
return db.select(sql)
三引号运算符,确保里面的内容无需被转义。这种写法可以完全自由发挥你的SQL书写能力。
3.3.3 查询参数使用
代码语言:javascript复制 var sql="""
select * from t_user where gender=#{gender} order by id
"""
return db.select(sql)
与上个例子相比,增加了gender参数,此时从请求参数处,会接收名为gender的参数
参数有两种使用方法,#{} 和 ${},区别为:
代码语言:javascript复制 #{}时,输出查询语句为
select * from t_user where gender=? order by id
${}时,输出查询语句为
select * from t_user where gender='男' order by id
#采用防注入占位符方式,$采用字符拼接方式,因此在String参数时,脚本写法也不一样,以下两者是等价的,注意单引号
select * from t_user where gender=#{gender} order by id
select * from t_user where gender='${gender}' order by id
3.3.4 动态SQL语句
在做条件查询时,经常遇到参数不确定的情况,此时需要动态语句支持
例如:参数gender和name作为查询条件,都是可有可无的,则脚本如下:
代码语言:javascript复制 var sql="""
select * from t_user where 1=1
?{gender!=null && gender!="", and gender=#{gender}}
?{name!=null && name!="", and name like '%${name}%'}
order by id
"""
return db.select(sql)
?表示这一行是一个可选条件,如果满足,则增加 and xx=? 子句,实现了一个简单的sql语句拼接
同时我们也可以看到,针对like条件,用$传参更容易操作模糊匹配
3.3.5 动态SQL语句MyBatis的方式
前一种方法,如果用不习惯,还是需要花点时间理解的。
MagicAPI提供了类似MyBatis的写法,如下:
代码语言:javascript复制 var sql="""
select * from t_user where 1=1
<if test="gender!=null and gender!=''">
and gender=#{gender}
</if>
<if test="name!=null and name!=''">
and name like '%${name}%'
</if>
order by id
"""
return db.select(sql)
这种if方式,对于MyBatis或者jsp爱好者,看起来更为亲切。
3.4 接口参数控制
接口发布时,经常要对入参进行约束,包括:
1.参数必填和选填
2.入参的格式,例如手机号,身份证,长度和正则等验证
3.错误提示,如某个参数有误,给出的提示语
直接可以用MagicAPI的参数信息面板完成设置
3.4.1 参数必填、选填
勾中必填选项,则会进行入参验证,相当于写代码时自己Assert.notNull等操作
对非必填项,还可以设置默认值。注意,必填项的默认值无效,只有非必填参数没传参时,会采用默认值
3.4.2 参数类型
可以对参数类型进行选择,支持常规参数类型,以及附件格式
3.4.3 参数验证
支持表达式验证,和正则验证方式,结合表达式和验证说明配置,可以做出丰富的效果
正则验证:
代码语言:javascript复制 参数 age
正则写为 ^d $
验证说明 age必须为数字
表达式验证
代码语言:javascript复制 参数 mobile
表达式写为 mobile.length() == 11
验证说明 手机号必须是11位
这样我们就可以快速搭建好API服务了
更多示范请参考:
https://magic-api.ssssssss.org.cn/magic/web/index.html
代码语言:javascript复制 # 1小时之后
王小面:经理,做完了
经理:测了吗?
王小面:当然啊,工具自带了冒烟测试呢
经理:干得漂亮,周末请你吃饭!