Browse Source

基本结构建立

zhouhao 8 years ago
parent
commit
315844b0b0
100 changed files with 5698 additions and 0 deletions
  1. 98 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authorize.java
  2. 30 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Logical.java
  3. 37 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/UserSubject.java
  4. 38 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/UserSubjectUtils.java
  5. 15 0
      hsweb-authorization/hsweb-authorization-oauth2/pom.xml
  6. 53 0
      hsweb-authorization/hsweb-authorization-shiro/pom.xml
  7. 62 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroUserSubject.java
  8. 38 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroUserSubjectUtils.java
  9. 62 0
      hsweb-authorization/hsweb-authorization-shiro/src/test/java/org/hswebframework/web/authorization/shiro/ShiroTests.java
  10. 15 0
      hsweb-authorization/hsweb-authorization-simple/pom.xml
  11. 3 0
      hsweb-authorization/pom.xml
  12. 52 0
      hsweb-commons/hsweb-commons-beans/pom.xml
  13. 29 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/Bean.java
  14. 62 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/GenericBean.java
  15. 56 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/PagerResult.java
  16. 38 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SharedBean.java
  17. 71 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SimpleGenericBean.java
  18. 57 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SimpleSharedBean.java
  19. 31 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SortSupport.java
  20. 95 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/TreeSortSupportBean.java
  21. 80 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/TreeSupport.java
  22. 18 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/dsl/QueryBean.java
  23. 33 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/factory/BeanFactory.java
  24. 68 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/factory/MapperBeanFactory.java
  25. 12 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/param/DeleteParamBean.java
  26. 12 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/param/QueryParamBean.java
  27. 18 0
      hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/param/UpdateParamBean.java
  28. 33 0
      hsweb-commons/hsweb-commons-beans/src/test/java/org/hswebframework/web/commons/beans/QueryBeanTests.java
  29. 61 0
      hsweb-commons/hsweb-commons-controller/pom.xml
  30. 74 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CrudController.java
  31. 46 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericBeanController.java
  32. 260 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java
  33. 44 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/pom.xml
  34. 36 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/CrudDao.java
  35. 27 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/Dao.java
  36. 29 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/DeleteDao.java
  37. 29 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/InsertDao.java
  38. 91 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DataSourceHolder.java
  39. 76 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DatabaseType.java
  40. 95 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DynamicDataSource.java
  41. 31 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/dynamic/DeleteByBeanDao.java
  42. 35 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/dynamic/QueryByBeanDao.java
  43. 31 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/dynamic/UpdateByBeanDao.java
  44. 50 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/pom.xml
  45. 105 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MyBatisAutoConfiguration.java
  46. 47 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MybatisDaoAutoConfiguration.java
  47. 110 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MybatisProperties.java
  48. 304 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java
  49. 49 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/InsertSqlBuilder.java
  50. 34 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/SqlBuilder.java
  51. 53 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/UpdateSqlBuilder.java
  52. 30 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/dynamic/DynamicDataSourceSqlSessionFactoryBuilder.java
  53. 203 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/dynamic/DynamicSpringManagedTransaction.java
  54. 147 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/dynamic/DynamicSqlSessionFactory.java
  55. 79 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/handler/JsonArrayHandler.java
  56. 79 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/handler/JsonMapHandler.java
  57. 84 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/Pager.java
  58. 64 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/PagerInterceptor.java
  59. 44 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/utils/ResultMapsUtils.java
  60. 151 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/resources/META-INF/spring-configuration-metadata.json
  61. 3 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/resources/META-INF/spring.factories
  62. 99 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/basic/BasicMapper.xml
  63. 43 0
      hsweb-commons/hsweb-commons-dao/pom.xml
  64. 40 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/pom.xml
  65. 28 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CreateBeanService.java
  66. 37 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CrudService.java
  67. 33 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/DeleteService.java
  68. 33 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/InsertService.java
  69. 37 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/QueryByBeanService.java
  70. 27 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/Service.java
  71. 49 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/UpdateService.java
  72. 60 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/pom.xml
  73. 56 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLDeleteService.java
  74. 76 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLQueryService.java
  75. 37 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLUpdateService.java
  76. 32 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDeleteService.java
  77. 111 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultQueryByBeanService.java
  78. 147 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericBeanService.java
  79. 44 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericService.java
  80. 21 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/DSLQuery.java
  81. 57 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/FieldCondition.java
  82. 46 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/SimpleDSLQuery.java
  83. 155 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/SimpleFieldCondition.java
  84. 49 0
      hsweb-commons/hsweb-commons-service/pom.xml
  85. 33 0
      hsweb-commons/hsweb-commons-utils/pom.xml
  86. 46 0
      hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/ThreadLocalUtils.java
  87. 40 0
      hsweb-commons/pom.xml
  88. 6 0
      hsweb-core/pom.xml
  89. 35 0
      hsweb-core/src/main/java/org/hswebframework/web/AuthorizeException.java
  90. 38 0
      hsweb-core/src/main/java/org/hswebframework/web/AuthorizeForbiddenException.java
  91. 46 0
      hsweb-core/src/main/java/org/hswebframework/web/BusinessException.java
  92. 35 0
      hsweb-core/src/main/java/org/hswebframework/web/Describe.java
  93. 28 0
      hsweb-core/src/main/java/org/hswebframework/web/NotFoundException.java
  94. 48 0
      hsweb-core/src/main/java/org/hswebframework/web/id/IDGenerator.java
  95. 81 0
      hsweb-core/src/main/java/org/hswebframework/web/validate/SimpleValidateResults.java
  96. 41 0
      hsweb-core/src/main/java/org/hswebframework/web/validate/ValidateResults.java
  97. 39 0
      hsweb-core/src/main/java/org/hswebframework/web/validate/ValidationException.java
  98. 15 0
      hsweb-dynamic-datasource/pom.xml
  99. 33 0
      hsweb-i18n/hsweb-i18n-cn/pom.xml
  100. 0 0
      hsweb-i18n/hsweb-i18n-cn/src/main/resources/messages_zh_CN.properties

+ 98 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authorize.java

@@ -0,0 +1,98 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization;
+
+import java.lang.annotation.*;
+
+/**
+ * 权限注解
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Authorize {
+
+    /**
+     * 对角色授权,当使用按角色授权时,对模块以及操作级别授权方式失效
+     *
+     * @return 进行授权的角色数组
+     */
+    String[] role() default {};
+
+    /**
+     * 对模块授权
+     *
+     * @return 进行授权的模块
+     */
+    String[] module() default {};
+
+    /**
+     * 如增删改查等
+     *
+     * @return
+     */
+    String[] action() default {};
+
+    String[] user() default {};
+
+    String message() default "{unauthorized}";
+
+    /**
+     * 表达式验证
+     *
+     * @return
+     */
+    String expression() default "";
+
+    /**
+     * 表达式语言,默认spring表达式
+     *
+     * @return 表达式语言
+     */
+    String expressionLanguage() default "spel";
+
+    /**
+     * 是否为api接口,为true时,可使用api方式请求。
+     *
+     * @return
+     */
+    boolean api() default false;
+
+    /**
+     * 可匿名访问
+     *
+     * @return 是否可匿名访问, 匿名访问将不用登录
+     */
+    boolean anonymous() default false;
+
+    /**
+     * 是否合并类上的注解
+     *
+     * @return 是否合并类上的注解
+     */
+    boolean merge() default true;
+
+    /**
+     * 验证模式,在使用多个验证条件时有效
+     *
+     * @return
+     */
+    Logical logical() default Logical.OR;
+
+}

+ 30 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Logical.java

@@ -0,0 +1,30 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization;
+
+enum Logical {
+    /**
+     * 并集,需要满足所有验证条件
+     */
+    AND,
+    /**
+     * 交集,满足其中一个验证条件
+     */
+    OR
+}

+ 37 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/UserSubject.java

@@ -0,0 +1,37 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization;
+
+import java.util.Set;
+
+/**
+ * @author zhouhao
+ */
+@Authorize(user = "{data.creatorId}")
+public interface UserSubject {
+
+    String getUsername();
+
+    boolean hasRoles(Set<String> roles);
+
+    boolean hasRole(String... roleId);
+
+    boolean hasModule(String moduleId, String... actions);
+
+}

+ 38 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/UserSubjectUtils.java

@@ -0,0 +1,38 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization;
+
+/**
+ * @author zhouhao
+ */
+public abstract class UserSubjectUtils {
+    private volatile static UserSubjectUtils instance;
+
+    public abstract UserSubject getUser();
+
+    public static UserSubject get() {
+        if (instance == null) return null;
+        return instance.getUser();
+    }
+
+    public synchronized static void setInstance(UserSubjectUtils instance) {
+        if (null == UserSubjectUtils.instance)
+            UserSubjectUtils.instance = instance;
+    }
+}

+ 15 - 0
hsweb-authorization/hsweb-authorization-oauth2/pom.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-authorization</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-authorization-oauth2</artifactId>
+
+
+</project>

