热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringBoot整合Hasor实践入坑指南

一、前言某日赵某下班乘坐地铁刷某乎时发现一篇文章,差不多标题的意思是再也不用再项目中写Controller、Service以及Dao了,这题目很是吸引

一、前言

某日赵某下班乘坐地铁刷某乎时发现一篇文章,差不多标题的意思是再也不用再项目中写Controller、Service以及Dao了,这题目很是吸引人啊,一般这样的文章下面都会有人在那讨论。正好闲来无事,我也看了看官方文档,结合当前工作的实际需要写了一个小项目。

二、了解一下Hasor:

先给出大家官方网站地址,毕竟官方的才是最权威的。
Hasor官方文档
Hasor有着自己的独立的生命周期与Spring的不同,是一套完整的体系,最低环境要求是JDK1.8,所以说这个东西很新,提供了注入DataQL、Dataway、hasor-web等等,让你的代码无需在写Controller、Service、Dao、BO、VO、mapper等等东西,这是一个数据聚合项目,有优点也有不足,主要看具体的需求环境是否合适,合适的才是最好的!
我为什么要用Hasor写一个的demo呢?我的需求场景:工作有一套系统对接了一个项目A,项目A会将数据推送到我们这里,我们对数据进行校验并保存请求记录,如果通过了我们的校验,我们在将数据封装推送给另一个项目C。我们的角色有点网关的意思哈,当然这个数据传输过程中的数据交换格式,以及数据内容什么的会发生一些变化。这个时候项目A的开发人员经常会询问我是否已经将数据推送给项目C,每次都需要我打开数据库,写上两行SQL去查询我们数据库中关于这条数据的状态是否已经成功推送到项目C;这是一种及其无聊且没有难度的重复性活动,我怎么会一直手动去数据库中一直给他查数据状态。这个时候的我就看上了Hasor中不用写Controller、service、dao以及各种model、mapper,我想要的只不过是将我在数据库查询到的结果反馈给项目A的开发人员即可。

三、创建一个SpringBoot项目,添加Hasor依赖

创建一个简单的SpringBoot项目,然后在Maven中添加hasor-spring连通Hasor和Spring,使得能够在SpringBoot中使用hasor,添加hasor-dataway让我们能够不用写Controller这些东西而通过页面配置接口的方式将数据和接口设计出来;一个Jdbc连接,用于连接Mysql数据库,注意使用Hasor-dataway必须使用数据库,配置也必须在数据库中配置两个表。

项目的Maven依赖如下:(以下依赖最好使用Hasor的最新版本,现在迭代速度还是很快的,旧版本可能会存在一些问题)

<properties><java.version>1.8</java.version></properties><dependencies><!--Spring-web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--连通 Spring 和 Hasor--><dependency><groupId>net.hasor</groupId><artifactId>hasor-spring</artifactId><version>4.1.7</version></dependency><!--DataWay 是Hasor生态中的一员--><dependency><groupId>net.hasor</groupId><artifactId>hasor-dataway</artifactId><version>4.1.7</version><!-- 4.1.4 包存在UI资源缺失问题 --></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--JDBC--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency></dependencies>

打开数据库&#xff0c;创建两个新的表&#xff0c;用于维护dataway的API,建表建议参考官方网站的&#xff0c;因为不同版本的Hasor依赖的表的字段可能是不同的。
建表语句如下&#xff08;如果出现表问题&#xff0c;可以参照官方网站修改&#xff09;

