前文提要
最近大家是不是都有那种危机感,项目变多了,工时压紧了,老板说,我不管你加不加班,我只看结果,项目经理说,我不管你用什么技术栈,我只要没BUG,测试说,交互不管好不好,我们只搞光速推塔。你心说?那我走?
大家也发现了,以前要很多行代码才能实现的功能,现在变得格外简单,原因很多大佬开源了很多项目,很多大厂平台供我们选择,从此,无止尽的C+V操作变成了拼技术选型,拼方向,别人一行代码搞定的事情,一个类生成CRUD,你要不停的拷拷拷,BUG多少全凭心情,那为什么不选择一款开箱既用的产品呢?
功能概述
使用 Apache License 2.0 协议,源代码完全开源,无商业限制
代码生成器 | VS | Erupt |
---|---|---|
前端 + 后端 7 ~ 10 个文件 | 文件数量 | 仅需一个类文件 |
重新生成代码或修改已生成代码 | 修改字段 | 添加字段注解 |
需要手动执行建表 SQL | 建表语句 | 自动建表 |
需要整个工程,模块众多不好管理 | 初次部署 | 仅需引入 Jar 依赖即可,基础数据自动生成 |
需要熟悉代码生成器所提供的前端 API,有一定学习成本 | 前端代码 | 零前端代码 |
传统分层调用的方式开发 | 开发方式 | 全注解式开发 |
仅支持基本的数据组件复杂的组件需自定义 | 组件支持 | 支持23类表单组件,且支持一对多,多对多等复杂关系组件 |
一般只支持 MySQL | 数据库 | 支持 MySQL、Oracle、PostgreSQL、H2 等所有主流数据库 |
需要生成大量代码复制到项目中,功能越多维护成本越高 | 开发时间 | 仅需一个后端工程师,短时间就可以完成高质量后台管理系统 |
Java 代码 | 逻辑扩展 | 按需 @DataProxy 实现 |
表数量越多启动越慢 | 启动速度 | 百张表映射毫秒级初始化 |
import: 支持多数据源:
并且:项目内置了很多功能无需开发,开箱即用
简单实力
简单CRUD
@Erupt(
name = "简单的例子",
power = @Power(importable = true, export = true)
)
@Table(name = "t_simple") //数据库表名
@Entity
public class Simple extends BaseModel {
@EruptField(
views = @View(title = "文本"),
edit = @Edit(title = "文本", notNull = true, search = @Search)
)
private String input;
@EruptField(
views = @View(title = "数值", sortable = true),
edit = @Edit(title = "数值", search = @Search)
)
private Float number;
@EruptField(
views = @View(title = "布尔"),
edit = @Edit(title = "布尔", search = @Search)
)
private Boolean bool;
@EruptField(
views = @View(title = "时间"),
edit = @Edit(title = "时间", search = @Search(vague = true))
)
private Date date;
@EruptField(
views = @View(title = "滑动条"),
edit = @Edit(title = "滑动条", type = EditType.SLIDER, search = @Search,
sliderType = @SliderType(max = 90, markPoints = {0, 30, 60, 90}, dots = true))
)
private Integer slide;
@EruptField(
views = @View(title = "下拉选择"),
edit = @Edit(
search = @Search,
title = "下拉选择", type = EditType.CHOICE,
choiceType = @ChoiceType(fetchHandler = SqlChoiceFetchHandler.class,
fetchHandlerParams = "select id,name from e_upms_menu"
)
)
)
private Long choice;
}
像这种带有CRUD功能的表单,只需要这样几行代码,一个文件就可以了
那你选择写Controller、Service、Dao、View + HTML语法,还是写这几行代码呢?
简单上传附件
@Column(length = 120)
@EruptField(
views = @View(title = "附件",
type = ViewType.ATTACHMENT),
edit = @Edit(title = "附件", type = EditType.ATTACHMENT,
attachmentType = @AttachmentType(fileTypes = {"PDF","PNG","JPEG","ZIP"}, maxLimit = 1))
)
private String fileUrl;
这是给你封装好的上传附件组件,无需其他代码,非常好用
一对多级联
@ManyToMany
@JoinTable(
name = "COMMON_ZY_SZHJXZY",
joinColumns = {@JoinColumn(
name = "zbid",
referencedColumnName = "id"
)},
inverseJoinColumns = {@JoinColumn(
name = "ywid",
referencedColumnName = "id"
)}
)
@EruptField(
edit = @Edit(
title = "仿真实习实训软件面向专业",
type = EditType.TAB_TABLE_REFER,
notNull = true,
search = @Search(vague = true)
),
sort = 45
)
private Set<ZyjsZyszView> zyjsZyszs;
高级用法
自定义数据源
如果你的数据源不是项目链接的单标,是从接口或者其他库获得的,我们可以采用多数据源
代码实力
//注入启动类
@Bean
public ApplicationRunner appRunner() {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
DataProcessorManager.register("BndhdDataSource", BndhdDataService.class);
}
};
}
实体类
@Erupt(
name = "SCHOOL_ACTIVITY_ZYJY",
desc = "本年度活动表"
)
@EruptDataProcessor("BndhdDataSource")
@Entity
@Getter
@Setter
@DynamicInsert
@DynamicUpdate
@Power(delete = false)
public class Bndhd{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "sys_uuid")
@GenericGenerator(name = "sys_uuid", strategy = "uuid")
@Column(name = "id", length = 64)
@EruptField
private String id;
@Column(length = 400)
@EruptField(
views = @View(
title = "学校名称",
desc = "学校名称",
width = "120"
),
edit = @Edit(
title = "学校名称",
desc = "学校名称",
search = @Search(vague = true)
)
)
private String XXMC;
@Column(length = 400)
@EruptField(
views = @View(
title = "活动名称",
desc = "活动名称",
width = "120"
)
)
private String HDMC;
@Column(length = 400)
@EruptField(
views = @View(
title = "活动类型",
desc = "活动类型",
width = "120"
),
edit = @Edit(
title = "活动类型",
desc = "活动类型",
search = @Search
)
)
private String HDLX;
@Column(length = 400)
@EruptField(
views = @View(
title = "活动开始时间",
desc = "活动开始时间",
width = "120"
)
)
private String HDKSRQ;
@Column(length = 400)
@EruptField(
views = @View(
title = "活动结束时间",
desc = "活动结束时间",
width = "120"
)
)
private String HDJSRQ;
@Column(length = 400)
@EruptField(
views = @View(
title = "目前状态",
desc = "目前状态",
width = "120"
)
)
private String MQZT;
}
重写数据源方法
@Service
public class BndhdDataService implements IEruptDataService {
@Autowired
private JdbcTemplateService jdbcTemplateService;
@Override
public PowerObject power(){
PowerObject powerObject = new PowerObject();
powerObject.setDelete(false);
powerObject.setAdd(false);
powerObject.setEdit(false);
powerObject.setViewDetails(false);
return powerObject;
}
@Override
public Object findDataById(EruptModel eruptModel, Object id) {
return null;
}
@Override
public Page queryList(EruptModel eruptModel, Page page, EruptQuery eruptQuery) {
Page pageResult = new Page();
pageResult.setPageSize(page.getPageSize());
String queryParam = "";
// 职业教育活动周
String zyhdzSql = "SELECT XXDM XXDM,HDMC,'职业教育活动周' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_ZYJY WHERE IS_DELETE = '0' ";
// 文明风采
String wmfcSql = "SELECT XXDM XXDM,HDMC,'文明风采' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_WMFC WHERE IS_DELETE = '0' ";
// 其他
String qtSql = "SELECT XXDM XXDM,HDMC,'其他' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_QT WHERE IS_DELETE = '0' ";
// 大国工匠
String dggjSql = "SELECT XXDM XXDM,HDMC,'大国工匠' HDLX,HDKSRQ HDKSRQ,HDJSRQ HDJSRQ FROM SCHOOL_ACTIVITY_DGGJ WHERE IS_DELETE = '0'";
String queryMainSql = "";
List<Condition> conditions = eruptQuery.getConditions();
Map<String, String> keyToQueryMainSql = new HashMap<>();
keyToQueryMainSql.put("职业教育活动周", zyhdzSql);
keyToQueryMainSql.put("文明风采", wmfcSql);
keyToQueryMainSql.put("其他", qtSql);
keyToQueryMainSql.put("大国工匠", dggjSql);
Boolean isDggj = true;
for (Condition condition : conditions) {
String key = condition.getKey();
if (ObjUtil.isNotEmpty(condition.getValue())) {
String value = condition.getValue().toString();
if (key.equals("XXMC")) {
queryParam = " AND T.XXMC = '" + value + "'";
} else if (key.equals("HDLX") && keyToQueryMainSql.containsKey(value)) {
queryMainSql = keyToQueryMainSql.get(value);
isDggj = false;
} else if(key.equals("HDLX") && !keyToQueryMainSql.containsKey(value)){
queryParam = " AND T.XXMC = '」@「'";
}
}
}
if (isDggj) {
StringBuilder sb = new StringBuilder();
keyToQueryMainSql.forEach((k, v) -> {
sb.append(v).append(" UNION ALL ");
});
queryMainSql = sb.substring(0, sb.length() - " UNION ALL ".length());
}
String dySql = "SELECT T.XXDM,T.XXMC,T.XXXZQHM AS REGIONID,REGION.NAME REGIONNAME,T.HDLX,T.HDMC,T.HDKSRQ,T.HDJSRQ, " +
"case when to_date(T.HDJSRQ,'') > sysdate then '未结束' else '结束' end as mqzt " +
"FROM ( " +
"SELECT T.XXDM,T.HDMC,T.HDLX,T.HDKSRQ,T.HDJSRQ,SCHOOL_INFO.XXXZQHM,SCHOOL_INFO.XXMC " +
"FROM " +
"( " + queryMainSql + ") T " +
"INNER JOIN SCHOOL_INFO ON ( T.XXDM = SCHOOL_INFO.XXDM) ) T " +
"INNER JOIN REGION ON T.XXXZQHM = REGION.ID " + queryParam;
String countSql = "SELECT COUNT(*) FROM (" + dySql + ") T";
Integer count = jdbcTemplateService.getValue(countSql);
long longValue = count.longValue();
pageResult.setTotal(longValue);
List<Map<String, Object>> bndhdList = new ArrayList<>();
bndhdList = jdbcTemplateService.getListMap(dySql);
pageResult.setList(bndhdList);
return pageResult;
}
@Override
public Collection<Map<String, Object>> queryColumn(EruptModel eruptModel, List<Column> columns, EruptQuery eruptQuery) {
return null;
}
@Override
public void addData(EruptModel eruptModel, Object object) {
}
@Override
public void editData(EruptModel eruptModel, Object object) {
}
@Override
public void deleteData(EruptModel eruptModel, Object object) {
}
}
重写登陆方法
用户表
--用户信息查询
select * from E_UPMS_USER where name = '李四'
流程测试用,不需要记住这么多密码
@Slf4j
@Service
public class MscLoginProxy implements LoginProxy {
@Autowired
private EruptDao eruptDao;
@Override
public EruptUser login(String account, String pwd) {
log.debug("当前登录用户名:【{}】", account);
LoginModel loginModel = login(account);
return loginModel.getEruptUser();
}
public LoginModel login(String account){
EruptUser eruptUser = eruptDao.lambdaQuery(EruptUser.class).eq(EruptUser::getAccount, account).one();
return new LoginModel(true, eruptUser);
}
}
怎么样?喜欢玩攻速流的程序员们心动了吗?现在Enjoy your time!