+ 53 - 0
hsweb-authorization/hsweb-authorization-shiro/pom.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-authorization</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-authorization-shiro</artifactId>
+
+    <properties>
+        <shiro.version>1.3.2</shiro.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>${parent.groupId}</groupId>
+            <artifactId>hsweb-authorization-api</artifactId>
+            <version>${parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 62 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroUserSubject.java

@@ -0,0 +1,62 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization.shiro;
+
+import org.apache.shiro.subject.Subject;
+import org.hswebframework.web.authorization.UserSubject;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author zhouhao
+ */
+public class ShiroUserSubject implements UserSubject {
+    private Subject subject;
+
+    public ShiroUserSubject(Subject subject) {
+        this.subject = subject;
+    }
+
+    @Override
+    public String getUsername() {
+        return (String) subject.getPrincipal();
+    }
+
+    @Override
+    public boolean hasRoles(Set<String> roles) {
+        return subject.hasAllRoles(roles);
+    }
+
+    @Override
+    public boolean hasRole(String... roleId) {
+        return hasRoles(new HashSet<>(Arrays.asList(roleId)));
+    }
+
+    @Override
+    public boolean hasModule(String moduleId, String... actions) {
+        if (actions.length == 0) return subject.isPermitted(moduleId);
+        String per[] = new String[actions.length];
+        for (int i = 0; i < per.length; i++) {
+            per[i] = moduleId.concat(":").concat(actions[i]);
+        }
+        return subject.isPermittedAll(per);
+    }
+}

+ 38 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroUserSubjectUtils.java

@@ -0,0 +1,38 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization.shiro;
+
+import org.apache.shiro.SecurityUtils;
+import org.hswebframework.web.authorization.UserSubject;
+import org.hswebframework.web.authorization.UserSubjectUtils;
+
+/**
+ * @author zhouhao
+ */
+public class ShiroUserSubjectUtils extends UserSubjectUtils {
+
+    @Override
+    public UserSubject getUser() {
+        return new ShiroUserSubject(SecurityUtils.getSubject());
+    }
+
+    public void bind() {
+        UserSubjectUtils.setInstance(this);
+    }
+}

+ 62 - 0
hsweb-authorization/hsweb-authorization-shiro/src/test/java/org/hswebframework/web/authorization/shiro/ShiroTests.java

@@ -0,0 +1,62 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization.shiro;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.realm.SimpleAccountRealm;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.subject.Subject;
+import org.hswebframework.web.authorization.UserSubjectUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author zhouhao
+ */
+public class ShiroTests {
+
+    @Test
+    public void simpleTest() {
+        DefaultSessionManager sessionManager = new DefaultSessionManager();
+        DefaultSecurityManager securityManager = new DefaultSecurityManager();
+
+        securityManager.setAuthenticator(new ModularRealmAuthenticator());
+        SimpleAccountRealm realm = new SimpleAccountRealm();
+        realm.addAccount("admin", "admin", "admin");
+        securityManager.setRealm(realm);
+        securityManager.setSessionManager(sessionManager);
+        SecurityUtils.setSecurityManager(securityManager);
+        Subject subject = SecurityUtils.getSubject();
+        UsernamePasswordToken token = new UsernamePasswordToken("admin", "admin");
+
+        token.setRememberMe(true);
+        subject.login(token);
+        Assert.assertTrue(subject.isAuthenticated());
+        Assert.assertTrue(subject.hasRole("admin"));
+        Assert.assertFalse(subject.hasRole("test"));
+        new ShiroUserSubjectUtils().bind();
+
+        Assert.assertTrue(UserSubjectUtils.get().hasRole("admin"));
+        Assert.assertEquals(UserSubjectUtils.get().getUsername(), "admin");
+        System.out.println();
+    }
+}

+ 15 - 0
hsweb-authorization/hsweb-authorization-simple/pom.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-authorization</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-authorization-simple</artifactId>
+
+
+</project>

+ 3 - 0
hsweb-authorization/pom.xml

@@ -13,6 +13,9 @@
     <packaging>pom</packaging>
     <modules>
         <module>hsweb-authorization-api</module>
+        <module>hsweb-authorization-oauth2</module>
+        <module>hsweb-authorization-simple</module>
+        <module>hsweb-authorization-shiro</module>
     </modules>
 
 

+ 52 - 0
hsweb-commons/hsweb-commons-beans/pom.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-beans</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hsweb-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-easy-orm-rdb</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 29 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/Bean.java

@@ -0,0 +1,29 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+import java.io.Serializable;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface Bean extends Serializable{
+}

+ 62 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/GenericBean.java

@@ -0,0 +1,62 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface GenericBean<PK> extends Bean {
+    String id = "id";
+
+    String properties = "properties";
+
+    GenericBean<PK> cloneBean();
+
+    PK getId();
+
+    void setId(PK id);
+
+    Map<String, Object> getProperties();
+
+    void setProperties(Map<String, Object> properties);
+
+    default <T> T getProperty(String propertyName, T defaultValue) {
+        Map<String, Object> map = getProperties();
+        if (map == null) return null;
+        return (T) map.getOrDefault(propertyName, defaultValue);
+    }
+
+    default <T> T getProperty(String propertyName) {
+        return getProperty(propertyName, null);
+    }
+
+    default void setProperty(String propertyName, Object value) {
+        Map<String, Object> map = getProperties();
+        if (map == null) {
+            map = new LinkedHashMap<>();
+            setProperties(map);
+        }
+        map.put(propertyName, value);
+    }
+
+}

+ 56 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/PagerResult.java

@@ -0,0 +1,56 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+
+import java.util.List;
+
+public class PagerResult<B> implements Bean {
+    private static final long serialVersionUID = -6171751136953308027L;
+    private int total;
+
+    private List<B> data;
+
+    public PagerResult() {
+    }
+
+    public PagerResult(int total, List<B> data) {
+        this.total = total;
+        this.data = data;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public PagerResult<B> setTotal(int total) {
+        this.total = total;
+        return this;
+    }
+
+    public List<B> getData() {
+        return data;
+    }
+
+    public PagerResult<B> setData(List<B> data) {
+        this.data = data;
+        return this;
+    }
+
+}

+ 38 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SharedBean.java

@@ -0,0 +1,38 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface SharedBean extends Bean {
+
+    String creatorId = "creatorId";
+    String shareCode = "shareCode";
+
+    String getCreatorId();
+
+    SharedBean setCreatorId(String creatorId);
+
+    String getShareCode();
+
+    SharedBean setShareCode(String shareCode);
+}

+ 71 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SimpleGenericBean.java

@@ -0,0 +1,71 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author zhouhao
+ * @since 3.0
+ */
+public abstract class SimpleGenericBean<PK> implements GenericBean<PK> {
+
+    private PK id;
+
+    private Map<String, Object> properties;
+
+    @Override
+    public PK getId() {
+        return this.id;
+    }
+
+    @Override
+    public void setId(PK id) {
+        this.id = id;
+    }
+
+    @Override
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    @Override
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T> T getProperty(String propertyName, T defaultValue) {
+        if (null == properties) return defaultValue;
+        return (T) properties.getOrDefault(propertyName, defaultValue);
+    }
+
+    @Override
+    public <T> T getProperty(String propertyName) {
+        return getProperty(propertyName, null);
+    }
+
+    @Override
+    public void setProperty(String propertyName, Object value) {
+        if (null == properties) properties = new LinkedHashMap<>();
+        properties.put(propertyName, value);
+    }
+}

+ 57 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SimpleSharedBean.java

@@ -0,0 +1,57 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+
+import org.hibernate.validator.constraints.NotBlank;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public abstract class SimpleSharedBean<PK> extends SimpleGenericBean<PK> implements SharedBean {
+    @NotBlank
+    private String creatorId;
+
+    @NotBlank
+    private String shareCode;
+
+    @Override
+    public String getCreatorId() {
+        return creatorId;
+    }
+
+    @Override
+    public SimpleSharedBean<PK> setCreatorId(String creatorId) {
+        this.creatorId = creatorId;
+        return this;
+    }
+
+    @Override
+    public String getShareCode() {
+        return shareCode;
+    }
+
+    @Override
+    public SimpleSharedBean<PK> setShareCode(String shareCode) {
+        this.shareCode = shareCode;
+        return this;
+    }
+}

+ 31 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/SortSupport.java

@@ -0,0 +1,31 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+public interface SortSupport extends Comparable<SortSupport> {
+
+    long getSortIndex();
+
+    SortSupport setSortIndex(long sortIndex);
+
+    default int compareTo(SortSupport support) {
+        if (support == null) return -1;
+        return Long.compare(getSortIndex(), support.getSortIndex());
+    }
+}

+ 95 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/TreeSortSupportBean.java

@@ -0,0 +1,95 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+import org.hswebframework.web.Describe;
+
+/**
+ * 支持树形结构,排序的实体类,要使用树形结构,排序功能的实体类直接继承该类
+ */
+public abstract class TreeSortSupportBean extends SimpleGenericBean<String> implements TreeSupport, SortSupport {
+
+    /**
+     * 父级类别
+     */
+    @Describe("父级类别ID")
+    private String parentId;
+
+    /**
+     * 树结构编码,用于快速查找, 每一层由4位字符组成,用-分割
+     * 如第一层:0001 第二层:0001-0001 第三层:0001-0001-0001
+     */
+    @Describe("树识别码")
+    private String treeCode;
+
+    /**
+     * 排序索引
+     */
+    @Describe("排序索引")
+    private long sortIndex;
+
+    @Override
+    public String getTreeCode() {
+        return treeCode;
+    }
+
+    @Override
+    public void setTreeCode(String treeCode) {
+        this.treeCode = treeCode;
+    }
+
+    @Override
+    public String getParentId() {
+        return parentId;
+    }
+
+    @Override
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    @Override
+    public long getSortIndex() {
+        return sortIndex;
+    }
+
+    @Override
+    public TreeSortSupportBean setSortIndex(long sortIndex) {
+        this.sortIndex = sortIndex;
+        return this;
+    }
+
+    public interface Property {
+        /**
+         * 父级类别
+         */
+        String parentId = "parentId";
+
+        /**
+         * 树结构编码,用于快速查找, 每一层由4位字符组成,用-分割
+         * 如第一层:0001 第二层:0001-0001 第三层:0001-0001-0001
+         */
+        String treeCode = "treeCode";
+
+        /**
+         * 排序索引
+         */
+        String sortIndex = "sortIndex";
+    }
+}

+ 80 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/TreeSupport.java

@@ -0,0 +1,80 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.beans;
+
+
+import org.hswebframework.web.id.IDGenerator;
+import org.hswebframwork.utils.RandomUtil;
+import org.hswebframwork.utils.StringUtils;
+
+import java.util.List;
+
+public interface TreeSupport {
+    String getId();
+
+    void setId(String id);
+
+    String getTreeCode();
+
+    void setTreeCode(String treeCode);
+
+    String getParentId();
+
+    void setParentId(String parentId);
+
+    <T extends TreeSupport> List<T> getChildren();
+
+    static String getParentTreeCode(String treeCode) {
+        if (treeCode == null || treeCode.length() < 4) return null;
+        return treeCode.substring(0, treeCode.length() - 5);
+    }
+
+    /**
+     * 将树形结构转为列表结构,并填充对应的数据。<br>
+     * 如树结构数据: {name:'父节点',children:[{name:'子节点1'},{name:'子节点2'}]}<br>
+     * 解析后:[{id:'id1',name:'父节点',treeCode:'<b>aoSt</b>'},{id:'id2',name:'子节点1',treeCode:'<b>aoSt</b>-oS5a'},{id:'id3',name:'子节点2',treeCode:'<b>aoSt</b>-uGpM'}]
+     *
+     * @param parent 树结构的根节点
+     * @param target 目标集合,转换后的数据将直接添加({@link List#add(Object)})到这个集合.
+     * @param <T>    继承{@link TreeSupport}的类型
+     */
+    static <T extends TreeSupport> void expandTree2List(T parent, List<T> target) {
+        List<T> children = parent.getChildren();
+        if (parent.getTreeCode() == null) {
+            parent.setTreeCode(RandomUtil.randomChar(4));
+        }
+        if (children != null) {
+            String pid = parent.getId();
+            if (pid == null) {
+                pid = IDGenerator.MD5.generate();
+                parent.setId(pid);
+            }
+            for (int i = 0; i < children.size(); i++) {
+                T child = children.get(i);
+                if (child instanceof SortSupport && parent instanceof SortSupport) {
+                    ((SortSupport) child).setSortIndex(StringUtils.toLong(((SortSupport) parent).getSortIndex() + "0" + (i + 1)));
+                }
+                child.setParentId(pid);
+                child.setTreeCode(parent.getTreeCode() + "-" + RandomUtil.randomChar(4));
+                target.add(child);
+                expandTree2List(child, target);
+            }
+        }
+    }
+}

+ 18 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/dsl/QueryBean.java

@@ -0,0 +1,18 @@
+package org.hswebframework.web.commons.beans.dsl;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface QueryBean<T extends QueryBean> extends Bean {
+
+
+    T like(Object value);
+
+    T gt(Object value);
+
+
+}

+ 33 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/factory/BeanFactory.java

@@ -0,0 +1,33 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *  
+ */
+
+package org.hswebframework.web.commons.beans.factory;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface BeanFactory {
+    <T extends Bean> T getInstance(Class<T> beanClass);
+
+    <T extends Bean> Class<T> getRealType(Class<T> beanClass);
+}

+ 68 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/factory/MapperBeanFactory.java

@@ -0,0 +1,68 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *  
+ */
+
+package org.hswebframework.web.commons.beans.factory;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public class MapperBeanFactory implements BeanFactory {
+    private Map<Class, Class> realTypeMapper = new HashMap<>();
+
+    @Override
+    public <T extends Bean> T getInstance(Class<T> beanClass) {
+        Class<T> realType = getRealType(beanClass);
+        if (realType == null) {
+            if (!Modifier.isInterface(beanClass.getModifiers()) && !Modifier.isAbstract(beanClass.getModifiers())) {
+                realType = beanClass;
+            }
+        }
+        //尝试使用 Simple类,如: package.SimpleUserBean
+        if (realType == null) {
+            String simpleClassName = beanClass.getPackage().getName().concat(".Simple").concat(beanClass.getSimpleName());
+            try {
+                realType = (Class<T>) Class.forName(simpleClassName);
+                realTypeMapper.put(beanClass, realType);
+            } catch (ClassNotFoundException e) {
+            }
+        }
+        if (realType != null) {
+            try {
+                return realType.newInstance();
+            } catch (Exception e) {
+                throw new RuntimeException("{create_bean_error}", e);
+            }
+        } else {
+            throw new UnsupportedOperationException("{create_bean_error}:realType not found!");
+        }
+    }
+
+    @Override
+    public <T extends Bean> Class<T> getRealType(Class<T> beanClass) {
+        return realTypeMapper.get(beanClass);
+    }
+}

+ 12 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/param/DeleteParamBean.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.commons.beans.param;
+
+import org.hsweb.ezorm.core.param.Param;
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class DeleteParamBean extends Param implements Bean {
+}

+ 12 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/param/QueryParamBean.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.commons.beans.param;
+
+import org.hsweb.ezorm.core.param.QueryParam;
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class QueryParamBean extends QueryParam implements Bean {
+}

+ 18 - 0
hsweb-commons/hsweb-commons-beans/src/main/java/org/hswebframework/web/commons/beans/param/UpdateParamBean.java

@@ -0,0 +1,18 @@
+package org.hswebframework.web.commons.beans.param;
+
+import org.hsweb.ezorm.core.param.UpdateParam;
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class UpdateParamBean<T> extends UpdateParam<T> implements Bean {
+    public UpdateParamBean() {
+    }
+
+    public UpdateParamBean(T data) {
+        super(data);
+    }
+}

+ 33 - 0
hsweb-commons/hsweb-commons-beans/src/test/java/org/hswebframework/web/commons/beans/QueryBeanTests.java

@@ -0,0 +1,33 @@
+package org.hswebframework.web.commons.beans;
+
+import org.hswebframework.web.commons.beans.dsl.QueryBean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class QueryBeanTests {
+
+    public static void main(String[] args) {
+
+
+    }
+}
+
+class TestQuery implements QueryBean<TestQuery> {
+
+    public final TestQuery name = new TestQuery();
+    public final TestQuery age = new TestQuery();
+
+
+    @Override
+    public TestQuery like(Object value) {
+        return null;
+    }
+
+    @Override
+    public TestQuery gt(Object value) {
+        return null;
+    }
+}

+ 61 - 0
hsweb-commons/hsweb-commons-controller/pom.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-controller</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-service-simple</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-easy-orm-rdb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-logging</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-authorization-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 74 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CrudController.java

@@ -0,0 +1,74 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.authorization.Authorize;
+import org.hswebframework.web.commons.beans.Bean;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.CrudService;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import static org.hswebframework.web.controller.message.ResponseMessage.ok;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface CrudController<B, PK, Q extends Bean> {
+
+    CrudService<B, PK, Q> getService();
+
+    @Authorize(action = "read")
+    @GetMapping
+    @AccessLogger("查询")
+    default ResponseMessage list(Q param) {
+        return ok(getService().selectPager(param));
+    }
+
+    @Authorize(action = "read")
+    @GetMapping(path = "/{id}")
+    @AccessLogger("根据主键查询")
+    default ResponseMessage getByPrimaryKey(PK id) {
+        return ok(getService().selectByPk(id));
+    }
+
+    @Authorize(action = "update")
+    @PutMapping(path = "/{id}")
+    @AccessLogger("根据主键修改数据")
+    ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody B data);
+
+    @Authorize(action = "delete")
+    @DeleteMapping(path = "/{id}")
+    @AccessLogger("根据主键删除数据")
+    default ResponseMessage deleteByPrimaryKey(@PathVariable PK id) {
+        return ok(getService().deleteByPk(id));
+    }
+
+    @Authorize(action = "add")
+    @PostMapping
+    @AccessLogger("添加数据")
+    @ResponseStatus(HttpStatus.CREATED)
+    default ResponseMessage add(@RequestBody B data) {
+        return ok(getService().insert(data));
+    }
+
+}

+ 46 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericBeanController.java

@@ -0,0 +1,46 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.commons.beans.Bean;
+import org.hswebframework.web.commons.beans.GenericBean;
+import org.hswebframework.web.commons.beans.param.QueryParamBean;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.service.CrudService;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import static org.hswebframework.web.controller.message.ResponseMessage.ok;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface GenericBeanController<B extends GenericBean<PK>, PK, Q extends Bean>
+        extends CrudController<B, PK, Q> {
+
+    CrudService<B, PK, Q> getService();
+
+    @Override
+    default ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody B data) {
+        data.setId(id);
+        return ok(getService().updateByPk(data));
+    }
+}