CREATE TABLE &#96;interface_info&#96; (&#96;api_id&#96; int(11) NOT NULL AUTO_INCREMENT COMMENT &#39;ID&#39;,&#96;api_method&#96; varchar(12) NOT NULL COMMENT &#39;HttpMethod&#xff1a;GET、PUT、POST&#39;,&#96;api_path&#96; varchar(512) NOT NULL COMMENT &#39;拦截路径&#39;,&#96;api_status&#96; int(2) NOT NULL COMMENT &#39;状态&#xff1a;0草稿&#xff0c;1发布&#xff0c;2有变更&#xff0c;3禁用&#39;,&#96;api_comment&#96; varchar(255) DEFAULT NULL COMMENT &#39;注释&#39;,&#96;api_type&#96; varchar(24) NOT NULL COMMENT &#39;脚本类型&#xff1a;SQL、DataQL&#39;,&#96;api_script&#96; mediumtext NOT NULL COMMENT &#39;查询脚本&#xff1a;xxxxxxx&#39;,&#96;api_schema&#96; mediumtext COMMENT &#39;接口的请求/响应数据结构&#39;,&#96;api_sample&#96; mediumtext COMMENT &#39;请求/响应/请求头样本数据&#39;,&#96;api_option&#96; mediumtext COMMENT &#39;扩展配置信息&#39;,&#96;api_create_time&#96; datetime DEFAULT CURRENT_TIMESTAMP COMMENT &#39;创建时间&#39;,&#96;api_gmt_time&#96; datetime DEFAULT CURRENT_TIMESTAMP COMMENT &#39;修改时间&#39;,PRIMARY KEY (&#96;api_id&#96;)
) ENGINE&#61;InnoDB AUTO_INCREMENT&#61;7 DEFAULT CHARSET&#61;utf8mb4 COMMENT&#61;&#39;Dataway 中的API&#39;;

CREATE TABLE &#96;interface_release&#96; (&#96;pub_id&#96; int(11) NOT NULL AUTO_INCREMENT COMMENT &#39;Publish ID&#39;,&#96;pub_api_id&#96; int(11) NOT NULL COMMENT &#39;所属API ID&#39;,&#96;pub_method&#96; varchar(12) NOT NULL COMMENT &#39;HttpMethod&#xff1a;GET、PUT、POST&#39;,&#96;pub_path&#96; varchar(512) NOT NULL COMMENT &#39;拦截路径&#39;,&#96;pub_status&#96; int(2) NOT NULL COMMENT &#39;状态&#xff1a;0有效&#xff0c;1无效&#xff08;可能被下线&#xff09;&#39;,&#96;pub_type&#96; varchar(24) NOT NULL COMMENT &#39;脚本类型&#xff1a;SQL、DataQL&#39;,&#96;pub_script&#96; mediumtext NOT NULL COMMENT &#39;查询脚本&#xff1a;xxxxxxx&#39;,&#96;pub_script_ori&#96; mediumtext NOT NULL COMMENT &#39;原始查询脚本&#xff0c;仅当类型为SQL时不同&#39;,&#96;pub_schema&#96; mediumtext COMMENT &#39;接口的请求/响应数据结构&#39;,&#96;pub_sample&#96; mediumtext COMMENT &#39;请求/响应/请求头样本数据&#39;,&#96;pub_option&#96; mediumtext COMMENT &#39;扩展配置信息&#39;,&#96;pub_release_time&#96; datetime DEFAULT CURRENT_TIMESTAMP COMMENT &#39;发布时间&#xff08;下线不更新&#xff09;&#39;,PRIMARY KEY (&#96;pub_id&#96;),KEY &#96;idx_interface_release&#96; (&#96;pub_api_id&#96;)
) ENGINE&#61;InnoDB AUTO_INCREMENT&#61;9 DEFAULT CHARSET&#61;utf8mb4 COMMENT&#61;&#39;Dataway API 发布历史。&#39;;

四、整合SpringBoot和Hasor

SpringBoot整合Hasor中的dataway主要是将数据也配置到Hasor中&#xff0c;同时在启动入口开启Hasor和Hasor-web。整合起来也是十分的简单。

