param) {
31 | return sqlTplResourceLoader.renderSql(id, param);
32 | }
33 |
34 | /**
35 | * 取得原始模版
36 | *
37 | * @param id xml中的唯一ID
38 | * @return 原始模版
39 | */
40 | public String getOriginalTemplate(String id) {
41 | return sqlTplResourceLoader.getSqlTemplate(id);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/annotation/SqlsXml.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.annotation;
2 |
3 | import com.github.threefish.nutz.sqltpl.templte.ISqlTemplteEngine;
4 | import com.github.threefish.nutz.sqltpl.templte.beetl.BeetlSqlTemplteEngineImpl;
5 |
6 | import java.lang.annotation.*;
7 |
8 | /**
9 | * @author 黄川 huchuc@vip.qq.com
10 | * Date: 2019/2/19
11 | */
12 | @Target({ElementType.TYPE})
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Documented
15 | @Inherited
16 | public @interface SqlsXml {
17 |
18 | /**
19 | * 文件相对与当前service类路径
20 | *
21 | * 默认为java文件名以.xml结尾 如(UserServicesImpl.java 对应 UserServicesImpl.xml)
22 | *
23 | * @return xml文件路径
24 | */
25 | String value() default "";
26 |
27 | /**
28 | * 模版类 (模版类需要放到IOC中进行管理)
29 | *
30 | * @return 提供渲染模版的实现类
31 | */
32 | Class extends ISqlTemplteEngine> klass() default BeetlSqlTemplteEngineImpl.class;
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/dto/PageDataDTO.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.dto;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author 黄川 huchuc@vip.qq.com
7 | *
Date: 2019/2/20
8 | */
9 | public class PageDataDTO {
10 |
11 | /**
12 | * 返回数据总数
13 | */
14 | private final Long count;
15 | /**
16 | * 返回数据
17 | */
18 | private final List data;
19 |
20 | public PageDataDTO(Long count, List data) {
21 | this.count = count;
22 | this.data = data;
23 | }
24 |
25 | public Long getCount() {
26 | return count;
27 | }
28 |
29 | public List getData() {
30 | return data;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return "PageDataDTO{" +
36 | "count=" + count +
37 | ", data=" + data +
38 | '}';
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/exception/NutzSqlTemplateXmlNotFoundError.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.exception;
2 |
3 | /**
4 | * @author huchuc@vip.qq.com
5 | * Date: 2019/06/05
6 | */
7 | public class NutzSqlTemplateXmlNotFoundError extends RuntimeException {
8 |
9 | public NutzSqlTemplateXmlNotFoundError(String message) {
10 | super(message);
11 | }
12 |
13 | public NutzSqlTemplateXmlNotFoundError(Throwable cause) {
14 | super(cause);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/resource/FileResource.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.resource;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | /**
9 | * @author 黄川 huchuc@vip.qq.com
10 | * date: 2020/3/11
11 | */
12 | public class FileResource implements Resource {
13 | /**
14 | * 文件(通过文件的修改时间判断是否重新加载xml文件)
15 | */
16 | protected File file;
17 |
18 | public FileResource(File file) {
19 | this.file = file;
20 | }
21 |
22 | @Override
23 | public InputStream getInputStream() throws IOException {
24 | return new FileInputStream(file);
25 | }
26 |
27 | @Override
28 | public File getFile() {
29 | return file;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/resource/JarResource.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.resource;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.net.URL;
7 |
8 | /**
9 | * @author 黄川 huchuc@vip.qq.com
10 | * date: 2020/3/11
11 | */
12 | public class JarResource extends FileResource {
13 |
14 | /**
15 | * xml资源路径
16 | */
17 | URL xmlFileUrl;
18 |
19 | public JarResource(File file, URL xmlFileUrl) {
20 | super(file);
21 | this.xmlFileUrl = xmlFileUrl;
22 | }
23 |
24 | @Override
25 | public InputStream getInputStream() throws IOException {
26 | return xmlFileUrl.openStream();
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/resource/Resource.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.resource;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | /**
8 | * @author 黄川 huchuc@vip.qq.com
9 | * date: 2020/3/14
10 | */
11 | public interface Resource {
12 |
13 | /**
14 | * @return xml输入流
15 | * @throws IOException
16 | */
17 | InputStream getInputStream() throws IOException;
18 |
19 | /**
20 | * 取得文件
21 | *
22 | * @return 取得文件
23 | */
24 | File getFile();
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/service/ISqlDaoExecuteService.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.service;
2 |
3 | import com.github.threefish.nutz.sqltpl.SqlsTplHolder;
4 | import com.github.threefish.nutz.sqltpl.dto.PageDataDTO;
5 | import org.nutz.dao.Cnd;
6 | import org.nutz.dao.Dao;
7 | import org.nutz.dao.Sqls;
8 | import org.nutz.dao.entity.Entity;
9 | import org.nutz.dao.pager.Pager;
10 | import org.nutz.dao.sql.Sql;
11 | import org.nutz.dao.sql.SqlCallback;
12 | import org.nutz.dao.util.Daos;
13 | import org.nutz.lang.util.NutMap;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * @author 黄川 huchuc@vip.qq.com
19 | * Date: 2019/2/19
20 | */
21 | public interface ISqlDaoExecuteService {
22 | /**
23 | * SQL信息持有者
24 | *
25 | * @return SQL信息持有者
26 | */
27 | SqlsTplHolder getSqlsTplHolder();
28 |
29 | /**
30 | * 取得dao
31 | *
32 | * @return 取得dao
33 | */
34 | Dao getDao();
35 |
36 | /**
37 | * 获取实体的Entity
38 | *
39 | * @return 实体的Entity
40 | */
41 | Entity getEntity();
42 |
43 | /**
44 | * 获取实体类型
45 | *
46 | * @return 实体类型
47 | */
48 | Class getEntityClass();
49 |
50 |
51 | /**
52 | * 取得Sql
53 | *
54 | * @param id sqlxml中的唯一ID
55 | * @param param 查询参数
56 | * @param cnd 为 SQL 增加条件,SQL 必须有 '$condition' 变量
57 | * @param callback 自定义callback
58 | * @return sql
59 | */
60 | default Sql getSql(String id, NutMap param, Cnd cnd, SqlCallback callback) {
61 | Sql sql = Sqls.create(getSqlsTplHolder().getSql(id, param));
62 | param.forEach((k, v) -> sql.setParam(k, v));
63 | sql.setCallback(callback);
64 | if (cnd != null) {
65 | sql.setCondition(cnd);
66 | }
67 | return sql;
68 | }
69 |
70 |
71 | /**
72 | * 分页查询列表
73 | *
74 | * @param id sqlxml中的唯一ID
75 | * @param param 查询参数
76 | * @param pager 分页参数
77 | * @return 列表NutMap类型
78 | */
79 | default PageDataDTO queryMapBySql(String id, NutMap param, Pager pager) {
80 | return queryMapBySql(id, param, null, pager);
81 | }
82 |
83 | /**
84 | * 分页查询列表实体
85 | *
86 | * @param id sqlxml中的唯一ID
87 | * @param param 查询参数
88 | * @param pager 分页参数
89 | * @return 列表实体类型
90 | */
91 | default PageDataDTO queryEntityBySql(String id, NutMap param, Pager pager) {
92 | return queryEntityBySql(id, param, null, pager, getEntityClass());
93 | }
94 |
95 | /**
96 | * 分页查询列表实体
97 | *
98 | * @param id sqlxml中的唯一ID
99 | * @param param 查询参数
100 | * @param pager 分页参数
101 | * @return 列表实体类型
102 | */
103 | default PageDataDTO queryEntityBySql(String id, NutMap param, Pager pager, Class entityClass) {
104 | Sql sql = getSql(id, param, null, Sqls.callback.entities());
105 | sql.setEntity(getDao().getEntity(entityClass));
106 | sql.setPager(pager);
107 | getDao().execute(sql);
108 | return queryEntityBySql(id, param, null, pager);
109 | }
110 |
111 | /**
112 | * 不分页查询列表
113 | *
114 | * @param id sqlxml中的唯一ID
115 | * @param param 查询参数
116 | * @return 列表NutMap类型
117 | */
118 | default List queryMapBySql(String id, NutMap param) {
119 | return queryMapBySql(id, param, (Cnd) null);
120 | }
121 |
122 | /**
123 | * 不分页查询列表实体
124 | *
125 | * @param id sqlxml中的唯一ID
126 | * @param param 查询参数
127 | * @return 列表实体类型
128 | */
129 | default List queryEntityBySql(String id, NutMap param) {
130 | return queryEntityBySql(id, param, (Cnd) null);
131 | }
132 |
133 | /**
134 | * 获取单个
135 | *
136 | * @param id sqlxml中的唯一ID
137 | * @param param 查询参数
138 | * @return 单个 NutMap
139 | */
140 | default NutMap fetchMapBySql(String id, NutMap param) {
141 | return fetchMapBySql(id, param, null);
142 | }
143 |
144 | /**
145 | * 获取单个
146 | *
147 | * @param id sqlxml中的唯一ID
148 | * @param param 查询参数
149 | * @param 实体类泛型
150 | * @return 单个实体类
151 | */
152 | default T fetchEntityBySql(String id, NutMap param) {
153 | return fetchEntityBySql(id, param, null);
154 | }
155 |
156 | /**
157 | * 更新
158 | *
159 | * @param id sqlxml中的唯一ID
160 | * @param param 参数
161 | * @return 更新个数
162 | */
163 | default int updateBySql(String id, NutMap param) {
164 | return updateBySql(id, param, null);
165 | }
166 |
167 | /**
168 | * 删除
169 | *
170 | * @param id sqlxml中的唯一ID
171 | * @param param 参数
172 | * @return 删除个数
173 | */
174 | default int delectBySql(String id, NutMap param) {
175 | return updateBySql(id, param);
176 | }
177 |
178 |
179 | /**
180 | * 不分页查询列表
181 | *
182 | * @param id sqlxml中的唯一ID
183 | * @param param 查询参数
184 | * @return 列表类型
185 | */
186 | default List queryStrsBySql(String id, NutMap param) {
187 | return queryStrsBySql(id, param, null);
188 | }
189 |
190 | /**
191 | * 不分页查询列表
192 | *
193 | * @param id sqlxml中的唯一ID
194 | * @param param 查询参数
195 | * @return 列表类型
196 | */
197 | default List queryIntsBySql(String id, NutMap param) {
198 | return queryIntsBySql(id, param, null);
199 | }
200 |
201 | /**
202 | * 计数查询
203 | *
204 | * @param id sqlxml中的唯一ID
205 | * @param param 查询参数
206 | * @return 数字
207 | */
208 | default long queryLongBySql(String id, NutMap param) {
209 | return queryLongBySql(id, param, null);
210 | }
211 |
212 | /**
213 | * 分页查询列表
214 | *
215 | * @param id sqlxml中的唯一ID
216 | * @param param 查询参数
217 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
218 | * @param pager 分页参数
219 | * @return 列表NutMap类型
220 | */
221 | default PageDataDTO queryMapBySql(String id, NutMap param, Cnd cnd, Pager pager) {
222 | Sql sql = getSql(id, param, cnd, Sqls.callback.maps());
223 | long count = Daos.queryCount(getDao(), sql);
224 | sql.setPager(pager);
225 | getDao().execute(sql);
226 | return new PageDataDTO(count, sql.getList(NutMap.class));
227 | }
228 |
229 | /**
230 | * 分页查询列表实体
231 | *
232 | * @param id sqlxml中的唯一ID
233 | * @param param 查询参数
234 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
235 | * @param pager 分页参数
236 | * @return 列表实体类型
237 | */
238 | default PageDataDTO queryEntityBySql(String id, NutMap param, Cnd cnd, Pager pager) {
239 | return queryEntityBySql(id, param, cnd, pager, getEntityClass());
240 | }
241 |
242 | /**
243 | * 分页查询列表实体
244 | *
245 | * @param id sqlxml中的唯一ID
246 | * @param param 查询参数
247 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
248 | * @param pager 分页参数
249 | * @param entityClass 实体类型
250 | * @return 列表实体类型
251 | */
252 | default PageDataDTO queryEntityBySql(String id, NutMap param, Cnd cnd, Pager pager, Class entityClass) {
253 | Sql sql = getSql(id, param, cnd, Sqls.callback.entities());
254 | long count = Daos.queryCount(getDao(), sql);
255 | sql.setEntity(getDao().getEntity(entityClass));
256 | sql.setPager(pager);
257 | getDao().execute(sql);
258 | return new PageDataDTO(count, sql.getList(getEntityClass()));
259 | }
260 |
261 | /**
262 | * 不分页查询列表
263 | *
264 | * @param id sqlxml中的唯一ID
265 | * @param param 查询参数
266 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
267 | * @return 列表NutMap类型
268 | */
269 | default List queryMapBySql(String id, NutMap param, Cnd cnd) {
270 | Sql sql = getSql(id, param, cnd, Sqls.callback.maps());
271 | getDao().execute(sql);
272 | return sql.getList(NutMap.class);
273 | }
274 |
275 | /**
276 | * 不分页查询列表实体
277 | *
278 | * @param id sqlxml中的唯一ID
279 | * @param param 查询参数
280 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
281 | * @return 列表实体类型
282 | */
283 | default List queryEntityBySql(String id, NutMap param, Cnd cnd) {
284 | return queryEntityBySql(id, param, cnd, getEntityClass());
285 | }
286 |
287 | /**
288 | * 不分页查询列表实体
289 | *
290 | * @param id sqlxml中的唯一ID
291 | * @param param 查询参数
292 | * @param entityClass 指定实体类型
293 | * @return 列表实体类型
294 | */
295 | default List queryEntityBySql(String id, NutMap param, Class entityClass) {
296 | return queryEntityBySql(id, param, (Cnd) null, entityClass);
297 | }
298 |
299 | /**
300 | * 不分页查询列表实体
301 | *
302 | * @param id sqlxml中的唯一ID
303 | * @param param 查询参数
304 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
305 | * @param entityClass 指定实体类型
306 | * @return 列表实体类型
307 | */
308 | default List queryEntityBySql(String id, NutMap param, Cnd cnd, Class entityClass) {
309 | Sql sql = getSql(id, param, cnd, Sqls.callback.entities());
310 | sql.setEntity(getDao().getEntity(entityClass));
311 | getDao().execute(sql);
312 | return sql.getList(entityClass);
313 | }
314 |
315 | /**
316 | * 获取单个
317 | *
318 | * @param id sqlxml中的唯一ID
319 | * @param param 查询参数
320 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
321 | * @return 单个 NutMap
322 | */
323 | default NutMap fetchMapBySql(String id, NutMap param, Cnd cnd) {
324 | Sql sql = getSql(id, param, cnd, Sqls.callback.map());
325 | getDao().execute(sql);
326 | return sql.getObject(NutMap.class);
327 | }
328 |
329 | /**
330 | * 获取单个
331 | *
332 | * @param id sqlxml中的唯一ID
333 | * @param param 查询参数
334 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
335 | * @param 实体类泛型
336 | * @return 单个实体类
337 | */
338 | default T fetchEntityBySql(String id, NutMap param, Cnd cnd) {
339 | return fetchEntityBySql(id, param, cnd, getEntityClass());
340 | }
341 |
342 | /**
343 | * 获取单个
344 | *
345 | * @param id sqlxml中的唯一ID
346 | * @param param 查询参数
347 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
348 | * @param entityClass 指定实体类型
349 | * @param 实体类泛型
350 | * @return 单个实体类
351 | */
352 | default T fetchEntityBySql(String id, NutMap param, Cnd cnd, Class entityClass) {
353 | Sql sql = getSql(id, param, cnd, Sqls.callback.entity());
354 | sql.setEntity(getDao().getEntity(entityClass));
355 | getDao().execute(sql);
356 | return (T) sql.getObject(entityClass);
357 | }
358 |
359 | /**
360 | * 更新
361 | *
362 | * @param id sqlxml中的唯一ID
363 | * @param param 参数
364 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
365 | * @return 更新个数
366 | */
367 | default int updateBySql(String id, NutMap param, Cnd cnd) {
368 | Sql sql = getSql(id, param, cnd, Sqls.callback.integer());
369 | getDao().execute(sql);
370 | return sql.getUpdateCount();
371 | }
372 |
373 | /**
374 | * 删除
375 | *
376 | * @param id sqlxml中的唯一ID
377 | * @param param 参数
378 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
379 | * @return 删除个数
380 | */
381 | default int delectBySql(String id, NutMap param, Cnd cnd) {
382 | return updateBySql(id, param, cnd);
383 | }
384 |
385 |
386 | /**
387 | * 不分页查询列表
388 | *
389 | * @param id sqlxml中的唯一ID
390 | * @param param 查询参数
391 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
392 | * @return 列表类型
393 | */
394 | default List queryStrsBySql(String id, NutMap param, Cnd cnd) {
395 | Sql sql = getSql(id, param, cnd, Sqls.callback.strs());
396 | getDao().execute(sql);
397 | return sql.getList(String.class);
398 | }
399 |
400 | /**
401 | * 不分页查询列表
402 | *
403 | * @param id sqlxml中的唯一ID
404 | * @param param 查询参数
405 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
406 | * @return 列表类型
407 | */
408 | default List queryIntsBySql(String id, NutMap param, Cnd cnd) {
409 | Sql sql = getSql(id, param, cnd, Sqls.callback.ints());
410 | getDao().execute(sql);
411 | return sql.getList(Integer.class);
412 | }
413 |
414 | /**
415 | * 计数查询
416 | *
417 | * @param id sqlxml中的唯一ID
418 | * @param param 查询参数
419 | * @param cnd cnd 不为Null时 SQL 必须有 '$condition' 变量
420 | * @return 数字
421 | */
422 | default long queryLongBySql(String id, NutMap param, Cnd cnd) {
423 | Sql sql = getSql(id, param, cnd, Sqls.callback.integer());
424 | getDao().execute(sql);
425 | return sql.getLong(0);
426 | }
427 |
428 |
429 | }
430 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/service/ISqlTpl.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.service;
2 |
3 | import com.github.threefish.nutz.sqltpl.SqlsTplHolder;
4 |
5 | /**
6 | * @author 黄川 huchuc@vip.qq.com
7 | * date 2020/3/11
8 | */
9 | public interface ISqlTpl {
10 | /**
11 | * @return 取得sql模版持有对象
12 | */
13 | SqlsTplHolder getSqlTplHolder();
14 |
15 | /**
16 | * 设置sql模版持有对象
17 | *
18 | * @param sqlsTplHolder
19 | */
20 | void setSqlTpl(SqlsTplHolder sqlsTplHolder);
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/templte/ISqlTemplteEngine.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.templte;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * @author 黄川 huchuc@vip.qq.com
7 | * Date: 2019/2/19
8 | */
9 | public interface ISqlTemplteEngine {
10 | /**
11 | * 解析模版
12 | *
13 | * @param source 源
14 | * @param bindData 绑定参数
15 | * @return 渲染后的SQL
16 | */
17 | String render(String source, Map bindData);
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/sqltpl/templte/beetl/BeetlSqlTemplteEngineImpl.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqltpl.templte.beetl;
2 |
3 | import com.github.threefish.nutz.sqltpl.templte.ISqlTemplteEngine;
4 | import org.beetl.core.Configuration;
5 | import org.beetl.core.GroupTemplate;
6 | import org.beetl.core.Template;
7 | import org.beetl.core.exception.BeetlException;
8 | import org.beetl.core.resource.StringTemplateResourceLoader;
9 | import org.nutz.ioc.loader.annotation.IocBean;
10 | import org.nutz.lang.Strings;
11 | import org.nutz.lang.Times;
12 |
13 | import java.io.IOException;
14 | import java.util.Map;
15 |
16 | /**
17 | * @author 黄川 huchuc@vip.qq.com
18 | * Date: 2019/2/19
19 | */
20 | @IocBean(create = "init")
21 | public class BeetlSqlTemplteEngineImpl implements ISqlTemplteEngine {
22 |
23 | GroupTemplate gt;
24 | String statementStart = "";
25 | String statementEnd = "";
26 |
27 | public void setStatementStart(String statementStart) {
28 | this.statementStart = statementStart;
29 | }
30 |
31 | public void setStatementEnd(String statementEnd) {
32 | this.statementEnd = statementEnd;
33 | }
34 |
35 | public void init() {
36 | try {
37 | Configuration cfg = Configuration.defaultConfiguration();
38 | cfg.setStatementStart(statementStart);
39 | cfg.setStatementEnd(statementEnd);
40 | cfg.setHtmlTagSupport(false);
41 | gt = new GroupTemplate(new StringTemplateResourceLoader(), cfg);
42 | gt.registerFunctionPackage("Strings", Strings.class);
43 | gt.registerFunctionPackage("Times", Times.class);
44 | gt.setErrorHandler((beeExceptionos, writer) -> {
45 | throw beeExceptionos;
46 | });
47 | } catch (IOException e) {
48 | e.printStackTrace();
49 | }
50 | }
51 |
52 | /**
53 | * 解析模版
54 | *
55 | * @param templeText 模版内容
56 | * @param bindData 绑定参数
57 | * @return 渲染后的SQL
58 | */
59 | @Override
60 | public String render(String templeText, Map bindData) throws BeetlException {
61 | Template template = gt.getTemplate(templeText);
62 | template.binding(bindData);
63 | return template.render().trim();
64 | }
65 |
66 | /**
67 | * 取得后可以注册很多方法或函数等等
68 | *
69 | * @return GroupTemplate
70 | */
71 | public GroupTemplate getGt() {
72 | return gt;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/github/threefish/nutz/utils/XmlUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.utils;
2 |
3 | import org.nutz.lang.Streams;
4 | import org.nutz.lang.Strings;
5 | import org.w3c.dom.Document;
6 | import org.w3c.dom.Element;
7 | import org.w3c.dom.Node;
8 | import org.w3c.dom.NodeList;
9 | import org.xml.sax.SAXException;
10 |
11 | import javax.xml.parsers.DocumentBuilder;
12 | import javax.xml.parsers.DocumentBuilderFactory;
13 | import javax.xml.parsers.ParserConfigurationException;
14 | import java.io.IOException;
15 | import java.io.InputStream;
16 | import java.util.ArrayList;
17 | import java.util.HashMap;
18 |
19 | /**
20 | * @author 黄川 huchuc@vip.qq.com
21 | * Date: 2019/2/19
22 | */
23 | public class XmlUtils {
24 |
25 |
26 | /**
27 | * 加载XML Document
28 | *
29 | * @param xmlInputStream 资源文件流
30 | * @return 文档
31 | */
32 | public static Document loadDocument(InputStream xmlInputStream) throws IOException, SAXException, ParserConfigurationException {
33 | if (xmlInputStream == null) {
34 | throw new RuntimeException("资源文件流是 null,请检查!!!");
35 | }
36 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
37 | factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
38 | factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
39 | factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
40 | factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
41 | factory.setXIncludeAware(false);
42 | factory.setExpandEntityReferences(false);
43 | factory.setIgnoringElementContentWhitespace(true);
44 | DocumentBuilder builder = factory.newDocumentBuilder();
45 | Document document = builder.parse(xmlInputStream);
46 | document.normalizeDocument();
47 | Streams.safeClose(xmlInputStream);
48 | return document;
49 |
50 | }
51 |
52 | /**
53 | * 设置缓存
54 | *
55 | * @param document 文档
56 | * @param tag 标签
57 | * @param attrName 属性
58 | * @param hashMap map对象
59 | */
60 | public static void setCache(Document document, String tag, String attrName, HashMap hashMap) {
61 | NodeList nodeList = document.getElementsByTagName(tag);
62 | for (int i = 0; i < nodeList.getLength(); i++) {
63 | if (nodeList.item(i) instanceof Element) {
64 | Element element = (Element) nodeList.item(i);
65 | if (element.hasAttribute(attrName) && Strings.isNotBlank(element.getAttribute(attrName))) {
66 | String id = element.getAttribute(attrName);
67 | boolean wrap = Boolean.parseBoolean(element.getAttribute("wrap"));
68 | if (wrap) {
69 | hashMap.put(id, getContent(element).replace("\n", " "));
70 | } else {
71 | hashMap.put(id, getContent(element));
72 | }
73 | }
74 | }
75 | }
76 | }
77 |
78 | /**
79 | * 取得模版内容支持 exp 标签
80 | *
81 | * @param element
82 | * @return
83 | */
84 | private static String getContent(Node element) {
85 | NodeList childs = element.getChildNodes();
86 | ArrayList sb = new ArrayList();
87 | if (childs.getLength() > 0) {
88 | for (int i = 0; i < childs.getLength(); i++) {
89 | Node node = childs.item(i);
90 | if (node.getNodeType() == Node.TEXT_NODE) {
91 | sb.add(node.getTextContent().trim());
92 | } else if ("exp".equals(node.getNodeName())) {
93 | sb.add("" + getContent(node) + "");
94 | } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
95 | sb.add(node.getTextContent().trim());
96 | } else {
97 | sb.add(getContent(node));
98 | }
99 | }
100 | return Strings.join(" ", sb.toArray()).trim();
101 | }
102 | return "";
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/resources/dtd/nutz-sqltpl.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/sqls/Bean.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqls;
2 |
3 | import com.github.threefish.nutz.sqltpl.annotation.SqlsXml;
4 |
5 | /**
6 | * @author 黄川 huchuc@vip.qq.com
7 | * @date: 2019/4/2
8 | */
9 | @SqlsXml
10 | public class Bean {
11 | }
12 |
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/sqls/Bean.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/sqls/Bean1.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqls;
2 |
3 | import com.github.threefish.nutz.sqltpl.SqlsTplHolder;
4 | import com.github.threefish.nutz.sqltpl.annotation.SqlsXml;
5 | import com.github.threefish.nutz.sqltpl.service.ISqlTpl;
6 |
7 | /**
8 | * @author 黄川 huchuc@vip.qq.com
9 | * @date: 2019/4/2
10 | */
11 | @SqlsXml("Bean1.xml")
12 | public class Bean1 implements ISqlTpl {
13 |
14 | private SqlsTplHolder sqlsTplHolder;
15 |
16 | @Override
17 | public SqlsTplHolder getSqlTplHolder() {
18 | return this.sqlsTplHolder;
19 | }
20 |
21 | @Override
22 | public void setSqlTpl(SqlsTplHolder sqlsTplHolder) {
23 | this.sqlsTplHolder = sqlsTplHolder;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/sqls/Bean2.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqls;
2 |
3 | import com.github.threefish.nutz.sqltpl.annotation.SqlsXml;
4 |
5 | /**
6 | * @author 黄川 huchuc@vip.qq.com
7 | * @date: 2019/4/2
8 | */
9 | @SqlsXml("/test/Bean2.xml")
10 | public class Bean2 {
11 | }
12 |
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/sqls/LoadTest.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.sqls;
2 |
3 | import com.github.threefish.nutz.sqltpl.annotation.SqlsXml;
4 | import org.junit.Assert;
5 | import org.junit.Test;
6 |
7 | /**
8 | * @author 黄川 huchuc@vip.qq.com
9 | * @date: 2019/2/25
10 | */
11 | public class LoadTest {
12 |
13 | private static final String XML = ".xml";
14 |
15 | @Test
16 | public void testBean() {
17 | Assert.assertTrue(("Bean.xml".equals(getXmlName(Bean.class))));
18 | Assert.assertTrue(("Bean1.xml".equals(getXmlName(Bean1.class))));
19 | Assert.assertTrue(("/test/Bean2.xml".equals(getXmlName(Bean2.class))));
20 | }
21 |
22 | private String getXmlName(Class klass) {
23 | SqlsXml sqls = (SqlsXml) klass.getAnnotation(SqlsXml.class);
24 | if (sqls != null) {
25 | return "".equals(sqls.value()) ? klass.getSimpleName().concat(XML) : sqls.value();
26 | }
27 | return null;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/sqls/test/Bean2.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/threefish/nutz-sqltpl/8125bd0e64bb00278d3a46432210c1320387a6c6/src/test/java/com/github/threefish/nutz/sqls/test/Bean2.xml
--------------------------------------------------------------------------------
/src/test/java/com/github/threefish/nutz/utils/XmlTest.java:
--------------------------------------------------------------------------------
1 | package com.github.threefish.nutz.utils;
2 |
3 | import com.github.threefish.nutz.sqltpl.templte.beetl.BeetlSqlTemplteEngineImpl;
4 | import com.github.threefish.nutz.sqltpl.templte.ISqlTemplteEngine;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 | import org.nutz.lang.util.NutMap;
8 | import org.w3c.dom.Document;
9 | import org.xml.sax.SAXException;
10 |
11 | import javax.xml.parsers.ParserConfigurationException;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.util.HashMap;
15 |
16 | /**
17 | * @author 黄川 huchuc@vip.qq.com
18 | * @date: 2019/2/25
19 | */
20 | public class XmlTest {
21 |
22 | @Test
23 | public void testBeetl() throws ParserConfigurationException, SAXException, IOException {
24 | InputStream in = this.getClass().getResourceAsStream("/testBeetl.xml");
25 | Document document = XmlUtils.loadDocument(in);
26 | HashMap cache = new HashMap<>();
27 | XmlUtils.setCache(document, "sql", "id", cache);
28 | ISqlTemplteEngine engine = new BeetlSqlTemplteEngineImpl();
29 | ((BeetlSqlTemplteEngineImpl) engine).init();
30 | String sql = engine.render(cache.getOrDefault("queryAll", ""), NutMap.NEW().setv("tableName", "table_a").setv("name", "aaa"));
31 | String wrapLine = engine.render(cache.getOrDefault("wrapLine", ""), NutMap.NEW().setv("tableName", "table_a").setv("name", "aaa"));
32 | Assert.assertTrue(("SELECT * from table_a where name like @name and 1>0".equals(sql)));
33 | Assert.assertTrue(("SELECT * from table_a \"实打实的哈桑\\n撒大苏 打的撒的哈\" where name like @name and 1>0 fsadf sdfasdf sdf".equals(wrapLine)));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/resources/testBeetl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | logistics_company
6 |
7 | SELECT * from ${tableName}
8 |
11 | where name like @name and 1>0
12 | }
13 |
14 |
15 |
16 |
18 |
21 | 0]]>
23 | }
24 | fsadf
25 | sdfasdf
26 | sdf
27 |
28 |
--------------------------------------------------------------------------------