+ 260 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java

@@ -0,0 +1,260 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller.message;
+
+
+import com.alibaba.fastjson.JSON;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * 响应消息。controller中处理后,返回此对象,响应请求结果给客户端。
+ */
+public class ResponseMessage implements Serializable {
+    private static final long serialVersionUID = 8992436576262574064L;
+
+    /**
+     * 反馈数据
+     */
+    private Object data;
+
+    /**
+     * 反馈信息
+     */
+    private String message;
+
+    /**
+     * 响应码
+     */
+    private int code;
+
+    /**
+     * 过滤字段:指定需要序列化的字段
+     */
+    private transient Map<Class<?>, Set<String>> includes;
+
+    /**
+     * 过滤字段:指定不需要序列化的字段
+     */
+    private transient Map<Class<?>, Set<String>> excludes;
+
+    private transient boolean onlyData;
+
+    private transient String callback;
+
+    public Map<String, Object> toMap() {
+        Map<String, Object> map = new HashMap<>();
+        if (data != null)
+            map.put("data", this.getData());
+        if (message != null)
+            map.put("message", this.getMessage());
+        map.put("code", this.getCode());
+        return map;
+    }
+
+    protected ResponseMessage() {
+    }
+
+
+    public ResponseMessage include(Class<?> type, String... fields) {
+        return include(type, Arrays.asList(fields));
+    }
+
+    public ResponseMessage include(Class<?> type, Collection<String> fields) {
+        if (includes == null)
+            includes = new HashMap<>();
+        if (fields == null || fields.isEmpty()) return this;
+        fields.forEach(field -> {
+            if (field.contains(".")) {
+                String tmp[] = field.split("[.]", 2);
+                try {
+                    Field field1 = type.getDeclaredField(tmp[0]);
+                    if (field1 != null) {
+                        include(field1.getType(), tmp[1]);
+                    }
+                } catch (Throwable e) {
+                }
+            } else {
+                getStringListFormMap(includes, type).add(field);
+            }
+        });
+        return this;
+    }
+
+    public ResponseMessage exclude(Class type, Collection<String> fields) {
+        if (excludes == null)
+            excludes = new HashMap<>();
+        if (fields == null || fields.isEmpty()) return this;
+        fields.forEach(field -> {
+            if (field.contains(".")) {
+                String tmp[] = field.split("[.]", 2);
+                try {
+                    Field field1 = type.getDeclaredField(tmp[0]);
+                    if (field1 != null) {
+                        exclude(field1.getType(), tmp[1]);
+                    }
+                } catch (Throwable e) {
+                }
+            } else {
+                getStringListFormMap(excludes, type).add(field);
+            }
+        });
+        return this;
+    }
+
+    public ResponseMessage exclude(Collection<String> fields) {
+        if (excludes == null)
+            excludes = new HashMap<>();
+        if (fields == null || fields.isEmpty()) return this;
+        Class type;
+        if (data != null) type = data.getClass();
+        else return this;
+        exclude(type, fields);
+        return this;
+    }
+
+    public ResponseMessage include(Collection<String> fields) {
+        if (includes == null)
+            includes = new HashMap<>();
+        if (fields == null || fields.isEmpty()) return this;
+        Class type;
+        if (data != null) type = data.getClass();
+        else return this;
+        include(type, fields);
+        return this;
+    }
+
+    public ResponseMessage exclude(Class type, String... fields) {
+        return exclude(type, Arrays.asList(fields));
+    }
+
+    public ResponseMessage exclude(String... fields) {
+        return exclude(Arrays.asList(fields));
+    }
+
+    public ResponseMessage include(String... fields) {
+        return include(Arrays.asList(fields));
+    }
+
+    protected Set<String> getStringListFormMap(Map<Class<?>, Set<String>> map, Class type) {
+        Set<String> list = map.get(type);
+        if (list == null) {
+            list = new HashSet<>();
+            map.put(type, list);
+        }
+        return list;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public ResponseMessage setData(Object data) {
+        this.data = data;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return JSON.toJSONStringWithDateFormat(this, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public ResponseMessage setCode(int code) {
+        this.code = code;
+        return this;
+    }
+
+    public static ResponseMessage fromJson(String json) {
+        return JSON.parseObject(json, ResponseMessage.class);
+    }
+
+    public Map<Class<?>, Set<String>> getExcludes() {
+        return excludes;
+    }
+
+    public Map<Class<?>, Set<String>> getIncludes() {
+        return includes;
+    }
+
+    public ResponseMessage onlyData() {
+        setOnlyData(true);
+        return this;
+    }
+
+    public void setOnlyData(boolean onlyData) {
+        this.onlyData = onlyData;
+    }
+
+    public boolean isOnlyData() {
+        return onlyData;
+    }
+
+    public ResponseMessage callback(String callback) {
+        this.callback = callback;
+        return this;
+    }
+
+    public String getCallback() {
+        return callback;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public static ResponseMessage ok() {
+        return ok(null);
+    }
+
+    public static ResponseMessage ok(Object data) {
+        ResponseMessage message = new ResponseMessage();
+        message.setCode(200);
+        message.setData(data);
+        return message;
+    }
+
+    public static ResponseMessage created(Object data) {
+        ResponseMessage message = new ResponseMessage();
+        message.setCode(201);
+        message.setData(data);
+        return message;
+    }
+
+    public static ResponseMessage error(String message) {
+        return error(message, 500);
+    }
+
+    public static ResponseMessage error(String message, int code) {
+        ResponseMessage response = new ResponseMessage();
+        response.setCode(code);
+        response.setData(message);
+        return response;
+    }
+
+}

+ 44 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/pom.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons-dao</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-dao-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-beans</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 36 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/CrudDao.java

@@ -0,0 +1,36 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao;
+
+import org.hswebframework.web.dao.dynamic.UpdateByBeanDao;
+import org.hswebframework.web.dao.dynamic.DeleteByBeanDao;
+import org.hswebframework.web.dao.dynamic.QueryByBeanDao;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface CrudDao<PO, PK> extends
+        InsertDao<PO>,
+        DeleteDao<PK>,
+        DeleteByBeanDao,
+        UpdateByBeanDao,
+        QueryByBeanDao<PO> {
+}

+ 27 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/Dao.java

@@ -0,0 +1,27 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface Dao {
+}

+ 29 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/DeleteDao.java

@@ -0,0 +1,29 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface DeleteDao<PK> extends Dao{
+    int deleteByPk(PK pk);
+}

+ 29 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/InsertDao.java

@@ -0,0 +1,29 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao;
+
+/**
+ * TODO  完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface InsertDao<PO> extends Dao {
+    void insert(PO po);
+}

+ 91 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DataSourceHolder.java

@@ -0,0 +1,91 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.datasource;
+
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class DataSourceHolder {
+
+    private static DynamicDataSource dynamicDataSource;
+
+    private static DataSource defaultDataSource;
+
+    private static DatabaseType defaultDatabaseType;
+
+    public void init(DataSource dataSource) throws SQLException {
+        if (null != dataSource) {
+            Connection connection = null;
+            try {
+                connection = dataSource.getConnection();
+                install(dataSource, DatabaseType.fromJdbcUrl(connection.getMetaData().getURL()));
+            } finally {
+                if (null != connection)
+                    connection.close();
+            }
+        }
+    }
+
+    public static DataSource getActiveSource() {
+        if (dynamicDataSource != null) {
+            return dynamicDataSource.getActiveDataSource();
+        }
+        return defaultDataSource;
+    }
+
+    public static String getActiveSourceId() {
+        if (DynamicDataSource.getActiveDataSourceId() != null) {
+            return DynamicDataSource.getActiveDataSourceId();
+        }
+        return "default";
+    }
+
+
+    public static DatabaseType getActiveDatabaseType() {
+        if (dynamicDataSource != null) {
+            return dynamicDataSource.getActiveDataBaseType();
+        }
+        return defaultDatabaseType;
+    }
+
+    public static DataSource getDefaultDataSource() {
+        return defaultDataSource;
+    }
+
+    public static DatabaseType getDefaultDatabaseType() {
+        return defaultDatabaseType;
+    }
+
+    public static void install(DynamicDataSource dynamicDataSource) {
+        if (DataSourceHolder.dynamicDataSource != null) {
+            throw new UnsupportedOperationException();
+        }
+        DataSourceHolder.dynamicDataSource = dynamicDataSource;
+    }
+
+    public static void install(DataSource dataSource, DatabaseType databaseType) {
+        if (DataSourceHolder.defaultDataSource != null) {
+           return;
+        }
+        DataSourceHolder.defaultDataSource = dataSource;
+        DataSourceHolder.defaultDatabaseType = databaseType;
+    }
+}

+ 76 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DatabaseType.java

@@ -0,0 +1,76 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.datasource;
+
+import org.hsweb.ezorm.rdb.render.dialect.Dialect;
+import org.hswebframwork.utils.StringUtils;
+
+public enum DatabaseType {
+    unknown(null, null, null, null),
+    mysql("com.mysql.jdbc.Driver", "com.mysql.jdbc.jdbc2.optional.MysqlXADataSource", "select 1", Dialect.MYSQL),
+    h2("org.h2.Driver", "org.h2.jdbcx.JdbcDataSource", "select 1", Dialect.H2),
+    oracle("oracle.jdbc.driver.OracleDriver", "oracle.jdbc.xa.client.OracleXADataSource", "select 1 from dual", Dialect.ORACLE);
+
+    DatabaseType(String driverClassName, String xaDataSourceClassName, String testQuery, Dialect dialect) {
+        this.driverClassName = driverClassName;
+        this.testQuery = testQuery;
+        this.xaDataSourceClassName = xaDataSourceClassName;
+        this.dialect = dialect;
+    }
+
+    private final String testQuery;
+
+    private final String driverClassName;
+
+    private final String xaDataSourceClassName;
+
+    private final Dialect dialect;
+
+    public String getDriverClassName() {
+        return driverClassName;
+    }
+
+    public String getXaDataSourceClassName() {
+        return xaDataSourceClassName;
+    }
+
+    public String getTestQuery() {
+        return testQuery;
+    }
+
+    public Dialect getDialect() {
+        return dialect;
+    }
+
+    public static DatabaseType fromJdbcUrl(String url) {
+        if (!StringUtils.isNullOrEmpty(url)) {
+            if (!url.trim().startsWith("jdbc")) {
+                throw new UnsupportedOperationException("URL must start with 'jdbc'");
+            }
+            String urlWithoutPrefix = url.substring("jdbc".length()).toLowerCase();
+            for (DatabaseType driver : values()) {
+                String prefix = ":" + driver.name().toLowerCase() + ":";
+                if (driver != unknown && urlWithoutPrefix.startsWith(prefix)) {
+                    return driver;
+                }
+            }
+        }
+        return unknown;
+    }
+}

+ 95 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/datasource/DynamicDataSource.java

@@ -0,0 +1,95 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.datasource;
+
+
+import org.hswebframework.web.ThreadLocalUtils;
+
+import javax.sql.DataSource;
+
+/**
+ * 动态数据源接口,此接口实现多数据源的动态切换
+ *
+ * @see DataSourceHolder
+ */
+public interface DynamicDataSource extends DataSource {
+    String DATA_SOURCE_FLAG = "data-source-id";
+
+    String DATA_SOURCE_FLAG_LAST = "data-source-id-last";
+
+    /**
+     * 使用上一次调用的数据源
+     */
+    static void useLast() {
+        use(ThreadLocalUtils.get(DATA_SOURCE_FLAG_LAST));
+    }
+
+    /**
+     * 选中参数(数据源ID)对应的数据源,如果数据源不存在,将使用默认数据源
+     *
+     * @param dataSourceId 数据源ID
+     */
+    static void use(String dataSourceId) {
+        ThreadLocalUtils.put(DATA_SOURCE_FLAG, dataSourceId);
+    }
+
+    /**
+     * 获取当前使用的数据源ID,如果不存在则返回null
+     *
+     * @return 数据源ID
+     */
+    static String getActiveDataSourceId() {
+        return ThreadLocalUtils.get(DATA_SOURCE_FLAG);
+    }
+
+    /**
+     * 切换为默认数据源,并指定是否记住上一次选中的数据源
+     *
+     * @param rememberLast 是否记住上一次选中的数据源
+     */
+    static void useDefault(boolean rememberLast) {
+        if (getActiveDataSourceId() != null && rememberLast)
+            ThreadLocalUtils.put(DATA_SOURCE_FLAG_LAST, getActiveDataSourceId());
+        ThreadLocalUtils.remove(DATA_SOURCE_FLAG);
+    }
+
+    /**
+     * 切换为默认数据源并记住上一次使用的数据源
+     *
+     * @see this#useDefault(boolean)
+     */
+    static void useDefault() {
+        useDefault(true);
+    }
+
+    /**
+     * 获取当前激活的数据源
+     *
+     * @return
+     */
+    DataSource getActiveDataSource();
+
+    /**
+     * 获取当前激活数据源的数据库类型
+     *
+     * @return 数据库类型
+     * @see DatabaseType
+     */
+    DatabaseType getActiveDataBaseType();
+}

+ 31 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/dynamic/DeleteByBeanDao.java

@@ -0,0 +1,31 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.dynamic;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO  完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface DeleteByBeanDao {
+    int delete(Bean bean);
+}

+ 35 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/dynamic/QueryByBeanDao.java

@@ -0,0 +1,35 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.dynamic;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+import java.util.List;
+
+/**
+ * TODO  完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface QueryByBeanDao<PO> {
+    List<PO> query(Bean queryBean);
+
+    int count(Bean queryBean);
+}

+ 31 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-api/src/main/java/org/hswebframework/web/dao/dynamic/UpdateByBeanDao.java

@@ -0,0 +1,31 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.dynamic;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * TODO  完成注释
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface UpdateByBeanDao {
+    int update(Bean bean);
+}

+ 50 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/pom.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons-dao</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-dao-mybatis</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-dao-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 105 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MyBatisAutoConfiguration.java

@@ -0,0 +1,105 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis;
+
+import org.apache.ibatis.mapping.DatabaseIdProvider;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.TransactionIsolationLevel;
+import org.apache.ibatis.transaction.Transaction;
+import org.hswebframework.web.dao.mybatis.dynamic.DynamicDataSourceSqlSessionFactoryBuilder;
+import org.hswebframework.web.dao.mybatis.dynamic.DynamicSpringManagedTransaction;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
+import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
+import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+
+@Configuration
+@EnableConfigurationProperties(MybatisProperties.class)
+@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
+public class MyBatisAutoConfiguration {
+
+    @Resource
+    private MybatisProperties mybatisProperties;
+
+    @Autowired(required = false)
+    private Interceptor[] interceptors;
+
+    @Autowired
+    private ResourceLoader resourceLoader = new DefaultResourceLoader();
+
+    @Autowired(required = false)
+    private DatabaseIdProvider databaseIdProvider;
+
+    @Bean
+    @Primary
+    @ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
+    public MybatisProperties mybatisProperties() {
+        return new MybatisProperties();
+    }
+
+    @Bean(name = "sqlSessionFactory")
+    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
+        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
+        factory.setVfs(SpringBootVFS.class);
+        if (mybatisProperties.isDynamicDatasource()) {
+            factory.setSqlSessionFactoryBuilder(new DynamicDataSourceSqlSessionFactoryBuilder());
+            factory.setTransactionFactory(new SpringManagedTransactionFactory() {
+                @Override
+                public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) {
+                    return new DynamicSpringManagedTransaction();
+                }
+            });
+        }
+        factory.setDataSource(dataSource);
+        if (StringUtils.hasText(this.mybatisProperties.getConfigLocation())) {
+            factory.setConfigLocation(this.resourceLoader.getResource(this.mybatisProperties
+                    .getConfigLocation()));
+        }
+        if (this.interceptors != null && this.interceptors.length > 0) {
+            factory.setPlugins(this.interceptors);
+        }
+        if (this.databaseIdProvider != null) {
+            factory.setDatabaseIdProvider(this.databaseIdProvider);
+        }
+        factory.setTypeAliasesPackage(this.mybatisProperties.getTypeAliasesPackage());
+        String typeHandlers = "org.hswebframework.web.dao.mybatis.handler";
+        if (this.mybatisProperties.getTypeHandlersPackage() != null) {
+            typeHandlers = typeHandlers + ";" + this.mybatisProperties.getTypeHandlersPackage();
+        }
+        factory.setTypeHandlersPackage(typeHandlers);
+        factory.setMapperLocations(this.mybatisProperties.resolveMapperLocations());
+        return factory.getObject();
+    }
+
+}

+ 47 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MybatisDaoAutoConfiguration.java

@@ -0,0 +1,47 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis;
+
+import org.hswebframework.web.dao.Dao;
+import org.hswebframework.web.dao.mybatis.utils.ResultMapsUtils;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+
+@Configuration
+@ComponentScan("org.hswebframework.web.dao.mybatis")
+@MapperScan(value = "org.hswebframework.web.dao", markerInterface = Dao.class)
+@AutoConfigureAfter(MyBatisAutoConfiguration.class)
+@EnableConfigurationProperties(MybatisProperties.class)
+public class MybatisDaoAutoConfiguration {
+
+    @Autowired
+    private SqlSessionTemplate sqlSessionTemplate;
+
+    @PostConstruct
+    public void init() {
+        ResultMapsUtils.setSqlSession(sqlSessionTemplate);
+    }
+}

+ 110 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MybatisProperties.java

@@ -0,0 +1,110 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * mybatis配置,继承官方配置类,增加一些属性以拓展更多功能
+ * <ul>
+ * <li>是否启用动态数据源{@link this#dynamicDatasource}</li>
+ * <li>可设置不加载的配置{@link this#mapperLocationExcludes}</li>
+ * </ul>
+ *
+ * @author zhouhao
+ * @see org.mybatis.spring.boot.autoconfigure.MybatisProperties
+ * @since 3.0
+ */
+public class MybatisProperties extends org.mybatis.spring.boot.autoconfigure.MybatisProperties {
+    /**
+     * 默认支持的hsweb mapper
+     */
+    private static final String   defaultMapperLocation  = "classpath*:org/hswebframework/web/dao/mybatis/mappers/**/*.xml";
+    /**
+     * 是否启用动态数据源
+     * 启用后调用{@link org.hswebframework.web.dao.datasource.DynamicDataSource#use(String)},mybatis也会进行数据源切换
+     *
+     * @see org.hswebframework.web.dao.datasource.DynamicDataSource
+     */
+    private              boolean  dynamicDatasource      = false;
+    /**
+     * 排除加载的mapper.xml
+     * 想自定义mapper并覆盖原始mapper的场景下,通过设置此属性来排除配置文件。
+     * 排除使用{@link Resource#getURL()#toString()}进行对比
+     */
+    private              String[] mapperLocationExcludes = null;
+
+    public String[] getMapperLocationExcludes() {
+        return mapperLocationExcludes;
+    }
+
+    public void setMapperLocationExcludes(String[] mapperLocationExcludes) {
+        this.mapperLocationExcludes = mapperLocationExcludes;
+    }
+
+    public boolean isDynamicDatasource() {
+        return dynamicDatasource;
+    }
+
+    public void setDynamicDatasource(boolean dynamicDatasource) {
+        this.dynamicDatasource = dynamicDatasource;
+    }
+
+    public Resource[] resolveMapperLocations() {
+        Map<String, Resource> resources = new HashMap<>();
+        Set<String> locations;
+
+        if (this.getMapperLocations() == null)
+            locations = new HashSet<>();
+        else
+            locations = Arrays.stream(getMapperLocations()).collect(Collectors.toSet());
+        locations.add(defaultMapperLocation);
+        for (String mapperLocation : locations) {
+            Resource[] mappers;
+            try {
+                mappers = new PathMatchingResourcePatternResolver().getResources(mapperLocation);
+                for (Resource mapper : mappers) {
+                    resources.put(mapper.getURL().toString(), mapper);
+                }
+            } catch (IOException e) {
+            }
+        }
+        //排除不需要的配置
+        if (mapperLocationExcludes != null && mapperLocationExcludes.length > 0) {
+            for (String mapperLocationExclude : mapperLocationExcludes) {
+                try {
+                    Resource[] excludesMappers = new PathMatchingResourcePatternResolver().getResources(mapperLocationExclude);
+                    for (Resource excludesMapper : excludesMappers) {
+                        resources.remove(excludesMapper.getURL().toString());
+                    }
+                } catch (IOException e) {
+                }
+            }
+        }
+        Resource[] mapperLocations = new Resource[resources.size()];
+        mapperLocations = resources.values().toArray(mapperLocations);
+        return mapperLocations;
+    }
+
+}

+ 304 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -0,0 +1,304 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.builder;
+
+import org.apache.commons.beanutils.BeanUtilsBean;
+import org.apache.commons.beanutils.PropertyUtilsBean;
+import org.apache.ibatis.mapping.ResultMap;
+import org.apache.ibatis.mapping.ResultMapping;
+import org.hsweb.ezorm.core.param.InsertParam;
+import org.hsweb.ezorm.core.param.QueryParam;
+import org.hsweb.ezorm.core.param.Term;
+import org.hsweb.ezorm.core.param.UpdateParam;
+import org.hsweb.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hsweb.ezorm.rdb.meta.RDBDatabaseMetaData;
+import org.hsweb.ezorm.rdb.meta.RDBTableMetaData;
+import org.hsweb.ezorm.rdb.render.SqlAppender;
+import org.hsweb.ezorm.rdb.render.SqlRender;
+import org.hsweb.ezorm.rdb.render.dialect.Dialect;
+import org.hsweb.ezorm.rdb.render.dialect.H2RDBDatabaseMetaData;
+import org.hsweb.ezorm.rdb.render.dialect.MysqlRDBDatabaseMetaData;
+import org.hsweb.ezorm.rdb.render.dialect.OracleRDBDatabaseMetaData;
+import org.hsweb.ezorm.rdb.render.support.simple.CommonSqlRender;
+import org.hsweb.ezorm.rdb.render.support.simple.SimpleWhereSqlBuilder;
+import org.hswebframework.web.BusinessException;
+import org.hswebframework.web.dao.datasource.DataSourceHolder;
+import org.hswebframework.web.dao.datasource.DatabaseType;
+import org.hswebframework.web.dao.mybatis.plgins.pager.Pager;
+import org.hswebframework.web.dao.mybatis.utils.ResultMapsUtils;
+import org.hswebframwork.utils.StringUtils;
+
+import java.sql.JDBCType;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author zhouhao
+ * @TODO
+ */
+public class EasyOrmSqlBuilder {
+
+    private static final   EasyOrmSqlBuilder  instance   = new EasyOrmSqlBuilder();
+    protected static final Map<Class, String> simpleName = new HashMap<>();
+
+    protected PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance().getPropertyUtils();
+
+    public static EasyOrmSqlBuilder getInstance() {
+        return instance;
+    }
+
+    private EasyOrmSqlBuilder() {
+    }
+
+    static {
+        simpleName.put(Integer.class, "int");
+        simpleName.put(Byte.class, "byte");
+        simpleName.put(Double.class, "double");
+        simpleName.put(Float.class, "float");
+        simpleName.put(Boolean.class, "boolean");
+        simpleName.put(Long.class, "long");
+        simpleName.put(Short.class, "short");
+        simpleName.put(Character.class, "char");
+        simpleName.put(String.class, "string");
+        simpleName.put(int.class, "int");
+        simpleName.put(double.class, "double");
+        simpleName.put(float.class, "float");
+        simpleName.put(boolean.class, "boolean");
+        simpleName.put(long.class, "long");
+        simpleName.put(short.class, "short");
+        simpleName.put(char.class, "char");
+        simpleName.put(byte.class, "byte");
+    }
+
+    public static String getJavaType(Class type) {
+        String javaType = simpleName.get(type);
+        if (javaType == null) javaType = type.getName();
+        return javaType;
+    }
+
+    private final RDBDatabaseMetaData mysql  = new MysqlMeta();
+    private final RDBDatabaseMetaData oracle = new OracleMeta();
+    private final RDBDatabaseMetaData h2     = new H2Meta();
+
+    private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>>() {
+        @Override
+        public Map<String, RDBTableMetaData> get(Object key) {
+            Map<String, RDBTableMetaData> map = super.get(key);
+            if (map == null) {
+                map = new HashMap<>();
+                put((RDBDatabaseMetaData) key, map);
+            }
+            return map;
+        }
+    };
+
+    public RDBDatabaseMetaData getActiveDatabase() {
+        DatabaseType type = DataSourceHolder.getActiveDatabaseType();
+        switch (type) {
+            case h2:
+                return h2;
+            case mysql:
+                return mysql;
+            case oracle:
+                return oracle;
+            default:
+                return h2;
+        }
+    }
+
+    protected RDBTableMetaData createMeta(String tableName, String resultMapId) {
+        RDBDatabaseMetaData active = getActiveDatabase();
+        String cacheKey = tableName.concat("-").concat(resultMapId);
+        Map<String, RDBTableMetaData> cache = metaCache.get(active);
+        RDBTableMetaData cached = cache.get(cacheKey);
+        if (cached != null) {
+            return cached;
+        }
+        RDBTableMetaData rdbTableMetaData = new RDBTableMetaData();
+        rdbTableMetaData.setName(tableName);
+        rdbTableMetaData.setDatabaseMetaData(active);
+        ResultMap resultMaps = ResultMapsUtils.getResultMap(resultMapId);
+        List<ResultMapping> resultMappings = new ArrayList<>(resultMaps.getResultMappings());
+        resultMappings.addAll(resultMaps.getIdResultMappings());
+        resultMappings.forEach(resultMapping -> {
+            if (resultMapping.getNestedQueryId() == null) {
+                RDBColumnMetaData column = new RDBColumnMetaData();
+                column.setJdbcType(JDBCType.valueOf(resultMapping.getJdbcType().name()));
+                column.setName(resultMapping.getColumn());
+                if (!StringUtils.isNullOrEmpty(resultMapping.getProperty()))
+                    column.setAlias(resultMapping.getProperty());
+                column.setJavaType(resultMapping.getJavaType());
+                column.setProperty("resultMapping", resultMapping);
+                rdbTableMetaData.addColumn(column);
+            }
+        });
+        cache.put(cacheKey, rdbTableMetaData);
+        return rdbTableMetaData;
+    }
+
+    public String buildUpdateFields(String resultMapId, String tableName, UpdateParam param) {
+        Pager.reset();
+        param.excludes("id");
+        RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
+        RDBDatabaseMetaData databaseMetaDate = getActiveDatabase();
+        Dialect dialect = databaseMetaDate.getDialect();
+        CommonSqlRender render = (CommonSqlRender) databaseMetaDate.getRenderer(SqlRender.TYPE.SELECT);
+        List<CommonSqlRender.OperationColumn> columns = render.parseOperationField(tableMetaData, param);
+        SqlAppender appender = new SqlAppender();
+        columns.forEach(column -> {
+            RDBColumnMetaData columnMetaData = column.getRDBColumnMetaData();
+            if (columnMetaData.getName().contains(".")) return;
+            if (columnMetaData == null) return;
+            try {
+                Object tmp = propertyUtils.getProperty(param.getData(), columnMetaData.getAlias());
+                if (tmp == null) return;
+            } catch (Exception e) {
+                return;
+            }
+            appender.add(",", encodeColumn(dialect, columnMetaData.getName())
+                    , "=", "#{data.", columnMetaData.getAlias(),
+                    ",javaType=", EasyOrmSqlBuilder.getJavaType(columnMetaData.getJavaType()),
+                    ",jdbcType=", columnMetaData.getJdbcType(),
+                    "}");
+        });
+        if (!appender.isEmpty()) appender.removeFirst();
+        return appender.toString();
+    }
+
+    public String encodeColumn(Dialect dialect, String field) {
+        if (field.contains(".")) {
+            String[] tmp = field.split("[.]");
+            return tmp[0] + "." + dialect.getQuoteStart() + (dialect.columnToUpperCase() ? (tmp[1].toUpperCase()) : tmp[1]) + dialect.getQuoteEnd();
+        } else {
+            return dialect.getQuoteStart() + (dialect.columnToUpperCase() ? (field.toUpperCase()) : field) + dialect.getQuoteEnd();
+        }
+    }
+
+    public String buildInsertSql(String resultMapId, String tableName, Object param) {
+        Pager.reset();
+        InsertParam insertParam;
+        if (param instanceof InsertParam)
+            insertParam = ((InsertParam) param);
+        else
+            insertParam = new InsertParam<>(param);
+        RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
+        SqlRender<InsertParam> render = tableMetaData.getDatabaseMetaData().getRenderer(SqlRender.TYPE.INSERT);
+        String sql = render.render(tableMetaData, insertParam).getSql();
+        return sql;
+    }
+
+    public String buildUpdateSql(String resultMapId, String tableName, UpdateParam param) {
+        Pager.reset();
+        RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
+        SqlRender<UpdateParam> render = tableMetaData.getDatabaseMetaData().getRenderer(SqlRender.TYPE.UPDATE);
+        return render.render(tableMetaData, param).getSql();
+    }
+
+    public String buildSelectFields(String resultMapId, String tableName, QueryParam param) {
+        if (param.isPaging() && Pager.get() == null) {
+            Pager.doPaging(param.getPageIndex(), param.getPageSize());
+        }
+        RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
+        RDBDatabaseMetaData databaseMetaDate = getActiveDatabase();
+        Dialect dialect = databaseMetaDate.getDialect();
+        CommonSqlRender render = (CommonSqlRender) databaseMetaDate.getRenderer(SqlRender.TYPE.SELECT);
+        List<CommonSqlRender.OperationColumn> columns = render.parseOperationField(tableMetaData, param);
+        SqlAppender appender = new SqlAppender();
+        columns.forEach(column -> {
+            RDBColumnMetaData columnMetaData = column.getRDBColumnMetaData();
+            if (columnMetaData == null) return;
+            String cname = columnMetaData.getName();
+            if (!cname.contains(".")) cname = tableName.concat(".").concat(cname);
+            appender.add(",", encodeColumn(dialect, cname)
+                    , " AS "
+                    , dialect.getQuoteStart()
+                    , columnMetaData.getName()
+                    , dialect.getQuoteEnd());
+        });
+        param.getIncludes().remove("*");
+        if (appender.isEmpty()) return "*";
+        appender.removeFirst();
+        return appender.toString();
+    }
+
+    public String buildOrder(String resultMapId, String tableName, QueryParam param) {
+        RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
+        SqlAppender appender = new SqlAppender(" order by ");
+        param.getSorts().stream()
+                .forEach(sort -> {
+                    RDBColumnMetaData column = tableMetaData.getColumn(sort.getName());
+                    if (column == null)
+                        column = tableMetaData.findColumn(sort.getName());
+                    if (column == null) return;
+                    String cname = column.getName();
+                    if (!cname.contains(".")) cname = tableName.concat(".").concat(cname);
+                    appender.add(encodeColumn(tableMetaData.getDatabaseMetaData().getDialect(), cname), " ", sort.getOrder(), ",");
+                });
+        if (appender.isEmpty()) return "";
+        appender.removeLast();
+        return appender.toString();
+    }
+
+    public String buildWhereForUpdate(String resultMapId, String tableName, List<Term> terms) {
+        String where = buildWhere(resultMapId, tableName, terms);
+        if (where.trim().isEmpty()) {
+            throw new BusinessException("禁止执行无条件的更新操作");
+        }
+        return where;
+    }
+
+    public String buildWhere(String resultMapId, String tableName, List<Term> terms) {
+        RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
+        RDBDatabaseMetaData databaseMetaDate = getActiveDatabase();
+        SimpleWhereSqlBuilder builder = new SimpleWhereSqlBuilder() {
+            @Override
+            public Dialect getDialect() {
+                return databaseMetaDate.getDialect();
+            }
+        };
+        SqlAppender appender = new SqlAppender();
+        builder.buildWhere(tableMetaData, "", terms, appender, new HashSet<>());
+        return appender.toString();
+    }
+
+    class MysqlMeta extends MysqlRDBDatabaseMetaData {
+        public MysqlMeta() {
+            super();
+            renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
+            renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.MYSQL));
+        }
+    }
+
+    class OracleMeta extends OracleRDBDatabaseMetaData {
+        public OracleMeta() {
+            super();
+            renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
+            renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.MYSQL));
+        }
+    }
+
+    class H2Meta extends H2RDBDatabaseMetaData {
+        public H2Meta() {
+            super();
+            renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
+            renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.MYSQL));
+        }
+    }
+}