import net.hasor.core.ApiBinder;
import net.hasor.core.DimModule;
import net.hasor.db.JdbcModule;
import net.hasor.db.Level;
import net.hasor.spring.SpringModule;
import org.springframework.stereotype.Component;import javax.sql.DataSource;&#64;DimModule // Hasor 中的标签&#xff0c;表明是一个Hasor的model
&#64;Component // Spring 中的标签&#xff0c;表明是一个组件
public class HasorComponent implements SpringModule {private final DataSource dataSource;public HasorComponent(DataSource dataSource){this.dataSource &#61; dataSource;}/*** Hasor 启动的时候会调用 loadModule 方法&#xff0c;* 在这里再把 DataSource 设置到 Hasor 中。* &#64;param apiBinder* &#64;throws Throwable*/&#64;Overridepublic void loadModule(ApiBinder apiBinder) throws Throwable {apiBinder.installModule(new JdbcModule(Level.Full, this.dataSource));}}

启动类代码如下&#xff1a;

import net.hasor.spring.boot.EnableHasor;
import net.hasor.spring.boot.EnableHasorWeb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** 启用Hasor*/
&#64;EnableHasor
&#64;EnableHasorWeb // 将 hasor-web 配置到 Spring 环境中&#xff0c;Dataway 的 UI 是通过 hasor-web 提供服务。
&#64;SpringBootApplication
public class QueryApplication {public static void main(String[] args) {SpringApplication.run(QueryApplication.class, args);}
}

application.yml文件&#xff08;主要是开启和配置Dataway&#xff09;配置如下&#xff1a;

server:port: 9800spring:profiles:active: dev
# 是否启用 Dataway 功能&#xff08;必选&#xff1a;默认false&#xff09;
HASOR_DATAQL_DATAWAY: true# 是否开启 Dataway 后台管理界面&#xff08;必选&#xff1a;默认false&#xff09;
HASOR_DATAQL_DATAWAY_ADMIN: true# dataway API工作路径&#xff08;可选&#xff0c;默认&#xff1a;/api/&#xff09;
HASOR_DATAQL_DATAWAY_API_URL: /interface/# dataway-ui 的工作路径&#xff08;可选&#xff0c;默认&#xff1a;/interface-ui/&#xff09;
HASOR_DATAQL_DATAWAY_UI_URL: /config/# SQL执行器方言设置&#xff08;可选&#xff0c;建议设置&#xff09;
HASOR_DATAQL_FX_PAGE_DIALECT: mysql

application-dev.yml配置文件如下(主要是配置数据源)&#xff1a;

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding&#61;UTF-8&serverTimezone&#61;UTC&useSSL&#61;false&allowPublicKeyRetrieval&#61;trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver

项目的代码编程语配置就好了&#xff0c;下面就可以启动程序了&#xff0c;因为我们后面想从数据库中拿取数据&#xff0c;就可以在页面中编辑就行了。
四、配置数据接口
在程序正常启动以后&#xff0c;在浏览器中打开DatawayAPI的配置页面&#xff0c;因为我在application.yml文件修改了默认UI页面地址&#xff0c;自己和自己的对应上就好了&#xff0c;地址&#xff1a;http://127.0.0.1:9800/config/
这里注意一下地址后面的/也要有,第一次打开会慢一点。打开后DatawayAPI配置页面如下图&#xff1a;
在这里插入图片描述
为了演示效果&#xff0c;我新建一个了animal表作为演示用&#xff0c;里面的inputtime和updatetime主要用于演示DataQL&#xff0c;建表语句如下&#xff1a;

CREATE TABLE &#96;animal&#96; (&#96;id&#96; bigint(20) NOT NULL AUTO_INCREMENT COMMENT &#39;自增主键&#39;,&#96;name&#96; varchar(20) NOT NULL COMMENT &#39;动物名称&#39;,&#96;alias&#96; varchar(40) NOT NULL COMMENT &#39;动物别名&#39;,&#96;description&#96; varchar(300) DEFAULT &#39;&#39; COMMENT &#39;动物描述&#39;,&#96;inputtime&#96; timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT &#39;动物信息入机时间&#39;,&#96;updatetime&#96; timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT &#39;动物信息更新时间&#39;,PRIMARY KEY (&#96;id&#96;)
) ENGINE&#61;InnoDB DEFAULT CHARSET&#61;utf8mb4;

插入几条测试数据&#xff1a;

INSERT INTO animal (name,alias,description) VALUES (&#39;西伯利亚猩猩&#39;,&#39;黑猩猩&#39;,&#39;西伯利亚&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;东北虎&#39;,&#39;大脑虎&#39;,&#39;东北地区&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;孔雀&#39;,&#39;白孔雀&#39;,&#39;北京动物园&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;狮子&#39;,&#39;辛巴&#39;,&#39;影视&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;边境牧羊犬&#39;,&#39;边牧&#39;,&#39;家中&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;西伯利亚雪橇犬&#39;,&#39;二哈&#39;,&#39;富足家庭中&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;蓝猫&#39;,&#39;猫&#39;,&#39;家养&#39;);INSERT INTO animal (name,alias,description) VALUES (&#39;大熊猫&#39;,&#39;国宝&#39;,&#39;北京动物园&#39;);

测试数据如下&#xff1a;
在这里插入图片描述

五、新建一个Dataway接口

首先介绍一些Dataway的基本知识&#xff0c;Dataway可以通过UI页面定义数据接口&#xff0c;然后通过自测和冒烟以后才能发布这个接口&#xff0c;当接口发布成功以后&#xff0c;就可以通过我们定义的接口路径来访问获取数据了&#xff0c;这些接口数据都是保存在我们上面创建的interface_info表中的&#xff0c;当然接口发布以后也可以修改&#xff0c;也即接口可以有历史版本&#xff0c;这些信息保存在interface_release 表中&#xff0c;这也就是为什么我们什么要在上面定义这两个表&#xff1b;&#xff08;Ps:当然Dataway也可以通过编写代码来实现&#xff09;在Dataway的数据访问中使用的是一种名字叫做DataQL的脚本语言&#xff0c;类似Javascript 先来一段官网的说明定义:
DataQL&#xff08;Data Query Language&#xff09;DataQL 是一种查询语言。旨在通过提供直观、灵活的语法来描述客户端应用程序的数据需求和交互。

数据的存储根据其业务形式通常是较为简单的&#xff0c;并不适合直接在页面上进行展示。因此开发页面的前端工程师需要为此做大量的工作&#xff0c;这就是 DataQL 极力解决的问题。另外还支持使用SQL来&#xff0c;但是SQL在Dataway中最终也都是转换成DataQL。
在这里插入图片描述
Dataway页面说明&#xff1a;
1、功能按钮&#xff1a;可以查看所有已经发布的接口
2、功能按钮&#xff1a;可以创建新的接口
3、链接&#xff1a;打开DataQL接口说明
4、请求方式&#xff1a;Http请求方式定义&#xff0c;默认是POST方法
5、接口路径&#xff1a;定义接口的请求路径&#xff0c;/interface/为配置文件中HASOR_DATAQL_DATAWAY_API_URL属性事先定义的值&#xff0c;后面补充路径&#xff0c;当接口路径发布后&#xff0c;后面定义的接口请求路径不能重名
6、接口说明&#xff1a;可以为接口添加中文说明
7、使用DataQL编写接口&#xff0c;默认选择为DataQL
8、使用SQl编写接口
9、接口编写代码部分
10、功能按钮&#xff1a;保存9部分编写的代码&#xff0c;注意只有先保存才能进行冒烟测试
11、功能按钮&#xff1a;测试按钮&#xff0c;当编写接口代码时&#xff0c;使用此按钮进行接口测试
12、功能按钮&#xff1a;冒烟测试按钮&#xff0c;通过了冒烟测试以后才能发布
13、功能按钮&#xff1a;发布接口&#xff0c;发布接口以后以后就可以通过发布的接口获取数据
14、功能按钮&#xff1a;接口编辑历史记录&#xff0c;可以通过历史记录回滚9区域的代码
15、功能按钮&#xff1a;删除按钮&#xff0c;点击删除后删除已经发布的接口&#xff08;数据库中也会清除这条记录&#xff09;
16、18功能区域&#xff1a;这个区域可以设置接口的请求参数例如通过POST方法传输一个请求报文&#xff0c;在此区域定义
17、功能按钮&#xff1a;设置接口的请求头参数
19、功能区域&#xff1a;测试接口区域&#xff0c;点击11测试按钮或者12冒烟以后在此区域显示测试结果
1&#xff09;在介绍完了页面的基本功能以后&#xff0c;新建一个请求接口。
在页面中点击【new】新建一个数据接口&#xff0c;请求方式设置为【GET】方法&#xff0c;路径为【querytest】&#xff0c;接口说明为【请求接口GET方法测试】&#xff0c;选择使用【DataQL】开发&#xff08;功能会更强大一点&#xff09;&#xff0c;编写代码部分的主要功能为查询数据中动物表&#xff08;animal&#xff09;中的&#xff08;name&#xff09;字段中包含犬的数据&#xff0c;接口参数设置为【name】传输要查询包含某个字的动物数据代码如下&#xff1a;

// 查询动物表中名字中包含犬的数据// 定义一个函数&#xff0c;将函数的查询结果存贮在querydog中
// &#64;&#64;sql()为插入外部SQL代码&#xff0c;<% %>为SQl代码区域
// name为函数的参数&#xff0c;如果想要在SQL使用这个参数&#xff0c;需要使用#{name}来使用
// #,$,&#64;都为特殊符号&#xff0c;一般情况下用法一致&#xff0c;更多用法可参考官方说明
var querydog &#61; &#64;&#64;sql(name)<%select * from animal where name like #{name}
%>// 返回上述SQL查询到的数据
// 通过$获取Parameters中的传过来的name 参数值return querydog(${name});

在这里插入图片描述
我们在接口返回中可以看见我们创建的animal表中的动物信息入机时间和更新时间都是时间戳&#xff0c;我们通过DataQL查询出来的也为时间戳&#xff0c;这个时候我们就可以借助DataQL的函数对数据进行一个转换
,与此同时&#xff0c;我们还可以借助lambda解析数据&#xff0c;将代码改为如下&#xff1a;

// 查询动物表中名字中包含犬的数据// 定义一个函数&#xff0c;将函数的查询结果存贮在querydog中
// &#64;&#64;sql()为插入外部SQL代码&#xff0c;<% %>为SQl代码区域
// name为函数的参数&#xff0c;如果想要在SQL使用这个参数&#xff0c;需要使用#{name}来使用
// #,$,&#64;都为特殊符号&#xff0c;一般情况下用法一致&#xff0c;更多用法可参考官方说明
var querydog &#61; &#64;&#64;sql(name)<%select * from animal where name like %#{name}%
%>// 返回上述SQL查询到的数据
// 通过$获取Parameters中的传过来的name 参数值
// 修改返回报文中的将id换成编号&#xff0c;name 换成动物名称 诸如此类......
// 查询到的数据包含多个对象&#xff0c;注意格式 [{}]&#xff0c;不然只显示一个
return querydog(${name})&#61;>[{"编号":id,"动物名称":name,"动物别名":alias,"动物描述":description,"动物信息入机时间":inputtime,"动物信息更新时间":updatetime
}]

