中文 | English
一个轻量级持久化框架,把代码与sql进行解耦,如果您厌倦了复杂的的DSL,Sql4j也许是您另外一个选择.
目前主流的持久层框架Mybatis Jooq 等都是结合一些DSL在使用,在不运行程序的情况下,单独运行sql来测试变得很困难,当然也有插件可以输出sql,但如果需要在服务器上运行就比较困难了。
<dependency>
<groupId>io.github.youkale</groupId>
<artifactId>sql4j</artifactId>
<version>0.2.0</version>
</dependency>-- :name com.github.youkale.sql4j.OrderMapper#getOrderIds :? :*
select id
from `order`
where id in (:v * :ids)
-- :name queryOrderIds :? :*
select id
from `order`
where id in (:v * :ids)public interface OrderMapper {
List<Integer> getOrderIds(@Param("ids") List<Integer> ids);
@Alias("queryOrderIds")
Integer[] getOrderIdsByVec(@Param("ids") List<Integer> ids);
@Alias("queryOrderIds")
int[] getOrderIdsByVecPrim(@Param("ids") List<Integer> ids);
}import java.util.List;
public class Main {
public static void main(String[] args) {
Sql4J sql4J = new Sql4J(dataSource, Dialect.mysql, "sql", true);
OrderMapper mapper = sql4J.lookup(OrderMapper.class);
List<Integer> ids = mapper.getOrderIds(List.of(1, 2, 3));
}
}HugSql Usage
:name表示映射的mapper名称:command执行的命令, 分为:execute和:query, 表示执行和查询,可以跟:name写一行:result结果类型, 可以跟:name写一行:raw对应的:command可以为:execute和:query:many、:one对应的:command为:query:affected对应的:command为:execute
:doc表示文档
command:execute->:!:query->:?
:result:many->:*:one->:1:affected->:n
- 多行
-- :name create-characters-table -- :command :execute -- :result :raw -- :doc Create characters table -- auto_increment and current_timestamp are -- H2 Database specific (adjust to your DB)
- 单行(查询多行)
-- :name queryOrders :? :* - 单行(查询单行)
-- :name queryOrders :? :!
-
:value或:v值类型参数, 这里的:id为{"id": 123}文档--:name value-param :? :* select * from characters where id = :id --:name value-param-with-param-type :? :* select * from characters where id = :v:id
-
:value*或:v*值列表参数, 这里的names为List<String>文档--:name value-list-param :? :* select * from characters where name in (:v*:names)
-
:tuple或:t元组参数, 这里id-name为[1 ,"youkale"]-- :name tuple-param -- :doc Tuple Param select * from test where (id, name) = :tuple:id-name
-
:tuple*或:t*元组列表参数, 这里的people为{"people": [[1, "Ed"], [2 "Al"], [3 "Bo"]]}文档-- :name tuple-param-list -- :doc Tuple Param List insert into test (id, name) values :t*:people
-
:identifier或i, 引述参数,在运行时被替换成引述字段,比如mysql会替换成`table` 文档--:name identifier-param :? :* select * from :i:table-name
-
:identifier*或i*引述列表参数,在运行时被替换成引述字段,比如mysql会替换成`columns` 文档--:name identifier-list-param :? :* select :i*:column-names, count(*) as population from example group by :i*:column-names order by :i*:column-names
- mapper
- 通过使用
java的动态代理,将定义的Mapper与hugsql的db-fn*进行绑定,默认使用Mapper的类名+方法的全限定名称,如果有指定Alias那么将使用其定义的名称。 - 返回的范型类型如果不是
ParameterizedType是不支持返回范型的,比如interface Foo<T> { T foo(); } class Bar { void call(){ Foo f = sql4j.lookup(Foo.class); } }
- 通过使用
- 入参处理(以下说明是针对在sql中取值)
- Map类型可以根据key进行访问,java bean会根据property名称进行访问
orderNo - 基本类型和List、Set类型,需要配合
@Param注解进行命名,方可在sql文件中访问.
- Map类型可以根据key进行访问,java bean会根据property名称进行访问
- 返回处理
- Map直接返回
- List、Order[]、Order等类型,会获取对bean的PropertyDescriptor的writeMethod进行写入。如遇到数据库
column与property不一致的情况,需要通过@Results注解进行配置映射关系。@Result是对应的每一个映射关系. 包含column与property
- JDK11
- Maven
某些IDE可能会出现clojure代码没有编译的情况,建议调试或者运行的时候先执行如下命令
mvn -P dev compile -DskipTests=true