+ 49 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/InsertSqlBuilder.java

@@ -0,0 +1,49 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.builder;
+
+import org.hsweb.ezorm.core.param.InsertParam;
+import org.hsweb.ezorm.rdb.executor.SQL;
+import org.hsweb.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hsweb.ezorm.rdb.meta.RDBTableMetaData;
+import org.hsweb.ezorm.rdb.render.SqlAppender;
+import org.hsweb.ezorm.rdb.render.support.simple.SimpleInsertSqlRender;
+
+/**
+ * @author zhouhao
+ */
+public class InsertSqlBuilder extends SimpleInsertSqlRender {
+    @Override
+    public SQL render(RDBTableMetaData metaData, InsertParam param) {
+        RDBTableMetaData metaDataNew = metaData.clone();
+        metaDataNew.setDatabaseMetaData(metaData.getDatabaseMetaData());
+        metaDataNew.getColumns().stream()
+                .filter(column -> column.getName().contains("."))
+                .map(RDBColumnMetaData::getName)
+                .forEach(metaDataNew::removeColumn);
+        return super.render(metaDataNew, param);
+    }
+
+    @Override
+    protected SqlAppender getParamString(String prefix, String paramName, RDBColumnMetaData rdbColumnMetaData) {
+        return new SqlAppender().add("#{", paramName,
+                ",javaType=", EasyOrmSqlBuilder.getJavaType(rdbColumnMetaData.getJavaType()),
+                ",jdbcType=", rdbColumnMetaData.getJdbcType(), "}");
+    }
+}