运行效果如下图&#xff1a;
在这里插入图片描述
添加DataQL中的FunctionX函数将时间戳改为我们指定格式时间格式&#xff0c;首先需要引入日期这个函数&#xff0c;as的作用相当于起一个别名来使用这个函数&#xff1a;

import &#39;net.hasor.dataql.fx.basic.DateTimeUdfSource&#39; as time;

在返回数据调用format方式格式化时间如下&#xff1a;

// 定义一个处理updatetime日期格式的函数
var formatupdatetime &#61; (updatetime)->{return time.format(updatetime, "yyyy-MM-dd HH:mm:ss")
}// 返回上述SQL查询到的数据
// 通过$获取Parameters中的传过来的name 参数值
// 修改返回报文中的将id换成编号&#xff0c;name 换成动物名称 诸如此类......
// 查询到的数据包含多个对象&#xff0c;注意格式 [{}]&#xff0c;不然只显示一个
// 调用日期函数&#xff0c;将Long类型的时间戳输出为格式化的时间
// dang然也可以定义一个函数来进行处理&#xff0c;如上的formatupdatetime函数
return querydog(${name})&#61;>[{"编号":id,"动物名称":name,"动物别名":alias,"动物描述":description,"动物信息入机时间":time.format(inputtime, "yyyy-MM-dd HH:mm:ss"),"动物信息更新时间": formatupdatetime(updatetime)
}]

