当前位置:   article > 正文

关于Java+Vue3快速开发框架esdk-nzb-cas的介绍

esdk

我为什么要写这么一篇文章呢?因为我从事java开发20余载,看着各种jdbc框架、应用框架一直在演变升级,却始终达不到我对Java项目的快速开发要求,所以忍不住把我多年经验积累的快速开发框架共享出来,希望能给java界带来一丝凉风,让大家体验不一样的开发。不过,认为springboot和mybatis是最好的同学可以不用看了,因为我不一个主流技术控,我是一个完美主义者,我追求的是开发的效率和质量,并且把代码的简洁放在了首位,享受着敲代码带给我的快乐。

这次介绍的是我个人比较喜欢的优点,如果不是为了这些优点,那我就没必要造轮子了,但是我的文笔不行,所以这篇文章只是一个开端,我先介绍我个人最喜欢的功能,也就是这个快速开发框架的亮点,我以后会逐步把这个快速开发框架做为一个教程全部写出来。

  1. 支持子查询和联表查询,每个Select对象都可以被重用。

  1. // 子查询示例:(DF是DaoFactory的缩写。Select、RowSet对象不需要我解释了吧?)
  2. String[] orderNumbers=["1111","2222"];
  3. ClientOrderSelect cos=DF.clientOrderSelect().setClientOrder(orderNumbers);
  4. OrderGoodsRowSet ogrs=DF.orderGoodsSelect().setOrderId(cos).toRowSet();
  5. // 对应sql:select * from order_goods where order_id in (select order_id from client_order where orderNumber in ('1111','2222'))
  1. Select对象可直接获取SQL,可重用,可以子表、联表查询,直接生成sql,加个select.useCache(true)就可以启用缓存,可以选择是否打印sql日志,可以极方便的使用or条件等等,这些优点都是Mybatis所没有的。

  1. //最简单的sql查询,可在执行sql之前使用.toString()打印出可直接执行的sql,方便直接复制客户端直接运行
  2. TestUserSelect tus=new TestUserSelect(conn).setUserCode("admin").setValid(true);
  3. esdk.tool.assertEquals(tus.toString(),"SELECT * FROM test_user WHERE user_code='admin' AND valid=1");
  4. //非常方便地使用Redis二级缓存。两种方式:true:默认15分钟;1000:1000秒。
  5. tus.useCache(true).toRowSet()
  6. tus.useCache(1000).toRowSet()
  7. //默认打印SQL日志,但是遇到一些频率非常高但意义不大的sql,看着就烦,有什么办法过滤掉呢?
  8. tus.showSql(false).toRowSet()
  9. //写or条件好麻烦,懂的人都懂,有什么更好的表达方式呢?我认为最完美的表达方式是这样的:
  10. tus.setValid(true).setSex("男");
  11. //tus.md对应的是TestUserMetaData.java静态类,是一个表基础信息类,可读取该表的所有信息,如字段名,备注名,主键名,唯一索引,默认值等。但为了方便表达,我后面都会有字符串表示,但实际项目上我不会直接用字符串,而是用MetaData类。
  12. tus.or(tus.md.UserName,"张三","login_name","like","test%")
  13. //输出SQL: SELECT * FROM test_user WHERE valid=1 and sex="男" and (user_name='张三' OR login_name like 'test%')
  14. //联表查询,这是我认为最好的表达方式了,也是esdk这个ORM框架的一个核心优点,而mybatisplus一直都做不到:
  15. TestCenterSelect tcs=DF.testCenterSelect().setCenterId(108).setOrder("category")
  16. JoinSelect cs=new JoinSelect(conn,tus,tcs).on(tcs,tds);
  17. esdk.tool.assertEquals(cs.getSQL(),"SELECT tu.*,tc.* from test_user tu left join test_center tc on tc.center_id=tu.center_id where tu.valid=1 and tu.sex='男' and tc.center_id=108 ORDER BY tc.category LIMIT 50");
  1. 说一下批处理插入/批更新量量,10万条记录可以批量分段插入,做数据迁移太方便了:

  1. JDBCTemplate jd=new JDBCTemplate(connSrc,"select * from "+srcTableName+" where id>? order by id limit ? offset ?",lastId,limit,offset);
  2. BatchInsert bi=new BatchInsert(distTableName ,connDist).
  3. ABResultSet<IRow> rs=jd.toABResultSet();
  4. BatchInsert bi=new BatchInsert(distTableName,connDist);
  5. log.info("正在读取源数据");
  6. TimeMeter tm1=new TimeMeter();
  7. for(IRow row=rs.getNextRow();row!=null;row=rs.getNextRow()){
  8. bi.addValue(row);
  9. }
  10. log.info("正在按10000条分段写入目标数据库");
  11. int count=bi.perform(10000,true);
  1. // 超过1万的日志打印出来的话会刷爆屏的,更会占用大量io和内存,优化为超过10条就省略。
  2. 2023-03-09 17:42:31,337 esdk warn 耗时:756ms, SQL:Insert Into member_point_record (id,points_account_id,points_account_code,trade_id,points,status,expired_date,expired,remark,create_time,member_model_id,channel,channel_no,effective_date,tenant_id,create_person,update_person,update_time,dr,migrated_time,instance_id,extension,current_points,available_points,trade_type,member_id,order_no,point_type,sync_type,businessId,shop_code,record_id,un_freeze_time,business_id,member_no,before_point,after_point) values (3345116,1328265456742041456,'',null,20,1,'2021-02-25 20:58:30',0,'获得积分','2020-02-26 20:58:30',null,'官方商城',null,null,null,null,null,'2023-01-10 16:24:11',0,null,null,'946.00',null,null,2,1328265456506111730,null,null,0,null,null,null,'2020-02-26 20:58:30','3345116',1312327918374372345,'1001519678',946,966)...共插入10000条记录;
  1. 为什么要用nutzboot?因为快,好用,上手容易。目前应用启动只需要2秒(Jetty启动占了1.5秒),占用内存不到50M,真正做到了“微”服务。

  1. Connected to the target VM, address: '127.0.0.1:49653', transport: 'socket'
  2. 2023-03-26 10:17:03,173 [ INFO][SimpleBannerPrinter:34]
  3. _ _ ______ ___
  4. | \ | || ___ \ ______ ______ ______ ______ ______| \ \
  5. | \| || |_/ / |______|______|______|______|______| |\ \
  6. | . ` || ___ \ ______ ______ ______ ______ ______| | > >
  7. | |\ || |_/ / |______|______|______|______|______| |/ /
  8. \_| \_/\____/ |_/_/
  9. :: Nutz Boot :: (2.4.2.v20201205)
  10. 2023-03-26 10:17:03,322 [ INFO][AnnotationIocLoader:47] > scan 'com.baijian.cas'
  11. 2023-03-26 10:17:03,421 [ INFO][AnnotationIocLoader:99] > add 'permissionFilter ' - com.baijian.cas.filter.PermissionFilter
  12. 2023-03-26 10:17:03,432 [ INFO][AnnotationIocLoader:99] > add 'mainLauncher ' - com.baijian.cas.MainLauncher
  13. 2023-03-26 10:17:03,440 [ INFO][AnnotationIocLoader:99] > add 'loginModule ' - com.baijian.cas.module.LoginModule
  14. 2023-03-26 10:17:03,461 [ INFO][AnnotationIocLoader:99] > add 'sysButtonModule ' - com.baijian.cas.module.SysButtonModule
  15. 2023-03-26 10:17:03,469 [ INFO][AnnotationIocLoader:99] > add 'sysDictModule ' - com.baijian.cas.module.SysDictModule
  16. 2023-03-26 10:17:03,474 [ INFO][AnnotationIocLoader:99] > add 'sysMenuModule ' - com.baijian.cas.module.SysMenuModule
  17. 2023-03-26 10:17:03,478 [ INFO][AnnotationIocLoader:99] > add 'sysOrgModule ' - com.baijian.cas.module.SysOrgModule
  18. 2023-03-26 10:17:03,479 [ INFO][AnnotationIocLoader:99] > add 'sysRoleModule ' - com.baijian.cas.module.SysRoleModule
  19. 2023-03-26 10:17:03,480 [ INFO][AnnotationIocLoader:99] > add 'sysTenantModule ' - com.baijian.cas.module.SysTenantModule
  20. 2023-03-26 10:17:03,482 [ INFO][AnnotationIocLoader:99] > add 'sysUserModule ' - com.baijian.cas.module.SysUserModule
  21. 2023-03-26 10:17:03,483 [ INFO][AnnotationIocLoader:99] > add 'testModule ' - com.baijian.cas.module.TestModule
  22. 2023-03-26 10:17:03,487 [ INFO][AnnotationIocLoader:99] > add 'uploadModule ' - com.baijian.cas.module.UploadModule
  23. 2023-03-26 10:17:03,488 [ INFO][AnnotationIocLoader:99] > add 'schedule ' - com.baijian.cas.schedule.Schedule
  24. 2023-03-26 10:17:03,488 [ INFO][AnnotationIocLoader:99] > add 'sysRolePermissionService ' - com.baijian.cas.service.SysRolePermissionService
  25. 2023-03-26 10:17:03,489 [ INFO][AnnotationIocLoader:47] > scan 'com.baijian.framework.filter'
  26. 2023-03-26 10:17:03,498 [ INFO][AnnotationIocLoader:99] > add 'accessControlAllowOriginFilter ' - com.baijian.framework.filter.AccessControlAllowOriginFilter
  27. 2023-03-26 10:17:03,500 [ INFO][AnnotationIocLoader:99] > add 'authorizationFilter ' - com.baijian.framework.filter.AuthorizationFilter
  28. 2023-03-26 10:17:03,501 [ INFO][AnnotationIocLoader:99] > add 'browserCacheFilter ' - com.baijian.framework.filter.BrowserCacheFilter
  29. 2023-03-26 10:17:03,502 [ INFO][AnnotationIocLoader:99] > add 'corsWebFilterFace ' - com.baijian.framework.filter.CorsWebFilterFace
  30. 2023-03-26 10:17:03,503 [ INFO][AnnotationIocLoader:47] > scan 'com.baijian.framework.processor'
  31. 2023-03-26 10:17:03,512 [ INFO][AnnotationIocLoader:99] > add 'accessLogProcessor ' - com.baijian.framework.processor.AccessLogProcessor
  32. 2023-03-26 10:17:03,514 [ INFO][AnnotationIocLoader:99] > add 'exceptionProcessor ' - com.baijian.framework.processor.ExceptionProcessor
  33. 2023-03-26 10:17:03,514 [ INFO][AnnotationIocLoader:99] > add 'moduleInterceptor ' - com.baijian.framework.processor.ModuleInterceptor
  34. 2023-03-26 10:17:03,515 [ INFO][AnnotationIocLoader:47] > scan 'com.baijian.framework.service'
  35. 2023-03-26 10:17:03,521 [ INFO][AnnotationIocLoader:99] > add 'registerService ' - com.baijian.framework.service.RegisterService
  36. 2023-03-26 10:17:03,522 [ INFO][AnnotationIocLoader:99] > add 'restApiService ' - com.baijian.framework.service.RestApiService
  37. 2023-03-26 10:17:03,523 [ INFO][AnnotationIocLoader:47] > scan 'org.nutz.boot.starter'
  38. 2023-03-26 10:17:03,543 [ INFO][AnnotationIocLoader:99] > add 'whaleFilterStarter ' - org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter
  39. 2023-03-26 10:17:03,545 [ INFO][AnnotationIocLoader:99] > add 'nutFilterStarter ' - org.nutz.boot.starter.nutz.mvc.NutFilterStarter
  40. 2023-03-26 10:17:03,546 [ INFO][AnnotationIocLoader:99] > add 'jettyStarter ' - org.nutz.boot.starter.jetty.JettyStarter
  41. 2023-03-26 10:17:03,567 [ INFO][AnnotationIocLoader:99] > add 'preventDuplicateSubmitStarter ' - org.nutz.boot.starter.PreventDuplicateSubmitStarter
  42. 2023-03-26 10:17:03,567 [ INFO][AnnotationIocLoader:99] > add 'dataSourceStarter ' - org.nutz.boot.starter.jdbc.DataSourceStarter
  43. 2023-03-26 10:17:03,568 [ INFO][AnnotationIocLoader:99] > add 'druidWebStatFilterStarter ' - org.nutz.boot.starter.jdbc.DruidWebStatFilterStarter
  44. 2023-03-26 10:17:03,568 [ INFO][AnnotationIocLoader:99] > add 'druidWebStatServletStarter ' - org.nutz.boot.starter.jdbc.DruidWebStatServletStarter
  45. 2023-03-26 10:17:03,569 [ INFO][AnnotationIocLoader:99] > add 'nbServletContextListener ' - org.nutz.boot.starter.servlet3.NbServletContextListener
  46. 2023-03-26 10:17:03,581 [ INFO][NutIoc:130] ... NutIoc init complete
  47. 2023-03-26 10:17:03,710 [ INFO][log:170] Logging initialized @2335ms to org.eclipse.jetty.util.log.Slf4jLog
  48. 2023-03-26 10:17:03,968 [ INFO][Server:375] jetty-9.4.41.v20210516; built: 2021-05-16T23:56:28.993Z; git: 98607f93c7833e7dc59489b13f3cb0a114fb9f4c; jvm 17.0.4.1+1-LTS
  49. 2023-03-26 10:17:04,124 [ INFO][AnnotationConfiguration:473] Scanning elapsed time=0ms
  50. 2023-03-26 10:17:04,132 [ INFO][StandardDescriptorProcessor:277] NO JSP Support for /cas, did not find org.eclipse.jetty.jsp.JettyJspServlet
  51. 2023-03-26 10:17:04,163 [ INFO][session:334] DefaultSessionIdManager workerName=node0
  52. 2023-03-26 10:17:04,164 [ INFO][session:339] No SessionScavenger set, using defaults
  53. 2023-03-26 10:17:04,167 [ INFO][session:132] node0 Scavenging every 600000ms
  54. 2023-03-26 10:17:04,267 [ INFO][DruidWebStatServletStarter:74] druid stat view random user=druid password=39qaaf3d5kh5prg18p0drevu77
  55. 2023-03-26 10:17:04,297 [ INFO][NutFilter:85] NutFilter[nutz] starting ...
  56. 2023-03-26 10:17:04,301 [ INFO][ErrorResourceLocation:28] [loc=D:\work\Projects\java\gitee\nzb-cas\esdk-nzb-cas\static\WEB-INF\classes]not exist
  57. 2023-03-26 10:17:04,306 [ INFO][NutLoading:39] Nutz Version : 1.r.69.v20220215
  58. 2023-03-26 10:17:04,306 [ INFO][NutLoading:40] Nutz.Mvc[nutz] is initializing ...
  59. 2023-03-26 10:17:04,311 [ INFO][NutLoading:146] Build URL mapping by org.nutz.mvc.impl.UrlMappingImpl ...
  60. 2023-03-26 10:17:04,422 [ INFO][BrowserCacheFilter:24] com.baijian.framework.filter.BrowserCacheFilter@203c20cf has inited
  61. 2023-03-26 10:17:04,604 [ INFO][NutFilePool:28] Init file-pool by: D:/work/Projects/java/gitee/nzb-cas/esdk-nzb-cas/static/WEB-INF/tmp [2000]
  62. 2023-03-26 10:17:04,604 [ INFO][NutFilePool:50] file-pool.cursor: 0
  63. 2023-03-26 10:17:04,972 [ INFO][NutLoading:208] Found 97 module methods
  64. 2023-03-26 10:17:04,981 [ INFO][NutLoading:128] Nutz.Mvc[nutz] is up in 675ms
  65. 2023-03-26 10:17:04,982 [ INFO][NutFilter:117] exclusionsPrefix = ^(/druid/)
  66. 2023-03-26 10:17:05,002 [ INFO][ContextHandler:916] Started o.e.j.w.WebAppContext@8b91134{/cas,[file:///D:/work/Projects/java/gitee/nzb-cas/esdk-nzb-cas/static/],AVAILABLE}
  67. 2023-03-26 10:17:05,059 [ INFO][AbstractConnector:331] Started ServerConnector@2102a4d5{HTTP/1.1, (http/1.1)}{0.0.0.0:8081}
  68. 2023-03-26 10:17:05,059 [ INFO][Server:415] Started @3686ms
  69. 2023-03-26 10:17:05,068 [ INFO][Schedule:32] Schedules is starting...
  70. 2023-03-26 10:17:05,080 [ INFO][MainLauncher:64] mainLauncher init
  71. jdbc:mysql://db.server:3306/cas?useUnicode=true&characterEncoding=utf8&autoReconnect=true, driver:com.mysql.cj.jdbc.Driver, MinIdle:0, MaxActive:10, ActiveCount:0
  72. jedis host: redis.server , max connection: 100
  73. 2023-03-26 10:17:05,167 [ INFO][NbApp:219] NB started : 2039ms
  1. 完善的请求日志及SQL日志,通过请求ID追踪全过程,并写到第三方日志系统(如PlumeLog),达到快速定位、解决问题的效果。

  1. 2023-03-26 10:20:27,340 nzb-cas info 请求ID:1681795822570, 耗时:2ms, SQL:SELECT * FROM sys_file_upload WHERE file_id=425283962380894208;
  2. 2023-03-26 10:20:27,486 [ INFO][AccessLogHandler:23] 请求ID:1681795822570, 耗时:158ms, 用户:张三, 请求:/cas/pic/425283962380894208?accessToken=5d70bab7-ba9f-40f8-b5e1-84733d37a52f, 返回:java.io.FileInputStream@23ea81a7
  3. 2023-03-26 10:22:07,387 nzb-cas info 请求ID:1681893112718, 耗时:5ms, SQL:SELECT user_id,user_type,login_name,user_name,user_nick,sex,mobile,email,remark,avatar_url,tenant_id,login_tenant_id,tenant_ids,tenant_names,org_ids,org_names,role_ids,role_names,rank,is_enabled,valid,create_time,create_user_id,create_user_name,update_time,update_user_id,update_user_name,version,tenant_name,login_tenant_code,login_tenant_name FROM sys_user_view WHERE valid=1 AND user_nick LIKE '小%' AND tenant_id=108 AND user_type='sys' ORDER BY user_id desc LIMIT 10 OFFSET 0;
  4. 2023-03-26 10:22:07,390 [ INFO][AccessLogHandler:23] 请求ID:1681893112718, 耗时:14ms, 用户:张三, 请求:/cas/system/user/list.do?roleIds=&orgIds=&userNick=小*&pageSize=10&userType=sys&page=1&tenantIds=, 返回:{"totalCount":1,"page":1,"pageCount":1,"pageSize":10,"start":0,"rows":[{"userId":"42634...
  1. 通过数据库反向生成易于业务扩展的前后端代码,实现真正的低代码。

  1. public static void main(String[] args) throws Exception{
  2. Stopwatch sw=new Stopwatch();
  3. //通过数据库生成数据表ORM对象
  4. genOrmFiles(esdk.str.splits("sys_role,sys_user,sys_org"));
  5. //通过ORM对象生成前后端代码,包括增删改查、导入、导出。
  6. genModules(true,true,true,"sys_user","sys_org");
  7. sw.stop();
  8. }
  1. /**
  2. * @业务描述 组织机构
  3. * @author 请填写姓名或邮箱
  4. * @since 2023-02-20 10:18:13
  5. */
  6. @IocBean(singleton=false) //注意:Module不能是单例例式,有Field
  7. @At("/system/org")
  8. @Ok("raw")
  9. @Fail("http:500")
  10. public class SysOrgModule extends ProjectModule<SysOrgRow,SysOrgViewRow>{
  11. private static Log log=esdk.log();
  12. @Override protected Class getModelClass(){return SysOrgRow.class;}
  13. /**通用查询接口,已实现指定字段的模糊查询、时间或数值类型的范围查询,并优先使用数据库视图输出字段,已实现分页或导出excel功能*/
  14. @At @GET
  15. public Object list(SysOrgViewRow model,Search search) throws Exception{
  16. setListLikeFields();
  17. Object pageOrRs=super.list(model,search);
  18. return pageOrRs;
  19. }
  20. /**调用list()时,继承toPage方法可以对Select/ABRowSet对象进行业务处理,不需要改动的话可以删除*/
  21. @Override
  22. protected Page toPage(IPageSelect pageSelect,Search search) throws Exception{
  23. SysOrgViewSelect select=(SysOrgViewSelect)pageSelect;
  24. return toPage(select.toRowSet(),search);
  25. }
  26. /**通用单条记录获取接口,优先使用数据库视图的字段输出*/
  27. @At @GET
  28. public SysOrgViewRow query(Long orgId) throws SQLException{
  29. return super.query(orgId);
  30. }
  31. /**新增单条记录,父类已实用通用新增方法*/
  32. @At @POST
  33. public Response insert(SysOrgRow model) throws Exception{
  34. return super.insert(model);
  35. }
  36. /**修改单条记录,父类已实用通用修改方法*/
  37. @At @POST
  38. public Response update(SysOrgRow model) throws Exception {
  39. return super.update(model);
  40. }
  41. /**调用insert、update、save方法时提交前的处理*/
  42. @Override
  43. protected Response beforeFlush(SysOrgRow db) throws Exception{
  44. return super.beforeFlush(db);
  45. }
  46. /**调用insert、update、save方法时提交后的处理*/
  47. @Override
  48. protected Response afterFlush(SysOrgRow db) throws Exception{
  49. return super.afterFlush(db);
  50. }
  51. /**通用保存接口,通过主键判断新增或修改*/
  52. @At @POST
  53. public Response save(SysOrgRow model) throws Exception {
  54. return super.save(model);
  55. }
  56. /**删除多条记录,父类已实用通用删除方法*/
  57. @At @POST
  58. public Response delete(Long[] ids) throws Exception{
  59. // DF.orgDao().delete(DF.orgSelect().setPrimaryKey(ids).toRowSet());
  60. return super.delete(ids);
  61. }
  62. /**查询下拉框,父类已实用通用查询方法*/
  63. @At @GET
  64. public ABRowSet dropdown(SysOrgRow model,Search search) throws SQLException{
  65. return super.dropdown(model,search);
  66. }
  67. /**导出excel文件*/
  68. @At @GET @Ok("void")
  69. public void export(SysOrgViewRow model,Search search) throws Exception{
  70. super.export(model,search);
  71. }
  72. /**excel文件批量导入*/
  73. @At("/import") @POST
  74. @AdaptBy(type=UploadAdaptor.class, args={"${app.root}/WEB-INF/tmp"})
  75. public Response uploadExcel(@Param("file") TempFile file,ServletContext sc) throws Exception{
  76. ri=new SysOrgUploadService().importExcel(file,true,true);
  77. return ri;
  78. }
  79. }
  1. 项目打包部署

  1. #部署增量包
  2. gradle deployJar
  3. #部署全量包
  4. gradle deployJarWithLib
  5. #前端编译打包,放到jetty的静态目录static下
  6. gradle npmRunBuild
  1. esdk-nzb-cas共享项目地址:https://gitee.com/ffychina/nzb-cas

  1. esdk快速开发工具项目地址:https://gitee.com/ffychina/esdk

今天就说这么多了,后面逐步完善,欢迎指点交流。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/715359
推荐阅读
相关标签
  

闽ICP备14008679号