+ 34 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/SqlBuilder.java

@@ -0,0 +1,34 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.builder;
+
+/**
+ * @author zhouhao
+ */
+public class SqlBuilder {
+    private static boolean dynamic;
+
+    public static final Object current() {
+        return EasyOrmSqlBuilder.getInstance();
+    }
+
+    public static void setDynamic(boolean dynamic) {
+        SqlBuilder.dynamic = dynamic;
+    }
+}

+ 53 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/UpdateSqlBuilder.java

@@ -0,0 +1,53 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.builder;
+
+import org.hsweb.ezorm.core.param.UpdateParam;
+import org.hsweb.ezorm.rdb.executor.SQL;
+import org.hsweb.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hsweb.ezorm.rdb.meta.RDBTableMetaData;
+import org.hsweb.ezorm.rdb.render.SqlAppender;
+import org.hsweb.ezorm.rdb.render.dialect.Dialect;
+import org.hsweb.ezorm.rdb.render.support.simple.SimpleUpdateSqlRender;
+
+/**
+ * @author zhouhao
+ */
+public class UpdateSqlBuilder extends SimpleUpdateSqlRender {
+    public UpdateSqlBuilder(Dialect dialect) {
+        super(dialect);
+    }
+    @Override
+    public SQL render(RDBTableMetaData metaData, UpdateParam param) {
+        RDBTableMetaData metaDataNew = metaData.clone();
+        metaDataNew.setDatabaseMetaData(metaData.getDatabaseMetaData());
+
+        metaDataNew.getColumns().stream()
+                .filter(column -> column.getName().contains("."))
+                .map(RDBColumnMetaData::getName)
+                .forEach(metaDataNew::removeColumn);
+        return super.render(metaDataNew, param);
+    }
+    @Override
+    protected SqlAppender getParamString(String paramName, RDBColumnMetaData rdbColumnMetaData) {
+        return new SqlAppender().add("#{", paramName,
+                ",javaType=", EasyOrmSqlBuilder.getJavaType(rdbColumnMetaData.getJavaType()),
+                ",jdbcType=", rdbColumnMetaData.getJdbcType(), "}");
+    }
+}

+ 30 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/dynamic/DynamicDataSourceSqlSessionFactoryBuilder.java

@@ -0,0 +1,30 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.dynamic;
+
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+
+public class DynamicDataSourceSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder {
+    @Override
+    public SqlSessionFactory build(Configuration config) {
+        return new DynamicSqlSessionFactory(config);
+    }
+}

+ 203 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/dynamic/DynamicSpringManagedTransaction.java

@@ -0,0 +1,203 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.dynamic;
+
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.logging.LogFactory;
+import org.apache.ibatis.transaction.Transaction;
+import org.hswebframework.web.dao.datasource.DataSourceHolder;
+import org.mybatis.spring.transaction.SpringManagedTransaction;
+import org.springframework.jdbc.datasource.ConnectionHolder;
+import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * mybatis 同一事务,同一个mapper,动态数据源切换支持
+ *
+ * @author zhouhao
+ */
+public class DynamicSpringManagedTransaction implements Transaction {
+
+    private static final Log LOGGER = LogFactory.getLog(SpringManagedTransaction.class);
+
+    private Map<String, TransactionProxy> connectionMap = new HashMap<>();
+
+    /**
+     * 当前数据源对应的事务代理
+     *
+     * @return {@link TransactionProxy}
+     */
+    protected TransactionProxy getProxy() {
+        return connectionMap.get(DataSourceHolder.getActiveSourceId());
+    }
+
+    /**
+     * 添加一个事务代理
+     *
+     * @param proxy
+     */
+    protected void addProxy(TransactionProxy proxy) {
+        connectionMap.put(DataSourceHolder.getActiveSourceId(), proxy);
+    }
+
+    /**
+     * 获取所有代理
+     *
+     * @return
+     */
+    protected Collection<TransactionProxy> getAllProxy() {
+        return connectionMap.values();
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        TransactionProxy proxy = getProxy();
+        if (proxy != null) {
+            return proxy.getConnection();
+        }
+        //根据当前激活的数据源 获取jdbc链接
+        DataSource dataSource = DataSourceHolder.getActiveSource();
+        String dsId = DataSourceHolder.getActiveSourceId();
+        Connection connection = DataSourceUtils.getConnection(dataSource);
+        proxy = new TransactionProxy(dsId, connection, dataSource);
+        addProxy(proxy);
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug(
+                    "DataSource (" + DataSourceHolder.getActiveSourceId() + ") JDBC Connection ["
+                            + connection
+                            + "] will"
+                            + (proxy.isConnectionTransactional ? " " : " not ")
+                            + "be managed by Spring");
+        }
+
+        return connection;
+    }
+
+    @Override
+    public void commit() throws SQLException {
+        for (TransactionProxy proxy : getAllProxy()) {
+            proxy.commit();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void rollback() throws SQLException {
+        for (TransactionProxy proxy : getAllProxy()) {
+            proxy.rollback();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws SQLException {
+        SQLException tmp = null;
+        for (TransactionProxy proxy : getAllProxy()) {
+            try {
+                proxy.close();
+                //保证每个链接都能被释放
+            } catch (SQLException e) {
+                tmp = e;
+            }
+        }
+        connectionMap.clear();
+        if (null != tmp) throw tmp;
+    }
+
+    @Override
+    public Integer getTimeout() throws SQLException {
+        return getProxy().getTimeout();
+    }
+
+    class TransactionProxy implements Transaction {
+        Connection connection;
+        DataSource dataSource;
+        boolean    isConnectionTransactional;
+        boolean    autoCommit;
+        String     dataSourceId;
+
+        public TransactionProxy(String dataSourceId, Connection connection, DataSource dataSource) {
+            this.connection = connection;
+            this.dataSource = dataSource;
+            this.dataSourceId = dataSourceId;
+            this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(connection, dataSource);
+            try {
+                this.autoCommit = connection.getAutoCommit();
+            } catch (SQLException e) {
+            }
+        }
+
+        @Override
+        public Connection getConnection() throws SQLException {
+            return connection;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void commit() throws SQLException {
+            if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug("Committing DataSource (" + dataSourceId + ") JDBC Connection [" + this.connection + "]");
+                }
+                this.connection.commit();
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void rollback() throws SQLException {
+            if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug("Rolling back DataSource (" + dataSourceId + ") JDBC Connection [" + this.connection + "]");
+                }
+                this.connection.rollback();
+            }
+        }
+
+        @Override
+        public void close() throws SQLException {
+            DataSourceUtils.releaseConnection(connection, dataSource);
+        }
+
+        @Override
+        public Integer getTimeout() throws SQLException {
+            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
+            if (holder != null && holder.hasTimeout()) {
+                return holder.getTimeToLiveInSeconds();
+            }
+            return null;
+        }
+    }
+}

+ 147 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/dynamic/DynamicSqlSessionFactory.java

@@ -0,0 +1,147 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.dynamic;
+
+import org.apache.ibatis.exceptions.ExceptionFactory;
+import org.apache.ibatis.executor.ErrorContext;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.Environment;
+import org.apache.ibatis.session.*;
+import org.apache.ibatis.session.defaults.DefaultSqlSession;
+import org.apache.ibatis.transaction.Transaction;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
+import org.hswebframework.web.dao.datasource.DataSourceHolder;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * @author zhouhao
+ */
+public class DynamicSqlSessionFactory implements SqlSessionFactory {
+    private final Configuration configuration;
+
+    public DynamicSqlSessionFactory(Configuration configuration) {
+        this.configuration = configuration;
+    }
+
+    @Override
+    public SqlSession openSession() {
+        return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
+    }
+
+    @Override
+    public SqlSession openSession(boolean autoCommit) {
+        return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
+    }
+
+    @Override
+    public SqlSession openSession(ExecutorType execType) {
+        return openSessionFromDataSource(execType, null, false);
+    }
+
+    @Override
+    public SqlSession openSession(TransactionIsolationLevel level) {
+        return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
+    }
+
+    @Override
+    public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {
+        return openSessionFromDataSource(execType, level, false);
+    }
+
+    @Override
+    public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
+        return openSessionFromDataSource(execType, null, autoCommit);
+    }
+
+    @Override
+    public SqlSession openSession(Connection connection) {
+        return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);
+    }
+
+    @Override
+    public SqlSession openSession(ExecutorType execType, Connection connection) {
+        return openSessionFromConnection(execType, connection);
+    }
+
+    @Override
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+
+    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
+        Transaction tx = null;
+        try {
+            final Environment environment = getConfiguration().getEnvironment();
+            final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
+            DataSource ds = DataSourceHolder.getActiveSource();
+            if (ds == null) ds = environment.getDataSource();
+            tx = transactionFactory.newTransaction(ds, level, autoCommit);
+            final Executor executor = getConfiguration().newExecutor(tx, execType);
+            return new DefaultSqlSession(getConfiguration(), executor, autoCommit);
+        } catch (Exception e) {
+            closeTransaction(tx); // may have fetched a connection so lets call close()
+            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
+        } finally {
+            ErrorContext.instance().reset();
+        }
+    }
+
+    private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
+        try {
+            boolean autoCommit;
+            try {
+                autoCommit = connection.getAutoCommit();
+            } catch (SQLException e) {
+                // Failover to true, as most poor drivers
+                // or databases won't support transactions
+                autoCommit = true;
+            }
+            final Environment environment = configuration.getEnvironment();
+            final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
+            final Transaction tx = transactionFactory.newTransaction(connection);
+            final Executor executor = configuration.newExecutor(tx, execType);
+            return new DefaultSqlSession(configuration, executor, autoCommit);
+        } catch (Exception e) {
+            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
+        } finally {
+            ErrorContext.instance().reset();
+        }
+    }
+
+    private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
+        if (environment == null || environment.getTransactionFactory() == null) {
+            return new ManagedTransactionFactory();
+        }
+        return environment.getTransactionFactory();
+    }
+
+    private void closeTransaction(Transaction tx) {
+        if (tx != null) {
+            try {
+                tx.close();
+            } catch (SQLException ignore) {
+                // Intentionally ignore. Prefer previous error.
+            }
+        }
+    }
+}

