├── .gitignore ├── README.md ├── build.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── github │ │ └── threefish │ │ └── nutz │ │ ├── sqltpl │ │ ├── SqlTplIocEventListener.java │ │ ├── SqlTplResourceLoader.java │ │ ├── SqlsTplHolder.java │ │ ├── annotation │ │ │ └── SqlsXml.java │ │ ├── dto │ │ │ └── PageDataDTO.java │ │ ├── exception │ │ │ └── NutzSqlTemplateXmlNotFoundError.java │ │ ├── resource │ │ │ ├── FileResource.java │ │ │ ├── JarResource.java │ │ │ └── Resource.java │ │ ├── service │ │ │ ├── ISqlDaoExecuteService.java │ │ │ └── ISqlTpl.java │ │ └── templte │ │ │ ├── ISqlTemplteEngine.java │ │ │ └── beetl │ │ │ └── BeetlSqlTemplteEngineImpl.java │ │ └── utils │ │ └── XmlUtils.java └── resources │ └── dtd │ └── nutz-sqltpl.dtd └── test ├── java └── com │ └── github │ └── threefish │ └── nutz │ ├── sqls │ ├── Bean.java │ ├── Bean.xml │ ├── Bean1.java │ ├── Bean2.java │ ├── LoadTest.java │ └── test │ │ └── Bean2.xml │ └── utils │ └── XmlTest.java └── resources └── testBeetl.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /*.iml 2 | /.idea 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | nutz-sqltpl SQL模板实现 2 | ================================== 3 | ### 配合[NutzCodeInsight](https://plugins.jetbrains.com/plugin/10311-nutzcodeinsight)插件使用更香 4 | [源码](https://github.com/threefish/nutz-sqltpl) 5 | 6 | ### 支持多种模板引擎 7 | 8 | 默认采用beetl引擎(注意,这不是与BeetlSql的集成),其他模版引擎可以自己扩展,详情看源码 9 | 10 | 11 | ### [spring 版本请看这里](https://gitee.com/threefish/spring-boot-sqltpl) 12 | 13 | ### 用法 14 | - 然后在pom.xml中 15 | ```xml 16 | 17 | com.github.threefish 18 | nutz-sqltpl 19 | 最新版本 20 | 21 | ``` 22 | maven坐标 [https://mvnrepository.com/artifact/com.github.threefish/nutz-sqltpl](https://mvnrepository.com/artifact/com.github.threefish/nutz-sqltpl) 23 | ##### 然后在ioc.js中 24 | ```javascript 25 | var ioc = { 26 | sqlTplIocEventListener: { 27 | type: "com.github.threefish.nutz.sqltpl.SqlTplIocEventListener", 28 | args: [{refer: '$ioc'}] 29 | }, 30 | beetlSqlTemplteEngineImpl: { 31 | type: "com.github.threefish.nutz.sqltpl.templte.beetl.BeetlSqlTemplteEngineImpl", 32 | events: { 33 | create: "init" 34 | }, 35 | fields: { 36 | statementStart : "",//可修改(如需要使用xmltag的只支持 xml tag,不支持其他xml tag) 37 | statementEnd :""//可修改 38 | } 39 | } 40 | } 41 | } 42 | ``` 43 | 44 | 然后,在MainSetup.init内加入下面的语句, 启用热加载 45 | 46 | ```java 47 | SqlsTplHolder.DEVELOPER_MODE = true; 48 | ``` 49 | 50 | #### 简单用法 51 | 52 | ```java 53 | @SqlsXml("Bean1.xml") 54 | public class Bean1 implements ISqlTpl { 55 | 56 | private SqlsTplHolder sqlsTplHolder; 57 | 58 | @Override 59 | public SqlsTplHolder getSqlTplHolder() { 60 | return this.sqlsTplHolder; 61 | } 62 | 63 | @Override 64 | public void setSqlTpl(SqlsTplHolder sqlsTplHolder) { 65 | this.sqlsTplHolder = sqlsTplHolder; 66 | } 67 | } 68 | ``` 69 | 70 | 71 | #### 复杂用法,你需要一个Service文件 实现 ISqlDaoExecuteService 接口 72 | 73 | ```java 74 | @IocBean(args = {"refer:dao"}, name = "companyService") 75 | @SqlsXml("CompanyService.xml") 76 | public class CompanyServiceImpl extends BaseServiceImpl implements ISqlTpl, CompanyService, ISqlDaoExecuteService { 77 | /** 78 | * 1、我是必须要有的 79 | * 2、可以不实现 ISqlDaoExecuteService 接口,用 SqlsTplHolder 直接渲染sql自己再进行操作 80 | */ 81 | private SqlsTplHolder sqlsTplHolder; 82 | 83 | public CompanyServiceImpl(Dao dao) { 84 | super(dao); 85 | } 86 | 87 | @Override 88 | public SqlsTplHolder getSqlsTplHolder() { 89 | return this.sqlsTplHolder; 90 | } 91 | 92 | 93 | @Override 94 | public SqlsTplHolder getSqlTplHolder() { 95 | return this.sqlsTplHolder; 96 | } 97 | 98 | @Override 99 | public void setSqlTpl(SqlsTplHolder sqlsTplHolder) { 100 | this.sqlsTplHolder = sqlsTplHolder; 101 | } 102 | 103 | 104 | @Override 105 | public Dao getDao() { 106 | return dao; 107 | } 108 | 109 | @Override 110 | public Entity getEntity() { 111 | return super.getEntity(); 112 | } 113 | 114 | @Override 115 | public Class getEntityClass() { 116 | return super.getEntityClass(); 117 | } 118 | /** 119 | * 分页查询列表 120 | * @param param 121 | * @param pager 122 | * @return 123 | */ 124 | @Override 125 | public List queryAllBySql(NutMap param, Pager pager) { 126 | //此处queryAll对应 127 | return queryMapBySql("queryAll", param); 128 | } 129 | } 130 | 131 | 132 | ``` 133 | 你需要一个XML文件来管理当前service的Sql(请把我和CompanyServiceImpl放在一起,或采用相对路径自己摸索) 134 | #### 当模版语法 if()... for()...等等 取值表达式 ${} 135 | 来看一下例子 136 | ```xml 137 | 138 | 140 | 141 | 142 | logistics_company 143 | 144 | 145 | SELECT * from ${tableName} 146 | if(isNotEmpty(name)){ 147 | where name like @name 148 | } 149 | 150 | 151 | ``` 152 | ![NutzCodeInsight](https://github.com/threefish/NutzCodeInsight/raw/master/image/NutzSqlTpl.gif) 153 | -------------------------------------------------------------------------------- /build.md: -------------------------------------------------------------------------------- 1 | ####发布相关 2 | 3 | ```bash 4 | mvn clean deploy -P release -D maven.test.skip=true 5 | ``` 6 | 7 | 8 | idea生成JAVADOC 报java.lang.IllegalArgumentException解决方案[终极] 9 | idea生成javadoc文档,总是会报 10 | ```bash 11 | java.lang.IllegalArgumentException 12 | at sun.net.www.ParseUtil.decode(ParseUtil.java:202) 13 | ``` 14 | 解决方案:原因是classpath环境变量中使用%JAVA_HOME%相对路径,改成绝对路径可解决此问题 15 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | org.sonatype.oss 9 | oss-parent 10 | 7 11 | 12 | 13 | com.github.threefish 14 | nutz-sqltpl 15 | 2.0.2.RELEASE 16 | 17 | https://github.com/threefish 18 | 19 | Github Issue 20 | https://github.com/threefish/nutz-sqltpl/issues 21 | 22 | 23 | 24 | UTF-8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | oss 32 | https://oss.sonatype.org/content/repositories/snapshots 33 | 34 | 35 | oss 36 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 37 | 38 | 39 | 40 | 41 | 42 | release 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-source-plugin 48 | 3.0.1 49 | 50 | 51 | attach-sources 52 | 53 | jar-no-fork 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-javadoc-plugin 61 | 3.0.1 62 | 63 | 64 | attach-javadocs 65 | 66 | jar 67 | 68 | 69 | 70 | 71 | 72 | org.apache.maven.plugins 73 | maven-gpg-plugin 74 | 1.5 75 | 76 | 77 | sign-artifacts 78 | verify 79 | 80 | sign 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | org.apache.maven.plugins 93 | maven-compiler-plugin 94 | 3.8.0 95 | 96 | 1.8 97 | 1.8 98 | 99 | -parameters 100 | 101 | false 102 | 103 | 104 | 105 | 106 | org.sonatype.plugins 107 | nexus-staging-maven-plugin 108 | 1.6.8 109 | true 110 | 111 | oss 112 | https://oss.sonatype.org/ 113 | true 114 | 115 | 116 | 117 | 118 | 119 | 120 | org.nutz 121 | nutz 122 | 1.r.68.v20190516 123 | 124 | 125 | com.ibeetl 126 | beetl 127 | 2.9.10 128 | true 129 | 130 | 131 | org.antlr 132 | antlr4-runtime 133 | 134 | 135 | 136 | 137 | junit 138 | junit 139 | 4.13.1 140 | test 141 | 142 | 143 | org.antlr 144 | antlr4-runtime 145 | 4.7.1 146 | 147 | 148 | com.h2database 149 | h2 150 | 1.4.193 151 | test 152 | 153 | 154 | log4j 155 | log4j 156 | 1.2.17 157 | test 158 | 159 | 160 | 161 | 162 | 163 | The Apache Software License, Version 2.0 164 | http://www.apache.org/licenses/LICENSE-2.0.txt 165 | repo 166 | 167 | 168 | 169 | master 170 | git@github.com:threefish/nutz-sqltpl.git 171 | scm:git:git@github.com:threefish/nutz-sqltpl.git 172 | scm:git:git@github.com:threefish/nutz-sqltpl.git 173 | 174 | 175 | 176 | threefish 177 | huchuc@vip.qq.com 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /src/main/java/com/github/threefish/nutz/sqltpl/SqlTplIocEventListener.java: -------------------------------------------------------------------------------- 1 | package com.github.threefish.nutz.sqltpl; 2 | 3 | import com.github.threefish.nutz.sqltpl.annotation.SqlsXml; 4 | import com.github.threefish.nutz.sqltpl.exception.NutzSqlTemplateXmlNotFoundError; 5 | import com.github.threefish.nutz.sqltpl.resource.FileResource; 6 | import com.github.threefish.nutz.sqltpl.resource.JarResource; 7 | import com.github.threefish.nutz.sqltpl.templte.ISqlTemplteEngine; 8 | import com.github.threefish.nutz.sqltpl.service.ISqlTpl; 9 | import org.nutz.ioc.Ioc; 10 | import org.nutz.ioc.IocEventListener; 11 | import org.nutz.ioc.loader.annotation.IocBean; 12 | import org.nutz.log.Log; 13 | import org.nutz.log.Logs; 14 | 15 | import java.io.File; 16 | import java.io.UnsupportedEncodingException; 17 | import java.net.URL; 18 | import java.net.URLDecoder; 19 | import java.nio.charset.Charset; 20 | import java.util.Objects; 21 | 22 | /** 23 | * @author 黄川 huchuc@vip.qq.com 24 | *

Date: 2019/2/19

25 | */ 26 | @IocBean(args = "refer:$ioc") 27 | public class SqlTplIocEventListener implements IocEventListener { 28 | private static final Log LOG = Logs.get(); 29 | private static final String JAR = "jar"; 30 | private static final String XML = ".xml"; 31 | private final Ioc ioc; 32 | 33 | public SqlTplIocEventListener(Ioc ioc) { 34 | this.ioc = ioc; 35 | } 36 | 37 | @Override 38 | public Object afterBorn(Object obj, String beanName) { 39 | return obj; 40 | } 41 | 42 | @Override 43 | public Object afterCreate(Object bean, String beanName) { 44 | if (bean instanceof ISqlTpl) { 45 | ISqlTpl iSqlTpl = (ISqlTpl) bean; 46 | Class klass = bean.getClass(); 47 | SqlsXml sqls = (SqlsXml) klass.getAnnotation(SqlsXml.class); 48 | if (sqls != null) { 49 | iSqlTpl.setSqlTpl(getSqlsTplHolder(klass, getXmlName(klass), ioc.getByType(sqls.klass()))); 50 | } 51 | } 52 | return bean; 53 | } 54 | 55 | @Override 56 | public int getOrder() { 57 | return 0; 58 | } 59 | 60 | /** 61 | * 取得xml文件名 62 | * @param klass 63 | * @return 64 | */ 65 | private String getXmlName(Class klass) { 66 | SqlsXml sqls = (SqlsXml) klass.getAnnotation(SqlsXml.class); 67 | return "".equals(sqls.value()) ? klass.getSimpleName().concat(XML) : sqls.value(); 68 | } 69 | 70 | /** 71 | * 取得xml文件 72 | * 73 | * @param klass 74 | * @param fileName 75 | * @return 76 | */ 77 | private SqlsTplHolder getSqlsTplHolder(Class klass, String fileName, ISqlTemplteEngine sqlTemplteEngine) { 78 | try { 79 | String xmlPath = klass.getPackage().getName().replace(".", File.separator) + File.separator + fileName; 80 | URL url = klass.getClassLoader().getResource(xmlPath); 81 | if (Objects.isNull(url)) { 82 | throw new NutzSqlTemplateXmlNotFoundError(String.format("sqls xml [%s] is not exists!!!", xmlPath)); 83 | } 84 | if (JAR.equals(url.getProtocol())) { 85 | return new SqlsTplHolder( 86 | new SqlTplResourceLoader(new JarResource(new File(klass.getProtectionDomain().getCodeSource().getLocation().getPath()), url), 87 | sqlTemplteEngine)); 88 | } else { 89 | File file = new File(URLDecoder.decode(url.getFile(), Charset.defaultCharset().name())); 90 | if (file.exists()) { 91 | return new SqlsTplHolder(new SqlTplResourceLoader(new FileResource(file), sqlTemplteEngine)); 92 | } 93 | } 94 | throw new NutzSqlTemplateXmlNotFoundError(String.format("sqls xml [%s] is not exists!!!", xmlPath)); 95 | } catch (UnsupportedEncodingException e) { 96 | LOG.error("不支持的编码异常", e); 97 | throw new NutzSqlTemplateXmlNotFoundError(e); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/com/github/threefish/nutz/sqltpl/SqlTplResourceLoader.java: -------------------------------------------------------------------------------- 1 | package com.github.threefish.nutz.sqltpl; 2 | 3 | import com.github.threefish.nutz.sqltpl.resource.Resource; 4 | import com.github.threefish.nutz.sqltpl.templte.ISqlTemplteEngine; 5 | import com.github.threefish.nutz.utils.XmlUtils; 6 | import org.nutz.log.Log; 7 | import org.nutz.log.Logs; 8 | import org.w3c.dom.Document; 9 | 10 | import java.io.File; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * @author 黄川 huchuc@vip.qq.com 16 | * date: 2020/5/25 17 | */ 18 | public class SqlTplResourceLoader { 19 | 20 | private static final Log LOGGER = Logs.get(); 21 | /** 22 | * 是否开发者模式,可以动态加载XML中的SQL 23 | */ 24 | public static boolean DEVELOPER_MODE = false; 25 | /** 26 | * 文件修改时间 27 | */ 28 | private static volatile Long updatetime = System.currentTimeMillis(); 29 | /** 30 | * 模版中可以进行引用的变量 如${cols} 31 | */ 32 | private final HashMap vars = new HashMap<>(); 33 | /** 34 | * 模版ID与未渲染前SQL内容的缓存 35 | */ 36 | private final HashMap sqlTemplateCache = new HashMap<>(); 37 | 38 | /** 39 | * jar情况下的文件资源 40 | */ 41 | private final Resource resource; 42 | 43 | /** 44 | * 当前使用的模版引擎 45 | */ 46 | private final ISqlTemplteEngine sqlTemplteEngine; 47 | 48 | /** 49 | * @param resource JAR中的xml文件资源信息 50 | * @param sqlTemplteEngine SQL模版引擎 51 | */ 52 | public SqlTplResourceLoader(Resource resource, ISqlTemplteEngine sqlTemplteEngine) { 53 | this.resource = resource; 54 | this.sqlTemplteEngine = sqlTemplteEngine; 55 | this.load(); 56 | } 57 | 58 | /** 59 | * 渲染Sql 60 | * 61 | * @param id xml中的唯一ID 62 | * @param param 变量参数 63 | * @return 渲染后的SQL文本 64 | */ 65 | public String renderSql(String id, Map param) { 66 | String sqlTemplate = getSqlTemplate(id); 67 | vars.forEach((key, value) -> param.put(key, value)); 68 | return sqlTemplteEngine.render(sqlTemplate, param); 69 | } 70 | 71 | /** 72 | * 取得未经过beetl模版引擎的sql语句 73 | * 74 | * @param id 75 | * @return 76 | */ 77 | public String getSqlTemplate(String id) { 78 | if (DEVELOPER_MODE) { 79 | File file = resource.getFile(); 80 | if (updatetime != file.lastModified()) { 81 | updatetime = file.lastModified(); 82 | this.load(); 83 | } 84 | } 85 | return sqlTemplateCache.get(id); 86 | } 87 | 88 | 89 | /** 90 | * 加载资源 91 | */ 92 | private final void load() { 93 | try { 94 | vars.clear(); 95 | sqlTemplateCache.clear(); 96 | Document document = XmlUtils.loadDocument(resource.getInputStream()); 97 | XmlUtils.setCache(document, "sql", "id", sqlTemplateCache); 98 | XmlUtils.setCache(document, "var", "name", vars); 99 | } catch (Exception e) { 100 | LOGGER.error("资源加载失败", e); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/github/threefish/nutz/sqltpl/SqlsTplHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.threefish.nutz.sqltpl; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author 黄川 huchuc@vip.qq.com 7 | *

Date: 2019/2/19

8 | */ 9 | public class SqlsTplHolder { 10 | /** 11 | * SQL资源加载器 12 | */ 13 | SqlTplResourceLoader sqlTplResourceLoader; 14 | 15 | /** 16 | * 17 | * @param sqlTplResourceLoader SQL资源加载器 18 | */ 19 | public SqlsTplHolder(SqlTplResourceLoader sqlTplResourceLoader) { 20 | this.sqlTplResourceLoader = sqlTplResourceLoader; 21 | } 22 | 23 | /** 24 | * 渲染Sql 25 | * 26 | * @param id xml中的唯一ID 27 | * @param param 变量参数 28 | * @return 渲染后的SQL文本 29 | */ 30 | public String getSql(String id, Map 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 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 | --------------------------------------------------------------------------------