ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 把SQL放到文件里 像MyBatis那样,复杂的SQL放到XML文件中维护,好处非常多,这也是为什么复杂的企业系统,互联网电商后台都采用sql文件维护sql的原因。当然,如果你项目足够简单,也可以在java里维护SQL。但BeetlSQL3推荐尽量使用markdown维护SQL 一个Markdown文件包含多个SQL片段,因此可以通过文件名+ sql标识来引用sql片段,比如 ```java SqlId id = SqlId.of("user","select"); ``` 这里表示一个user.md文件中的select片段 ```java SqlId id = SqlId.of("sys.user","select"); ``` 这表示sys/user.md中的select片段 文件默认位于classpath的sql目录下,这是在SQLManagerBuilder中定义的,你可以设置不同的目录 ```java SQLManagerBuilder builder = new SQLManagerBuilder(source); ClasspathLoader sqlLoader = new MarkdownClasspathLoader("sql","utf-8"); builder.setSqlLoader(sqlLoader); ``` BeetlSQL通过SqlId来锁定sql片段的内容。但也考虑数据库类型,考虑到跨库操作,可能同一个查询在不同数据库下确实是不同的sql,BeetlSQL会进一步查询数据库下有没有特定的sql。比如SQLManager的dbStyle是H2Style,则查询 `sql/user.md` 和 `sql/${style.getNme()}/user.md ` 这里style.getName 返回的是h2,如果数据库方言下有特定的sql片段,则优先使用 > 通常sql/user.md 放入公共的,通用sql, style目录下放入不同的sql 关于如何写sql模板,会稍后章节说明,如下是一些简单说明。 - 采用md格式,===上面是sql语句在本文件里的唯一标示,下面则是sql语句。 - `-- @` 和`回车符号`是定界符号,可以在里面写beetl语句。 - `#{}` 是占位符号,生成sql语句得时候,将输出?,如果你想输出表达式值,需要用text函数,或者任何以db开头的函数,引擎则认为是直接输出文本。 - `${}`直接输出文本内容而不是占位符,需要开发者自行考虑是否sql注入。beetlsql支持定制`${}`语义来自动判断sql注入安全 如下是一个简单的markdwon文件 ```markdown select === select * from sys_user where 1=1 @if(!isEmpty(age)){ and age = #{age} @} @if(!isEmpty(name)){ and name = {name} @} updateById === update sys_user set status=1 where id = #{id} ``` > beetlsql 支持idea插件,使用beetlsql插件管理,导航,提示sql语句,同mybatis插件一样功能 BeetlSQL提供如下API调用SQL片段查询数据库 - public <T> List<T> select(SqlId sqlId, Class<T> clazz, Map<String, Object> paras) 根据sqlid来查询,参数是个map - public <T> List<T> select(SqlId sqlId, Class<T> clazz, Object paras) 根据sqlid来查询,参数是个pojo - public <T> List<T> select(SqlId sqlId, Class<T> clazz) 根据sqlid来查询,无参数 - public <T> T selectSingle(SqlId id,Object paras, Class<T> target) 根据sqlid查询,输入是Pojo,将对应的唯一值映射成指定的target对象,如果未找到,则返回空。需要注意的时候,有时候结果集本身是空,这时候建议使用unique - public <T> T selectSingle(SqlId id,Map<String, Object> paras, Class<T> target) 根据sqlid查询,输入是Map,将对应的唯一值映射成指定的target对象,如果未找到,则返回空。需要注意的时候,有时候结果集本身是空,这时候建议使用unique - public <T> T selectUnique(SqlId id,Object paras, Class<T> target) 根据sqlid查询,输入是Pojo或者Map,将对应的唯一值映射成指定的target对象,如果未找到,则抛出异常 - public <T> T selectUnique(String id,Map<String, Object> paras, Class<T> target) 根据sqlid查询,输入是Pojo或者Map,将对应的唯一值映射成指定的target对象,如果未找到,则抛出异常 - public Integer intValue(SqlId id,Object paras) 查询结果映射成Integer,如果找不到,返回null,输入是object - public Integer intValue(SqlId id,Map paras) 查询结果映射成Integer,如果找不到,返回null,输入是map,其他还有 longValue,bigDecimalValue 通过sqlid更新(删除) - public int insert(SqlId sqlId,Object paras,KeyHolder holder) 根据sqlId 插入,并返回主键,主键id由paras对象所指定,调用此方法,对应的数据库表必须主键自增。 - public int insert(SqlId sqlId,Object paras,KeyHolder holder,String keyName) 同上,主键由keyName指定 - public int insert(SqlId sqlId,Map paras,KeyHolder holder,String keyName),同上,参数通过map提供 - public int update(SqlId sqlId, Object obj) 根据sqlid更新 - public int update(SqlId sqlId, Map<String, Object> paras) 根据sqlid更新,输出参数是map - public int[] updateBatch(SqlId sqlId,List<?> list) 批量更新 - public int[] updateBatch(SqlId sqlId,Map<String, Object>[] maps) 批量更新,参数是个数组,元素类型是map ```java SqlId id = SqlId.of("user","select"); Map map = new HashMap(); map.put("name","n"); List<UserEntity> list = sqlManager.select(id,UserEntity.class,map); ```