最后的整体代码如下&#xff1a;

import &#39;net.hasor.dataql.fx.basic.DateTimeUdfSource&#39; as time;
// 查询动物表中名字中包含犬的数据// 定义一个函数&#xff0c;将函数的查询结果存贮在querydog中
// &#64;&#64;sql()为插入外部SQL代码&#xff0c;<% %>为SQl代码区域
// name为函数的参数&#xff0c;如果想要在SQL使用这个参数&#xff0c;需要使用#{name}来使用
// #,$,&#64;都为特殊符号&#xff0c;一般情况下用法一致&#xff0c;更多用法可参考官方说明
var querydog &#61; &#64;&#64;sql(name)<%select * from animal where name like #{name}
%>// 定义一个处理updatetime日期格式的函数
var formatupdatetime &#61; (updatetime)->{return time.format(updatetime, "yyyy-MM-dd HH:mm:ss")
}// 返回上述SQL查询到的数据
// 通过$获取Parameters中的传过来的name 参数值
// 修改返回报文中的将id换成编号&#xff0c;name 换成动物名称 诸如此类......
// 查询到的数据包含多个对象&#xff0c;注意格式 [{}]&#xff0c;不然只显示一个
// 调用日期函数&#xff0c;将Long类型的时间戳输出为格式化的时间
// dang然也可以定义一个函数来进行处理&#xff0c;如上的formatupdatetime函数
return querydog(${name})&#61;>[{"编号":id,"动物名称":name,"动物别名":alias,"动物描述":description,"动物信息入机时间":time.format(inputtime, "yyyy-MM-dd HH:mm:ss"),"动物信息更新时间": formatupdatetime(updatetime)
}]

