13. Beetl 入门

Beetl 语法类似js,java,如下做简要说明,使用可以参考 http://ibeetl.com , 或者在线体验 http://ibeetl.com/beetlonline/

13.1. 定界符号

默认的定界符号是@ 和 回车。 里面可以放控制语句,表达式等语,,占位符号是##,占位符号默认是输出?,并在执行sql的传入对应的值。如果想在占位符号输出变量值,则需要使用text函数

  1. @if(!isEmpty(name)){
  2. and name = #name#
  3. }

如果想修改定界符,可以增加一个/btsql-ext.properties. 设置如下属性

  1. DELIMITER_PLACEHOLDER_START=#
  2. DELIMITER_PLACEHOLDER_END=#
  3. DELIMITER_STATEMENT_START=@
  4. DELIMITER_STATEMENT_END=

beetlsql 的其他属性也可以在此文件里设置

13.2. 变量

通过程序传入的变量叫全局变量,可以在sql模板里使用,也可以定义变量,如

  1. @var count = 3;
  2. @var status = {"a":1} //json变量

13.3. 算数表达式

同js,如a+1-b%30, i++ 等

  1. select * from user where name like #'%'+name+'%'#

13.4. 逻辑表达式

有“&&” “||” ,还有 “!”,分别表示与,或,非, beetl也支持三元表达式

  1. #user.gender==1?'女':'男'#

13.5. 控制语句

  • if else 这个同java,c,js。
  • for,循环语句,如for(id:ids){}
  1. select * from user where status in (
  2. @for(id in ids){
  3. #id# #text(idLP.last?"":"," )#
  4. @}

注意

  • 变量名+LP 是一个内置变量,包含了循环状态,具体请参考beetl文档,text方法表示直接输出文本而不是符号“?”
  • 关于 sql中的in,可以使用内置的join方法更加方便
  • while 循环语句 ,如while(i<count))

13.6. 访问变量属性

  • 如果是对象,直接访问属性名,user.name
  • 如果是Map,用key访问 map["key"];
  • 如果是数组或者list,用索引访问,如list[1],list[i];
  • 可以直采用java方式访问变量的方法和属性,如静态类Constatns
  1. public class Constatns{
  2. public static int RUNNING = 0;
  3. public static User getUser(){}
  4. }

直接以java方式访问,需要再变量符号前加上@,可以在模板里访问

  1. select * from user where status = #@Constatns.RUNNING# and id = #@Constatns.getUser().getId()#

注意,如果Constants 类 没有导入进beetl,则需要带包名,导入beetl方法是配置IMPORT_PACKAGE=包名.;包名.

13.7. 判断对象非空

可以采用isEmpty判断变量表达式是否为空(为null),是否存在,如果是字符串,是否是空字符串,如

  1. if(isEmpty(user)||isEmpty(role.name))

也可以用传统方法判断,如

  1. if(user==null) or if(role.name!=null))

变量有可能不存在,可用hasH函数或者需要使用安全输出符号,如

  1. if(null==user.name!))
  2. //or
  3. if(has(user))

变量表达式后面跟上"!" 表示如果变量不存在,则为!后面的值,如果!后面没有值,则为null

13.8. 调用方法

同js,唯一值得注意的是,在占位符里调用text方法,会直接输出变量而不是“?”,其他以db开头的方式也是这样。架构师可以设置SQLPlaceholderST.textFunList.add(xxxx) 来决定那些方法在占位符号里可以直接输出文本而不是符号"?"

beetl提供了很多内置方法,如print,debug,isEmpty,date等,具体请参考文档

13.9. 自定义方法

通过配置btsql-ext.properties, 可以注册自己定义的方法在beetlsql里使用,如注册一个返回当前年份的函数,可以在btsql-ext.properties加如下代码

  1. FN.db.year= com.xxx.YearFunction

这样在模板里,可以调用db.year() 获得当前年份。YearFunction 需要实现Function的 call方法,如下是个简单代码

  1. public class YearFunction implements Function{
  2. public String call(Object[] paras, Context ctx){
  3. return "2015";
  4. }
  5. }