+ 79 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/handler/JsonArrayHandler.java

@@ -0,0 +1,79 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.apache.ibatis.type.*;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Alias("jsonArrayHandler")
+@MappedTypes({List.class})
+@MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.CLOB})
+public class JsonArrayHandler extends BaseTypeHandler<List<Object>> {
+
+    @Override
+    public List<Object> getResult(ResultSet rs, int columnIndex) throws SQLException {
+        String s = rs.getString(columnIndex);
+        return JSON.parseArray(s);
+    }
+
+    @Override
+    public List<Object> getResult(ResultSet rs, String columnName) throws SQLException {
+        String s = rs.getString(columnName);
+        return JSON.parseArray(s);
+    }
+
+    @Override
+    public List<Object> getResult(CallableStatement cs, int columnIndex) throws SQLException {
+        String s = cs.getString(columnIndex);
+        return JSON.parseArray(s);
+    }
+
+    @Override
+    public void setParameter(PreparedStatement ps, int i, List<Object> parameter, JdbcType jdbcType) throws SQLException {
+        ps.setString(i, JSON.toJSONString(parameter, SerializerFeature.WriteClassName));
+    }
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, List<Object> parameter, JdbcType jdbcType) throws SQLException {
+        ps.setString(i, "[]");
+    }
+
+    @Override
+    public List<Object> getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return new ArrayList<>();
+    }
+}

+ 79 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/handler/JsonMapHandler.java

@@ -0,0 +1,79 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.apache.ibatis.type.*;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+@Alias("jsonMapHandler")
+@MappedTypes({Map.class})
+@MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.CLOB})
+public class JsonMapHandler extends BaseTypeHandler<Map<String, Object>> {
+
+    @Override
+    public Map<String, Object> getResult(ResultSet rs, int columnIndex) throws SQLException {
+        String s = rs.getString(columnIndex);
+        return JSON.parseObject(s);
+    }
+
+    @Override
+    public Map<String, Object> getResult(ResultSet rs, String columnName) throws SQLException {
+        String s = rs.getString(columnName);
+        return JSON.parseObject(s);
+    }
+
+    @Override
+    public Map<String, Object> getResult(CallableStatement cs, int columnIndex) throws SQLException {
+        String s = cs.getString(columnIndex);
+        return JSON.parseObject(s);
+    }
+
+    @Override
+    public void setParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType) throws SQLException {
+        ps.setString(i, JSON.toJSONString(parameter, SerializerFeature.WriteClassName));
+    }
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType) throws SQLException {
+        ps.setString(i, "{}");
+    }
+
+    @Override
+    public Map<String, Object> getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return new HashMap<>();
+    }
+
+    @Override
+    public Map<String, Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return new HashMap<>();
+    }
+
+    @Override
+    public Map<String, Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return new HashMap<>();
+    }
+}

+ 84 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/Pager.java

@@ -0,0 +1,84 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.plgins.pager;
+
+
+import org.hswebframework.web.ThreadLocalUtils;
+
+/**
+ * 分页插件,通过此接口进行分页操作
+ *
+ * @author zhouhao
+ * @see PagerInterceptor
+ */
+public interface Pager {
+    int pageIndex();
+
+    int pageSize();
+
+    String threadLocalKey = "nowPager";
+
+    static Pager getAndReset() {
+        try {
+            return get();
+        } finally {
+            reset();
+        }
+    }
+
+    static Pager get() {
+        return ThreadLocalUtils.get(threadLocalKey);
+    }
+
+    static void reset() {
+        ThreadLocalUtils.remove(threadLocalKey);
+    }
+
+    static void doPaging(int pageIndex, int pageSize) {
+        ThreadLocalUtils.put(threadLocalKey, new Pager() {
+            @Override
+            public int pageIndex() {
+                return pageIndex;
+            }
+
+            @Override
+            public int pageSize() {
+                return pageSize;
+            }
+        });
+    }
+
+    static void doPaging(int pageIndex, int pageSize, int total) {
+        doPaging(pageIndex, pageSize);
+        rePaging(total);
+    }
+
+    static void rePaging(int total) {
+        Pager pager = get();
+        int pageIndex = 0;
+        if (pager != null) {
+            // 当前页没有数据后跳转到最后一页
+            if (pager.pageIndex() != 0 && (pager.pageIndex() * pager.pageSize()) >= total) {
+                int tmp = total / pager.pageSize();
+                pageIndex = total % pager.pageSize() == 0 ? tmp - 1 : tmp;
+            }
+            doPaging(pageIndex, pager.pageSize());
+        }
+    }
+}

+ 64 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/plgins/pager/PagerInterceptor.java

@@ -0,0 +1,64 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.plgins.pager;
+
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.executor.statement.StatementHandler;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.plugin.*;
+import org.apache.ibatis.reflection.MetaObject;
+import org.apache.ibatis.reflection.SystemMetaObject;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+import org.hswebframework.web.dao.mybatis.builder.EasyOrmSqlBuilder;
+import org.springframework.stereotype.Component;
+
+import java.util.Properties;
+
+@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
+        RowBounds.class, ResultHandler.class})})
+@Component
+public class PagerInterceptor implements Interceptor {
+
+    @Override
+    public Object intercept(Invocation target) throws Throwable {
+        return target.proceed();
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        if (target instanceof StatementHandler) {
+            StatementHandler statementHandler = (StatementHandler) target;
+            MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
+            String sql = statementHandler.getBoundSql().getSql();
+            Pager pager = Pager.getAndReset();
+            if (pager != null && sql.trim().toLowerCase().startsWith("select")) {
+                String newSql = EasyOrmSqlBuilder.getInstance()
+                        .getActiveDatabase().getDialect()
+                        .doPaging(sql, pager.pageIndex(), pager.pageSize());
+                metaStatementHandler.setValue("delegate.boundSql.sql", newSql);
+            }
+        }
+        return Plugin.wrap(target, this);
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+    }
+}

+ 44 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/utils/ResultMapsUtils.java

@@ -0,0 +1,44 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.dao.mybatis.utils;
+
+import org.apache.ibatis.mapping.ResultMap;
+import org.apache.ibatis.session.SqlSession;
+import org.mybatis.spring.SqlSessionTemplate;
+
+/**
+ * Created by zhouhao on 16-6-3.
+ */
+public class ResultMapsUtils {
+    private static SqlSession sqlSession;
+
+    public static ResultMap getResultMap(String id) {
+        while (sqlSession == null) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+            }
+        }
+        return sqlSession.getConfiguration().getResultMap(id);
+    }
+
+    public static void setSqlSession(SqlSessionTemplate sqlSession) {
+        ResultMapsUtils.sqlSession = sqlSession;
+    }
+}

+ 151 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/resources/META-INF/spring-configuration-metadata.json

@@ -0,0 +1,151 @@
+{
+  "groups": [
+    {
+      "name": "mybatis",
+      "type": "org.hswebframework.web.dao.mybatis.MybatisProperties",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    }
+  ],
+  "properties": [
+    {
+      "name": "mybatis.dynamic-datasource",
+      "type": "java.lang.Boolean",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties",
+      "description": "enable dynamicDatasource."
+    },
+    {
+      "name": "mybatis.mapper-location-excludes",
+      "type": "java.lang.String[]",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties",
+      "description": "exclude mapperLocations."
+    },
+    {
+      "name": "mybatis.check-config-location",
+      "type": "java.lang.Boolean",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.check-config-location",
+      "type": "java.lang.Boolean",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.check-config-location",
+      "type": "java.lang.Boolean",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.check-config-location",
+      "type": "java.lang.Boolean",
+      "description": "Check the config file exists.",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties",
+      "defaultValue": false
+    },
+    {
+      "name": "mybatis.config",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.config",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.config",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.config",
+      "type": "java.lang.String",
+      "description": "Config file path.",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.executor-type",
+      "type": "org.apache.ibatis.session.ExecutorType",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.executor-type",
+      "type": "org.apache.ibatis.session.ExecutorType",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.executor-type",
+      "type": "org.apache.ibatis.session.ExecutorType",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.executor-type",
+      "type": "org.apache.ibatis.session.ExecutorType",
+      "description": "Execution mode.",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.mapper-locations",
+      "type": "java.lang.String[]",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.mapper-locations",
+      "type": "java.lang.String[]",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.mapper-locations",
+      "type": "java.lang.String[]",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.mapper-locations",
+      "type": "java.lang.String[]",
+      "description": "Location of mybatis mapper files.",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-aliases-package",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-aliases-package",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-aliases-package",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-aliases-package",
+      "type": "java.lang.String",
+      "description": "Package to scan domain objects.",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-handlers-package",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-handlers-package",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-handlers-package",
+      "type": "java.lang.String",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    },
+    {
+      "name": "mybatis.type-handlers-package",
+      "type": "java.lang.String",
+      "description": "Package to scan handlers.",
+      "sourceType": "org.hswebframework.web.dao.mybatis.MybatisProperties"
+    }
+  ],
+  "hints": []
+}

+ 3 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,3 @@
+# Auto Configure
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.hswebframework.web.dao.mybatis.MybatisDaoAutoConfiguration