在这里插入图片描述
至此我们通过GET方法查询动物表中动物名称包含有犬的功能接口就开发完了&#xff0c;点击保存按钮进行保存&#xff0c;点击冒烟测试按钮进行测试&#xff0c;点击发布按钮进行发布。发布成功以后&#xff0c;我们就可以通过定义的API直接获取数据了&#xff0c;而不需要进行Controller、service、dao、Mapper等的书写&#xff1b;
在这里插入图片描述
然后我们在浏览器中直接输入已经发布的API &#xff0c;测试能否获取我们预想的数据&#xff1b;
注意这里我们设置成GET请求方式&#xff0c;需要的入参为name的值&#xff0c;请求路径应如&#xff1a;http://127.0.0.1:9800/interface/querytest?name&#61;%犬%
这与POST请求方式不同&#xff1b;&#xff08;这里的接口设计是有一定问题的&#xff0c;我们为了模糊查询在参数中传入了%&#xff0c;中文转码以后会有冲突&#xff0c;可以换成数据库name为边境牧羊犬进行查询或者使用Postman传参&#xff09;
在这里插入图片描述
使用Postman的测试结果如下&#xff1a;
在这里插入图片描述

六、新建一个POST 接口与GET接口进行比较

之所以要进行POST接口与GET接口的请求比较主要是因为POST的入参方式和GET方式的不同&#xff0c;究其根本其实也就是POST与GET方法的区别&#xff1b;我们还是复用上面的那个已经写好了的接口&#xff0c;但是定义成POST请求方式&#xff1b;
在这里插入图片描述
这里就没有办法通过浏览器来测试接口的返回数据了&#xff0c;因为浏览器默认使用的是GET方法&#xff0c;这里我们使用Postman进行测试&#xff1b;
在这里插入图片描述
这就是GET方法的API和POST方法API的区别&#xff0c;当然更多玩法可以参看官方文档&#xff1a;Hasor官方文档

七、总结

总结一下&#xff0c;个人觉得Hasor还是有很多优点的&#xff0c;例如可以和方便的与SpringBoot结合&#xff0c;可以不用写Controller、service、dao、mapper这一套东西&#xff0c;可以动态修改配置API等等&#xff1b;但是缺点也是有的&#xff0c;个人觉得这东西还很年轻&#xff0c;有一定的学习成本&#xff08;例如要学习DataQL&#xff09;等等这些。我之所以写这篇博客是因为现在的Hasor更好符合我的需求。
有兴趣的小伙伴可以关注微信公众号【为码以梦】&#xff0c;更方便看文

在这里插入图片描述


推荐阅读
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
author-avatar
mobiledu2502929627
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有