关于如何完成自定义方法,请参考 ibeetl 官方文档

13.10. 内置方法

  • print println 输出,同js,如print("table1");
  • has, 判断是否有此全局变量;
  • isEmpty 判断表达式是否为空,不存在,空字符串,空集合都返回true;
  • debug 将变量输出到控制台,如 debug(user);
  • text 输出,但可用于占位符号里
  • page 函数,用于在PageQuery翻页里,根据上下问决定输出count(1) 或者count(*),如果有参数,则按照参数输出
  • join, 用逗号连接集合或者数组,并输出?,用于in,如
  1. select * from user where status in ( #join(ids)#)
  2. -- 输出成 select * from user where status in (?,?,?)
  • use 参数是同一个md文件的sqlid,类似mybatis的 sql功能,如
  1. condtion
  2. ===
  3. where 1=1 and name = #name#
  4. selectUser
  5. ===
  6. select * from user #use("condition")#

globalUse 参数是其他文件的globalUse,如globalUse("share.accessControl"),将访问share.md(sql)文件的accessControl片段

  • db.dynamicSql类似use功能,但第一个参数是sql片段,而不是sqlId
  1. queryUsers
  2. ===
  3. @ var sql = "id=#xxx#";
  4. select #page("*")# from user where 1=1 and #db.dynamicSql(sql,{xxx:1})#
  • page 用于pagequery,但beetlsql 使用pagequery查询,会将sql模板翻译成带有count(1),和列表名的俩个sql语句,因此必须使用page函数或者pageTag标签
  1. queryNewUser
  2. ===
  3. select #page()# from user

如果无参数,则在查询的时候解释成 *,如果有参数,则解释成列名,如 page("a.name,a.id,b.name role_name") ,如果列名较多,可以使用pageTag

13.11. 标签功能

  • beetlsql 提供了trim标签函数,用于删除标签体最后一个逗号,这可以帮助拼接条件sql,如
  1. updateStatus
  2. ===
  3. update user set
  4. @trim(){
  5. @if(!isEmpty(age){
  6. age = #age# ,
  7. @} if(!isEmpty(status){
  8. status = #status#,
  9. @}
  10. @}
  11. where id = #id#

trim 标签可以删除 标签体里的最后一个逗号.trim 也可以实现类似mybatis的功能,通过传入trim参数prefix,prefixOverrides来完成。具体参考标签api 文档

  • pageTag,同page函数,用于pageQuery,如
  1. queryNewUser
  2. ===
  3. select
  4. @pageTag(){
  5. id,name,status
  6. @}
  7. from user

注:可以参考beetl官网 了解如何开发自定义标签以及注册标签函数

  • pageIgnoreTag,该标签的作用是在生成分页查询的count语句时,忽略sql语句里的某些内容,如:order by 。pageIgnoreTag与pageTag标签组合使用,组合如下
  1. queryNewUser
  2. ===
  3. select
  4. @pageTag(){
  5. id,name,status
  6. @}
  7. from user
  8. @pageIgnoreTag(){
  9. order by a.createTime
  10. @}

因为count语句,无需要排序语句部分,而且,有些数据库,如SQLServer并不支持count语句被排序,因此可以使用pageIgnoreTag来解决夸数据库问题

  • where 该标签复用TrimTag,其工作过程是:判断where 里的sql内容是否为空,如果为空就不输出空字符串,如果不为空则判断sql是否以AND或OR开头,如果是,则去掉。例如模板内容如下:
  1. queryNewUser
  2. ===
  3. select a.* from user a
  4. @where(){
  5. @if(!isEmpty(age){
  6. and a.age=#age#
  7. @}
  8. @if(!isEmpty(status){
  9. and a.status=#status#
  10. @}
  11. @}

将生成

  1. select a.* from user a
  2. where
  3. a.age=?
  4. and a.status=?

当然,如果你不用where,也可用where 1=1 来解决,我看并没有多大差别。