# SQL 模板

Fly不进行完整的SQL解析,为了方便SQL的管理及维护,可以借助一些简单的语法标记,在实体配置存在的情况下,根据这些配置信息对SQL做一些简单的处理,包括但不限于:

  1. 实体及字段名转换
  2. 动态 SQL

具体使用方法见下文。

# 实体及字段映射

  • 实体映射语法:[Entity]若有别名,应同时把别名括入

假设实体Entity表名为entity_table,实体User表名为user_table

SELECT e.title, u.name FROM [Entity e] LEFT JOIN [User u] ON (e.created_by = u.id)

最终执行的SQL为:

SELECT e.title, u.name FROM entity_table e LEFT JOIN user_table u ON (e.created_by = u.id)
  • 字段映射语法:#field若有前缀,#应在前缀之前

字段映射需要在已有实体映射的基础上配置,假设上例中Entity实体表的created_by列字段名为createdBy,则SQL可写为:

SELECT e.title, u.name FROM [Entity e] LEFT JOIN [User u] ON (#e.createdBy = u.id)

※ 常见问题

  1. 若实体或字段没有找到对应的定义数据,则带[]#原样执行,通过数据库抛异常的方式提醒补充对应的配置;

  2. 区分小大写;

  3. 若存在多个映射实体,且实体中有同名字段,在SQL中进行字段映射时,若有前缀则根据前缀对应的实体获取字段;若没有前缀,则默认从SQL中一个映射实体中获取字段,没有则从下一个实体获取,以此类推,因此建议在有多个映射实体的SQL中,需要映射的字段指定前缀。

# 动态 SQL

# 命名参数是否存在

语法为:{?...},大括号内部为SQL,示例:

select * from entity where 1=1 {?and name = :name or title = :title}

内部必须有一个以上命名参数,{?...}不能嵌套使用,只有判断到所有命名参数都有值时,大括号内部的语句块才会加入最后执行的SQL

dao.createSQLQuery("select * from entity where 1=1 {?and name = :name or title = :title}")
    .param("name", "n")
    .parem("title", "t")
    .count();

两个命名参数都有值,最终执行的SQL为:

select * from entity where 1=1 and name = 'n' or title = 't'

nametitlenull,则最终执行的SQL为:

select * from entity where 1=1

# if-else

{?...}只能判断参数是否有值,不能对比参数的内容或进行更复杂的判断逻辑,因此需要使用if-else语法,语法为:

@if(spel表达式) SQL @elseif(spel表达式) SQL @else SQL @end
  • 必须以@if开头
  • 必须以@end结尾
  • 括号中为 spel 表达式,可以使用命名参数作判断

简单示例:

如查询中会传入命名参数type,根据参数值判断查询条件,当type值不同查询条件也不同:

SELECT * FROM entity where @if(type == 1) type_code = '1' @elseif(type == 2) type_code = '2' @else type_code is null @end and code = 'demo'

type为 1 时,最终执行的SQL为:

SELECT * FROM entity where type_code = '1' and code = 'demo'

当未传入type参数时,最终执行的SQL为:

SELECT * FROM entity where type_code is null and code = 'demo'
顶部