+ 99 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/basic/BasicMapper.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="BasicMapper">
+    <!--通用查询条件-->
+    <sql id="buildWhere">
+        ${@org.hswebframework.web.dao.mybatis.builder.SqlBuilder@current().buildWhere(resultMapId,tableName,#this['_parameter'].terms)}
+    </sql>
+    <sql id="buildWhereForUpdate">
+        ${@org.hswebframework.web.dao.mybatis.builder.SqlBuilder@current().buildWhereForUpdate(resultMapId,tableName,#this['_parameter'].terms)}
+    </sql>
+    <!--生成查询字段-->
+    <sql id="buildSelectField">
+        ${@org.hswebframework.web.dao.mybatis.builder.SqlBuilder@current().buildSelectFields(resultMapId,tableName,#this['_parameter'])}
+    </sql>
+
+    <!--生成修改字段-->
+    <sql id="buildUpdateField">
+        <set>
+            ${@org.hswebframework.web.dao.mybatis.builder.SqlBuilder@current().buildUpdateFields(resultMapId,tableName,#this['_parameter'])}
+        </set>
+    </sql>
+
+    <!--生成排序字段-->
+    <sql id="buildSortField">
+        ${@org.hswebframework.web.dao.mybatis.builder.SqlBuilder@current().buildOrder(resultMapId,tableName,#this['_parameter'])}
+    </sql>
+
+    <!--生成查询sql-->
+    <sql id="buildSelectSql">
+        <trim>
+            select
+            <include refid="BasicMapper.buildSelectField"/>
+            from ${tableName}
+            <where>
+                <include refid="BasicMapper.buildWhere"/>
+            </where>
+            <include refid="BasicMapper.buildSortField"/>
+        </trim>
+    </sql>
+
+    <!--生成删除sql-->
+    <sql id="buildDeleteSql">
+        <trim>
+            delete from ${tableName}
+            <where>
+                <include refid="BasicMapper.buildWhereForUpdate"/>
+            </where>
+        </trim>
+    </sql>
+
+    <!--生成InsertSql-->
+    <sql id="buildInsertSql">
+        ${@org.hswebframework.web.dao.mybatis.builder.SqlBuilder@current().buildInsertSql(resultMapId,tableName,#this['_parameter'])}
+    </sql>
+
+    <!--生成UpdateSql-->
+    <sql id="buildUpdateSql">
+        <trim>
+            update ${tableName}
+            <include refid="BasicMapper.buildUpdateField"/>
+            <where>
+                <include refid="BasicMapper.buildWhereForUpdate"/>
+                <if test="terms.size()==0">
+                    u_id=#{data.id}
+                </if>
+            </where>
+        </trim>
+    </sql>
+
+    <!--生成查询数量sql-->
+    <sql id="buildTotalSql">
+        <trim>
+            select count(0) as total from ${tableName}
+            <where>
+                <include refid="BasicMapper.buildWhere"/>
+            </where>
+        </trim>
+    </sql>
+</mapper>

+ 43 - 0
hsweb-commons/hsweb-commons-dao/pom.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-dao</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-commons-dao-api</module>
+        <module>hsweb-commons-dao-mybatis</module>
+    </modules>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-easy-orm-rdb</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 40 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/pom.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons-service</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-service-api</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-dao-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 28 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CreateBeanService.java

@@ -0,0 +1,28 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface CreateBeanService<B> {
+    B createBean();
+}

+ 37 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CrudService.java

@@ -0,0 +1,37 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.beans.Bean;
+
+/**
+ * 通用Service,实现增删改查
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public interface CrudService<B, PK, Q extends Bean> extends
+        QueryByBeanService<B, Q>,
+        UpdateService<B>,
+        InsertService<B, PK>,
+        DeleteService<PK>,
+        CreateBeanService<B> {
+
+    B selectByPk(PK id);
+}

+ 33 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/DeleteService.java

@@ -0,0 +1,33 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+/**
+ * @author zhouhao
+ */
+public interface DeleteService<PK> {
+    /**
+     * 根据主键删除记录
+     *
+     * @param pk 主键
+     * @return 影响记录数
+     */
+    int deleteByPk(PK pk);
+
+}

+ 33 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/InsertService.java

@@ -0,0 +1,33 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+/**
+ * @author zhouhao
+ */
+public interface InsertService<B,Pk> {
+
+    /**
+     * 添加一条数据
+     *
+     * @param data 要添加的数据
+     * @return 添加后生成的主键
+     */
+    Pk insert(B data);
+}

+ 37 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/QueryByBeanService.java

@@ -0,0 +1,37 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.beans.Bean;
+import org.hswebframework.web.commons.beans.PagerResult;
+
+import java.util.List;
+
+public interface QueryByBeanService<B, Q extends Bean> extends Service {
+    PagerResult<B> selectPager(Q param);
+
+    List<B> select(Q param);
+
+    List<B> select();
+
+    int count(Q param);
+
+    B selectSingle(Q param);
+
+}

+ 27 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/Service.java

@@ -0,0 +1,27 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface Service {
+}

+ 49 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/UpdateService.java

@@ -0,0 +1,49 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import java.util.List;
+
+public interface UpdateService<Po> extends Service {
+    /**
+     * 修改记录信息
+     *
+     * @param data 要修改的对象
+     * @return 影响记录数
+     */
+    int updateByPk(Po data);
+
+    /**
+     * 批量修改记录
+     *
+     * @param data 要修改的记录集合
+     * @return 影响记录数
+     */
+    int updateByPk(List<Po> data);
+
+    /**
+     * 保存或修改
+     *
+     * @param po 要修改的数据
+     * @return
+     */
+    int saveOrUpdate(Po po);
+
+
+}

+ 60 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/pom.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons-service</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-service-simple</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-service-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-dao-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 56 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLDeleteService.java

@@ -0,0 +1,56 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hsweb.ezorm.core.dsl.Delete;
+import org.hswebframework.web.commons.beans.param.DeleteParamBean;
+import org.hswebframework.web.dao.dynamic.DeleteByBeanDao;
+
+/**
+ * @author zhouhao
+ */
+public interface DefaultDSLDeleteService<PK> extends DefaultDeleteService<PK> {
+    DeleteByBeanDao getDao();
+
+    default Delete<DeleteParamBean> createDelete() {
+        Delete<DeleteParamBean> delete = new Delete<>(new DeleteParamBean());
+        delete.setExecutor(getDao()::delete);
+        return delete;
+    }
+
+    static Delete<DeleteParamBean> createDelete(DeleteByBeanDao deleteDao) {
+        Delete<DeleteParamBean> update = new Delete<>(new DeleteParamBean());
+        update.setExecutor(deleteDao::delete);
+        return update;
+    }
+
+    /**
+     * 自定义一个删除执行器。创建dsl数据删除操作对象
+     *
+     * @param executor 执行器
+     * @return {@link Delete}
+     * @since 3.0
+     */
+    static Delete<DeleteParamBean> createDelete(Delete.Executor<DeleteParamBean> executor) {
+        Delete<DeleteParamBean> update = new Delete<>(new DeleteParamBean());
+        update.setExecutor(executor);
+        return update;
+    }
+
+}

+ 76 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLQueryService.java

@@ -0,0 +1,76 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hsweb.ezorm.core.dsl.Query;
+import org.hswebframework.web.commons.beans.param.QueryParamBean;
+import org.hswebframework.web.dao.dynamic.QueryByBeanDao;
+
+import java.util.List;
+
+public interface DefaultDSLQueryService<B>
+        extends DefaultQueryByBeanService<B> {
+
+    /**
+     * 创建本服务的dsl查询操作对象
+     * 可通过返回的Query对象进行dsl方式操作如:<br>
+     * <code>
+     * createQuery().where("id",1).single();
+     * </code>
+     *
+     * @return {@link Query}
+     * @see Query
+     * @see org.hsweb.ezorm.core.Conditional
+     * @since 3.0
+     */
+    default Query<B, QueryParamBean> createQuery() {
+        Query<B, QueryParamBean> query = Query.empty(new QueryParamBean());
+        query.setListExecutor(this::select);
+        query.setTotalExecutor(this::count);
+        query.setSingleExecutor(this::selectSingle);
+        return query;
+    }
+
+    /**
+     * 指定一个dao映射接口,接口需继承{@link QueryByBeanDao}创建dsl数据查询对象<br>
+     * 可通过返回的Query对象进行dsl方式操作如:<br>
+     * <code>
+     * createQuery(userMapper).where("id",1).single();
+     * </code>
+     *
+     * @param dao  dao接口
+     * @param <PO> PO泛型
+     * @return {@link Query}
+     * @see Query
+     * @see org.hsweb.ezorm.core.Conditional
+     * @since 3.0
+     */
+    static <PO> Query<PO, QueryParamBean> createQuery(QueryByBeanDao<PO> dao) {
+        Query<PO, QueryParamBean> query = new Query<>(new QueryParamBean());
+        query.setListExecutor(dao::query);
+        query.setTotalExecutor(dao::count);
+        query.setSingleExecutor((param) -> {
+            param.doPaging(0, 1);
+            List<PO> list = dao.query(param);
+            if (null == list || list.size() == 0) return null;
+            else return list.get(0);
+        });
+        return query;
+    }
+}

+ 37 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLUpdateService.java

@@ -0,0 +1,37 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hsweb.ezorm.core.dsl.Update;
+import org.hswebframework.web.dao.dynamic.UpdateByBeanDao;
+import org.hswebframework.web.commons.beans.param.UpdateParamBean;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface DefaultDSLUpdateService<PO> extends UpdateService<PO> {
+
+    UpdateByBeanDao getDao();
+
+    default Update<PO, UpdateParamBean<PO>> createUpdate(PO data) {
+        return Update.build(getDao()::update, new UpdateParamBean<>(data));
+    }
+}

+ 32 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDeleteService.java

@@ -0,0 +1,32 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+/**
+ * @author zhouhao
+ */
+public interface DefaultDeleteService<PK> extends DeleteService<PK> {
+    /**
+     * 根据主键删除记录
+     *
+     * @param pk 主键
+     * @return 影响记录数
+     */
+    int deleteByPk(PK pk);
+}

+ 111 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultQueryByBeanService.java

@@ -0,0 +1,111 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hsweb.ezorm.core.dsl.Query;
+import org.hsweb.ezorm.core.param.QueryParam;
+import org.hswebframework.web.commons.beans.PagerResult;
+import org.hswebframework.web.commons.beans.param.QueryParamBean;
+import org.hswebframework.web.dao.dynamic.QueryByBeanDao;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface DefaultQueryByBeanService<B>
+        extends QueryByBeanService<B, QueryParamBean> {
+    QueryByBeanDao<B> getDao();
+
+    @Override
+    default PagerResult<B> selectPager(QueryParamBean param) {
+        PagerResult<B> pagerResult = new PagerResult<>();
+        param.setPaging(false);
+        int total = getDao().count(param);
+        pagerResult.setTotal(total);
+        if (total == 0) {
+            pagerResult.setData(new ArrayList<>());
+        } else {
+            //根据实际记录数量重新指定分页参数
+            param.rePaging(total);
+            pagerResult.setData(getDao().query(param));
+        }
+        return pagerResult;
+    }
+
+    /**
+     * 分页进行查询数据,查询条件同 {@link DefaultQueryByBeanService#select}
+     *
+     * @param param 查询参数
+     * @return 分页结果
+     * @ 查询异常
+     */
+
+    /**
+     * 根据查询参数进行查询,参数可使用 {@link Query}进行构建
+     *
+     * @param param 查询参数
+     * @return 查询结果
+     * @see QueryParam
+     */
+    @Override
+    @Transactional(readOnly = true)
+    default List<B> select(QueryParamBean param) {
+        return getDao().query(param);
+    }
+
+    /**
+     * 查询所有数据
+     *
+     * @return 所有数据
+     */
+    @Override
+    @Transactional(readOnly = true)
+    default List<B> select() {
+        return getDao().query(new QueryParamBean());
+    }
+
+    /**
+     * 查询记录总数,用于分页等操作。查询条件同 {@link DefaultQueryByBeanService#select}
+     *
+     * @param param 查询参数
+     * @return 查询结果,实现mapper中的sql应指定默认值,否则可能抛出异常
+     */
+    @Override
+    @Transactional(readOnly = true)
+    default int count(QueryParamBean param) {
+        return getDao().count(param);
+    }
+
+    /**
+     * 查询只返回单个结果
+     *
+     * @param param 查询条件
+     * @return 单个结果
+     * @see this#select(QueryParamBean)
+     */
+    @Override
+    @Transactional(readOnly = true)
+    default B selectSingle(QueryParamBean param) {
+        param.doPaging(0, 1);
+        List<B> list = this.select(param);
+        if (list.size() == 0) return null;
+        else return list.get(0);
+    }
+
+}

+ 147 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericBeanService.java

@@ -0,0 +1,147 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.beans.GenericBean;
+import org.hswebframework.web.commons.beans.factory.BeanFactory;
+import org.hswebframework.web.NotFoundException;
+import org.hswebframework.web.dao.CrudDao;
+import org.hswebframework.web.validate.SimpleValidateResults;
+import org.hswebframework.web.validate.ValidationException;
+import org.hswebframwork.utils.ClassUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.validation.Validator;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Transactional(rollbackFor = Throwable.class)
+public abstract class GenericBeanService<B extends GenericBean<PK>, PK> implements GenericService<B, PK> {
+
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired(required = false)
+    private Validator validator;
+
+    @Autowired(required = false)
+    private BeanFactory beanFactory;
+
+    private Class<B>  beanType;
+    private Class<PK> primaryKeyType;
+
+    @SuppressWarnings("unchecked")
+    public GenericBeanService(){
+        primaryKeyType = (Class<PK>) ClassUtils.getGenericType(this.getClass(), 1);
+        beanType = (Class<B>) ClassUtils.getGenericType(this.getClass(), 0);
+    }
+
+    @Override
+    public abstract CrudDao<B, PK> getDao();
+
+    private boolean beanFactoryIsEnabled() {
+        if (beanFactory == null) {
+            logger.warn("beanFactory is null!");
+        }
+        return null != beanFactory;
+    }
+
+    protected Class<B> getBeanRealType() {
+        return beanFactory.getRealType(getBeanType());
+    }
+
+    protected Class<B> getBeanType() {
+        return beanType;
+    }
+
+    protected Class<PK> getPrimaryKeyType() {
+        return primaryKeyType;
+    }
+
+    @Override
+    public B createBean() {
+        if (!beanFactoryIsEnabled()) {
+            throw new UnsupportedOperationException("{unsupported_operation}");
+        }
+        return beanFactory.getInstance(getBeanType());
+    }
+
+    public void tryValidate(B bean) {
+        if (validator == null) {
+            logger.warn("validator is null!");
+            return;
+        }
+        SimpleValidateResults results = new SimpleValidateResults();
+        validator.validate(bean).forEach(violation -> results.addResult(violation.getPropertyPath().toString(), violation.getMessage()));
+        if (!results.isSuccess())
+            throw new ValidationException(results);
+    }
+
+    @Override
+    public int deleteByPk(PK pk) {
+        return createDelete().where(GenericBean.id, pk).exec();
+    }
+
+    @Override
+    public int updateByPk(B data) {
+        tryValidate(data);
+        return createUpdate(data).where(GenericBean.id, data.getId()).exec();
+    }
+
+    @Override
+    public int updateByPk(List<B> data) {
+        return data.stream().map(this::updateByPk).reduce(Math::addExact).orElse(0);
+    }
+
+    @Override
+    public int saveOrUpdate(B po) {
+        if (null != po.getId()) {
+            return updateByPk(po);
+        } else {
+            insert(po);
+        }
+        return 1;
+    }
+
+    @Override
+    public PK insert(B data) {
+        tryValidate(data);
+        getDao().insert(data);
+        return data.getId();
+    }
+
+    @Override
+    public B selectByPk(PK id) {
+        return createQuery().where(GenericBean.id, id).single();
+    }
+
+    public void assertNotNull(Object data) {
+        assertNotNull(data, "{data_not_found}");
+    }
+
+    public void assertNotNull(Object data, String message) {
+        if (null == data) throw new NotFoundException(message);
+    }
+}

+ 44 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericService.java

@@ -0,0 +1,44 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.dao.CrudDao;
+import org.hswebframework.web.commons.beans.param.QueryParamBean;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ * @see DefaultDSLQueryService
+ * @see DefaultDSLUpdateService
+ * @see DefaultDSLDeleteService
+ * @see CrudService
+ * @see QueryParamBean
+ * @see CrudDao
+ */
+public interface GenericService<B, PK> extends
+        DefaultDSLQueryService<B>,
+        DefaultDSLUpdateService<B>,
+        DefaultDSLDeleteService<PK>,
+        CrudService<B, PK, QueryParamBean> {
+    @Override
+    @Transactional
+    CrudDao<B, PK> getDao();
+}

+ 21 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/DSLQuery.java

@@ -0,0 +1,21 @@
+package org.hswebframework.web.service.dsl;
+
+
+import org.hswebframework.web.commons.beans.Bean;
+
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface DSLQuery<PO> extends Bean {
+    List<PO> list();
+
+    List<PO> list(int pageIndex, int pageSize);
+
+    PO single();
+
+    int count();
+}

+ 57 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/FieldCondition.java

@@ -0,0 +1,57 @@
+package org.hswebframework.web.service.dsl;
+
+
+import java.util.Collection;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface FieldCondition<PO, R extends DSLQuery<PO>> {
+
+    R accept(String termType, Object value);
+
+    R is(Object value);
+
+    R like(Object value);
+
+    R like$(Object value);
+
+    R $like(Object value);
+
+    R $like$(Object value);
+
+    R notLike(Object value);
+
+    R gt(Object value);
+
+    R lt(Object value);
+
+    R gte(Object value);
+
+    R lte(Object value);
+
+    R in(Object value);
+
+    R in(Object... values);
+
+    R in(Collection values);
+
+    R notIn(Object value);
+
+    R isEmpty();
+
+    R notEmpty();
+
+    R isNull();
+
+    R notNull();
+
+    R not(Object value);
+
+    R between(Object between, Object and);
+
+    R notBetween(Object between, Object and);
+
+}

+ 46 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/SimpleDSLQuery.java

@@ -0,0 +1,46 @@
+package org.hswebframework.web.service.dsl;
+
+import org.hsweb.ezorm.core.dsl.Query;
+import org.hswebframework.web.commons.beans.param.QueryParamBean;
+import org.hswebframework.web.service.DefaultQueryByBeanService;
+
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class SimpleDSLQuery<PO> implements DSLQuery<PO> {
+    protected Query<PO, QueryParamBean> query = Query.empty(new QueryParamBean());
+
+    public SimpleDSLQuery(DefaultQueryByBeanService<PO> service) {
+        query.setListExecutor(service::select);
+        query.setTotalExecutor(service::count);
+        query.setSingleExecutor(service::selectSingle);
+    }
+
+    public Query<PO, QueryParamBean> dynamic() {
+        return query;
+    }
+
+    @Override
+    public List<PO> list() {
+        return query.list();
+    }
+
+    @Override
+    public List<PO> list(int pageIndex, int pageSize) {
+        return query.list(pageIndex, pageSize);
+    }
+
+    @Override
+    public PO single() {
+        return query.single();
+    }
+
+    @Override
+    public int count() {
+        return query.total();
+    }
+}

+ 155 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/dsl/SimpleFieldCondition.java

@@ -0,0 +1,155 @@
+package org.hswebframework.web.service.dsl;
+
+import org.hsweb.ezorm.core.dsl.Query;
+import org.hswebframework.web.commons.beans.param.QueryParamBean;
+
+import java.util.Collection;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class SimpleFieldCondition<PO, R extends DSLQuery<PO>> implements FieldCondition<PO, R> {
+    Query<PO, QueryParamBean> query;
+    R                         proxy;
+    String                    filed;
+
+    public SimpleFieldCondition(Query<PO, QueryParamBean> query, R proxy, String filed) {
+        this.query = query;
+        this.proxy = proxy;
+        this.filed = filed;
+    }
+
+    @Override
+    public R accept(String termType, Object value) {
+        query.accept(filed, termType, value);
+        return proxy;
+    }
+
+    @Override
+    public R is(Object value) {
+        query.is(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R like(Object value) {
+        query.like(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R like$(Object value) {
+        query.like$(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R $like(Object value) {
+        query.$like(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R $like$(Object value) {
+        query.$like$(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R notLike(Object value) {
+        query.notLike(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R gt(Object value) {
+        query.gt(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R lt(Object value) {
+        query.lt(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R gte(Object value) {
+        query.gte(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R lte(Object value) {
+        query.lte(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R in(Object value) {
+        query.in(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R in(Object... values) {
+        query.in(filed, values);
+        return proxy;
+    }
+
+    @Override
+    public R in(Collection values) {
+        query.in(filed, values);
+        return proxy;
+    }
+
+    @Override
+    public R notIn(Object value) {
+        query.is(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R isEmpty() {
+        query.isEmpty(filed);
+        return proxy;
+    }
+
+    @Override
+    public R notEmpty() {
+        query.notEmpty(filed);
+        return proxy;
+    }
+
+    @Override
+    public R isNull() {
+        query.isNull(filed);
+        return proxy;
+    }
+
+    @Override
+    public R notNull() {
+        query.notNull(filed);
+        return proxy;
+    }
+
+    @Override
+    public R not(Object value) {
+        query.not(filed, value);
+        return proxy;
+    }
+
+    @Override
+    public R between(Object between, Object and) {
+        query.between(filed, between, and);
+        return proxy;
+    }
+
+    @Override
+    public R notBetween(Object between, Object and) {
+        query.notBetween(filed, between, and);
+        return proxy;
+    }
+}

+ 49 - 0
hsweb-commons/hsweb-commons-service/pom.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-service</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-commons-service-simple</module>
+        <module>hsweb-commons-service-api</module>
+    </modules>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-easy-orm-rdb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-beans</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 33 - 0
hsweb-commons/hsweb-commons-utils/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-commons</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons-utils</artifactId>
+
+
+</project>

+ 46 - 0
hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/ThreadLocalUtils.java

@@ -0,0 +1,46 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by zhouhao on 16-5-26.
+ */
+public class ThreadLocalUtils {
+    private static final ThreadLocal<Map<String, Object>> local = ThreadLocal.withInitial(() -> new HashMap<>());
+
+    public static <T> T put(String key, T value) {
+        local.get().put(key, value);
+        return value;
+    }
+
+    public static void remove(String key) {
+        local.get().remove(key);
+    }
+
+    public static void clear() {
+        local.remove();
+    }
+
+    public static <T> T get(String key) {
+        return ((T) local.get().get(key));
+    }
+}

+ 40 - 0
hsweb-commons/pom.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-framework</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-commons</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-commons-beans</module>
+        <module>hsweb-commons-dao</module>
+        <module>hsweb-commons-service</module>
+        <module>hsweb-commons-controller</module>
+        <module>hsweb-commons-utils</module>
+    </modules>
+
+</project>

+ 6 - 0
hsweb-core/pom.xml

@@ -12,4 +12,10 @@
     <artifactId>hsweb-core</artifactId>
 
 
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-utils</artifactId>
+        </dependency>
+    </dependencies>
 </project>

+ 35 - 0
hsweb-core/src/main/java/org/hswebframework/web/AuthorizeException.java

@@ -0,0 +1,35 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+public class AuthorizeException extends BusinessException {
+    private static final long serialVersionUID = 2422918455013900645L;
+
+    public AuthorizeException(String message) {
+        this(message, 401);
+    }
+
+    public AuthorizeException(String message, int status) {
+        super(message, status);
+    }
+
+    public AuthorizeException(String message, Throwable cause, int status) {
+        super(message, cause, status);
+    }
+}

+ 38 - 0
hsweb-core/src/main/java/org/hswebframework/web/AuthorizeForbiddenException.java

@@ -0,0 +1,38 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+/**
+ * Created by 浩 on 2015-12-23 0023.
+ */
+public class AuthorizeForbiddenException extends BusinessException {
+    private static final long serialVersionUID = 2422918455013900645L;
+
+    public AuthorizeForbiddenException(String message) {
+        this(message, 403);
+    }
+
+    public AuthorizeForbiddenException(String message, int status) {
+        super(message, status);
+    }
+
+    public AuthorizeForbiddenException(String message, Throwable cause, int status) {
+        super(message, cause, status);
+    }
+}

+ 46 - 0
hsweb-core/src/main/java/org/hswebframework/web/BusinessException.java

@@ -0,0 +1,46 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class BusinessException extends RuntimeException {
+    private int status = 400;
+
+    public BusinessException(String message) {
+        this(message, 400);
+    }
+
+    public BusinessException(String message, int status) {
+        super(message);
+        this.status = status;
+    }
+
+    public BusinessException(String message, Throwable cause, int status) {
+        super(message, cause);
+        this.status = status;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+}

+ 35 - 0
hsweb-core/src/main/java/org/hswebframework/web/Describe.java

@@ -0,0 +1,35 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+import java.lang.annotation.*;
+
+/**
+ * 功能描述
+ *
+ * @author zhouhao
+ */
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Describe {
+    String value();
+
+    Class type() default Object.class;
+}

+ 28 - 0
hsweb-core/src/main/java/org/hswebframework/web/NotFoundException.java

@@ -0,0 +1,28 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+/**
+ * Created by zhouhao on 16-4-29.
+ */
+public class NotFoundException extends BusinessException {
+    public NotFoundException(String message) {
+        super(message, 404);
+    }
+}

+ 48 - 0
hsweb-core/src/main/java/org/hswebframework/web/id/IDGenerator.java

@@ -0,0 +1,48 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.id;
+
+import org.hswebframwork.utils.RandomUtil;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface IDGenerator<T> {
+    T generate();
+
+    IDGenerator<String> UUID = java.util.UUID.randomUUID()::toString;
+
+    IDGenerator<String> RANDOM = RandomUtil::randomChar;
+
+    IDGenerator<String> MD5 = () -> {
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            md.update(UUID.generate().concat(RandomUtil.randomChar()).getBytes());
+            return new BigInteger(1, md.digest()).toString(16);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    };
+}

+ 81 - 0
hsweb-core/src/main/java/org/hswebframework/web/validate/SimpleValidateResults.java

@@ -0,0 +1,81 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.validate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class SimpleValidateResults implements ValidateResults {
+
+    private List<ValidateResults.Result> results = new ArrayList<>();
+
+    public SimpleValidateResults addResult(String field, String message) {
+        results.add(new Result(field, message));
+        return this;
+    }
+
+    @Override
+    public boolean isSuccess() {
+        return results == null || results.isEmpty();
+    }
+
+    @Override
+    public List<ValidateResults.Result> getResults() {
+        return results;
+    }
+
+    class Result implements ValidateResults.Result {
+        private String field;
+        private String message;
+
+        public Result(String field, String message) {
+            this.field = field;
+            this.message = message;
+        }
+
+        @Override
+        public String getField() {
+            return field;
+        }
+
+        @Override
+        public String getMessage() {
+            return message;
+        }
+
+        @Override
+        public String toString() {
+            return "{" +
+                    "\"field\":\"" + field + '\"' +
+                    ", \"message:\"" + message + '\"' +
+                    '}';
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (isSuccess()) return "success";
+        return results.toString();
+    }
+}

+ 41 - 0
hsweb-core/src/main/java/org/hswebframework/web/validate/ValidateResults.java

@@ -0,0 +1,41 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.validate;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface ValidateResults extends Serializable {
+
+    boolean isSuccess();
+
+    List<Result> getResults();
+
+    interface Result extends Serializable {
+        String getField();
+
+        String getMessage();
+    }
+
+}

+ 39 - 0
hsweb-core/src/main/java/org/hswebframework/web/validate/ValidationException.java

@@ -0,0 +1,39 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.validate;
+
+
+import org.hswebframework.web.BusinessException;
+
+public class ValidationException extends BusinessException {
+    private ValidateResults results;
+
+    public ValidationException(String message) {
+        super(message, 400);
+    }
+
+    public ValidationException(ValidateResults results) {
+        super(results.toString(), 400);
+        this.results = results;
+    }
+
+    public Object getResults() {
+        return results;
+    }
+}

+ 15 - 0
hsweb-dynamic-datasource/pom.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-framework</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-dynamic-datasource</artifactId>
+
+
+</project>

+ 33 - 0
hsweb-i18n/hsweb-i18n-cn/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * Copyright 2016 http://www.hswebframework.org
+  ~  *
+  ~  * Licensed under the Apache License, Version 2.0 (the "License");
+  ~  * you may not use this file except in compliance with the License.
+  ~  * You may obtain a copy of the License at
+  ~  *
+  ~  *     http://www.apache.org/licenses/LICENSE-2.0
+  ~  *
+  ~  * Unless required by applicable law or agreed to in writing, software
+  ~  * distributed under the License is distributed on an "AS IS" BASIS,
+  ~  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  * See the License for the specific language governing permissions and
+  ~  * limitations under the License.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-i18n</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-i18n-cn</artifactId>
+
+
+</project>

+ 0 - 0
hsweb-i18n/hsweb-i18n-cn/src/main/resources/messages_zh_CN.properties


Some files were not shown because too many files changed in this diff