wuhongshuang 4 éve
commit
34f24c8af6
87 módosított fájl, 8304 hozzáadás és 0 törlés
  1. 6 0
      .gitignore
  2. 13 0
      README.md
  3. 159 0
      generatorConfig-write.xml
  4. 144 0
      generatorConfig-write_mysql.xml
  5. 234 0
      pom.xml
  6. 23 0
      src/main/java/com/shawn/Application.java
  7. 30 0
      src/main/java/com/shawn/common/dbConfig/DynamicDataSource.java
  8. 127 0
      src/main/java/com/shawn/common/dbConfig/MyBatisConfig.java
  9. 10 0
      src/main/java/com/shawn/common/myAnnotation/CamelCaseToUnderscore.java
  10. 39 0
      src/main/java/com/shawn/common/myAnnotation/CamelCaseToUnderscoreFormatAnnotationFormatterFactory.java
  11. 51 0
      src/main/java/com/shawn/common/myAnnotation/CamelCaseToUnderscoreFormatter.java
  12. 55 0
      src/main/java/com/shawn/common/myAnnotation/GenHtml.java
  13. 13 0
      src/main/java/com/shawn/common/myAnnotation/HtmlHead.java
  14. 37 0
      src/main/java/com/shawn/common/myFormat/DateSerializer.java
  15. 304 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/MyCommentGenerator.java
  16. 51 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/MyJavaTypeResolver.java
  17. 284 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/MyPluginAdapter.java
  18. 98 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/MySQLLimitPlugin.java
  19. 148 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/OraclePaginationPlugin.java
  20. 44 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/HtmlField.java
  21. 48 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/MavenProgressCallback.java
  22. 82 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/MavenShellCallback.java
  23. 1076 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/MyBatisGeneratorMojo.java
  24. 202 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/SqlScriptRunner.java
  25. 119 0
      src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/TextUtil.java
  26. 66 0
      src/main/java/com/shawn/common/webConfig/CorsConfig.java
  27. 16 0
      src/main/java/com/shawn/constant/DatabaseType.java
  28. 19 0
      src/main/java/com/shawn/constant/ErrorCode.java
  29. 78 0
      src/main/java/com/shawn/constant/OprTypeEnum.java
  30. 19 0
      src/main/java/com/shawn/constant/PageConstant.java
  31. 31 0
      src/main/java/com/shawn/model/bean/PageBean.java
  32. 26 0
      src/main/java/com/shawn/model/dto/Error.java
  33. 25 0
      src/main/java/com/shawn/model/dto/HttpResult.java
  34. 29 0
      src/main/java/com/shawn/model/dto/PaginatedResult.java
  35. 26 0
      src/main/java/com/shawn/model/dto/ResultMessage.java
  36. 58 0
      src/main/java/com/shawn/monitor/PerformanceMonitor.java
  37. 54 0
      src/main/java/com/shawn/monitor/RepositoryMonitor.java
  38. 63 0
      src/main/java/com/shawn/monitor/ServiceMonitor.java
  39. 10 0
      src/main/java/com/shawn/repository/GetNoMapper.java
  40. 39 0
      src/main/java/com/shawn/repository/base/BaseDaoInterface.java
  41. 66 0
      src/main/java/com/shawn/security/AuthorizationServerConfiguration.java
  42. 25 0
      src/main/java/com/shawn/security/ResourceServerConfiguration.java
  43. 24 0
      src/main/java/com/shawn/security/WebSecurityConfiguration.java
  44. 128 0
      src/main/java/com/shawn/service/base/BaseService.java
  45. 74 0
      src/main/java/com/shawn/service/base/BaseServiceInterface.java
  46. 102 0
      src/main/java/com/shawn/service/base/GetNoServiceImpl.java
  47. 104 0
      src/main/java/com/shawn/util/BeanUtils.java
  48. 249 0
      src/main/java/com/shawn/util/DateUtils.java
  49. 162 0
      src/main/java/com/shawn/util/DiskClassLoader.java
  50. 153 0
      src/main/java/com/shawn/util/DomainEquals.java
  51. 490 0
      src/main/java/com/shawn/util/FgObjectUtil.java
  52. 42 0
      src/main/java/com/shawn/util/ListUtils.java
  53. 70 0
      src/main/java/com/shawn/util/PackageUtil.java
  54. 103 0
      src/main/java/com/shawn/util/PageUtil.java
  55. 138 0
      src/main/java/com/shawn/util/ProjectOutputClass.java
  56. 72 0
      src/main/java/com/shawn/util/ReadLog.java
  57. 470 0
      src/main/java/com/shawn/web/controller/base/BaseController.java
  58. 96 0
      src/main/java/com/shawn/web/exception/ExceptionHandlerControllerAdvice.java
  59. 24 0
      src/main/java/com/shawn/web/exception/MyException.java
  60. 25 0
      src/main/java/com/shawn/web/exception/ParamNotFoundException.java
  61. 10 0
      src/main/java/com/shawn/web/exception/ParameterIllegalException.java
  62. 24 0
      src/main/java/com/shawn/web/exception/ResourceNotFoundException.java
  63. 10 0
      src/main/java/com/shawn/web/exception/ServerInternalErrorException.java
  64. 71 0
      src/main/resources/application.properties
  65. 39 0
      src/main/resources/code_template_html/add.component.html.vm
  66. 0 0
      src/main/resources/code_template_html/add.component.scss.vm
  67. 50 0
      src/main/resources/code_template_html/add.component.ts.vm
  68. 42 0
      src/main/resources/code_template_html/edit.component.html.vm
  69. 0 0
      src/main/resources/code_template_html/edit.component.scss.vm
  70. 63 0
      src/main/resources/code_template_html/edit.component.ts.vm
  71. 54 0
      src/main/resources/code_template_html/grid.component.html.vm
  72. 0 0
      src/main/resources/code_template_html/grid.component.scss.vm
  73. 98 0
      src/main/resources/code_template_html/grid.component.ts.vm
  74. 5 0
      src/main/resources/code_template_html/manager.component.html.vm
  75. 0 0
      src/main/resources/code_template_html/manager.component.scss.vm
  76. 44 0
      src/main/resources/code_template_html/manager.component.ts.vm
  77. 28 0
      src/main/resources/code_template_html/searchType.vm
  78. 53 0
      src/main/resources/code_template_html/service.ts.vm
  79. 26 0
      src/main/resources/code_template_new/Dict.java.vm
  80. 42 0
      src/main/resources/code_template_new/DictController.java.vm
  81. 14 0
      src/main/resources/code_template_new/DictMapper.java.vm
  82. 43 0
      src/main/resources/code_template_new/DictParam.java.vm
  83. 31 0
      src/main/resources/code_template_new/DictServiceImpl.java.vm
  84. 14 0
      src/main/resources/code_template_new/DictServiceInterface.java.vm
  85. 868 0
      src/main/resources/code_template_new/api.vm
  86. 18 0
      src/main/resources/db/hsqldb/GET_SN_SEQUENCE.sql
  87. 84 0
      src/main/resources/logConfig.xml

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+/.idea
+/target
+/data
+/*.iml
+/*.ipr
+/*.iws

+ 13 - 0
README.md

@@ -0,0 +1,13 @@
+1、修改generatorConfig-write_mysql.xml文件中的	
+<classPathEntry location="D:\Project\mysql-connector-java-5.1.40.jar" />
+mysql依赖包的路径
+
+2、修改 数据源
+<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://47.112.127.131:3306/mianhuatang" userId="hboxs" password="hboxs@mysql" />
+ 
+3、MyBatisGeneratorMojo.java
+的generatorServer() 下的 mojo.projectPath
+修改生到项目的路径
+
+4、执行 MyBatisGeneratorMojo.java main 方法
+

+ 159 - 0
generatorConfig-write.xml

@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
+<!-- 配置生成器 -->
+<generatorConfiguration>
+	<!-- 指定驱动的路径 -->
+	<classPathEntry location="/Users/wuhs/workplace/maven/repo/com/oracle/ojdbc6/10.2.0.1.0/ojdbc6-10.2.0.1.0.jar"/>
+	<!-- <classPathEntry location="G:\apache-maven-3.3.9\repo\mysql\mysql-connector-java\5.1.40\mysql-connector-java-5.1.40.jar" /> --> 
+	
+	<!-- 
+    context:生成一组对象的环境 
+    id:必选,上下文id,用于在生成错误时提示
+    defaultModelType:指定生成对象的样式
+        1,conditional:类似hierarchical;
+        2,flat:所有内容(主键,blob)等全部生成在一个对象中;
+        3,hierarchical:主键生成一个XXKey对象(key class),Blob等单独生成一个对象,其他简单属性在一个对象中(record class)
+    targetRuntime:
+        1,MyBatis3:默认的值,生成基于MyBatis3.x以上版本的内容,包括XXXBySample;
+        2,MyBatis3Simple:类似MyBatis3,只是不生成XXXBySample;
+    introspectedColumnImpl:类全限定名,用于扩展MBG
+	-->
+	<context id="context1" defaultModelType="flat" targetRuntime="MyBatis3">
+	  	<!-- 
+	  		自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
+        一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
+     	-->
+    	<property name="autoDelimitKeywords" value="false"/>
+    	<!-- 生成的Java文件的编码 -->
+    	<property name="javaFileEncoding" value="UTF-8"/>
+    	<!-- 格式化java代码 -->
+    	<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
+    	<!-- 格式化XML代码 -->
+    	<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
+    	<!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
+		<property name="beginningDelimiter" value="`" />
+		<property name="endingDelimiter" value="`" />
+		
+		<!-- 利用mybatis.generator插件功能,自定义mysql分页功能 -->
+		<!-- <plugin type="com.shawn.common.mybatisGeneratorConfig.MySQLLimitPlugin"/> -->
+		<!-- 利用mybatis.generator插件功能,自定义oracle分页功能 -->
+		<plugin type="com.shawn.common.mybatisGeneratorConfig.OraclePaginationPlugin"/>
+		
+		<!-- 默认设置,去掉type即可 -->
+		<commentGenerator type="com.shawn.common.mybatisGeneratorConfig.MyCommentGenerator">
+			<!-- 去掉日期注释 -->
+	        <!-- <property name="suppressDate" value="true"/> -->
+	        <!-- 去掉所有注释 -->
+	        <!-- <property name="suppressAllComments" value="true" /> -->
+    	</commentGenerator>
+
+		<!-- 配置链接数据库 -->
+		<!-- <jdbcConnection driverClass="com.mysql.jdbc.Driver"
+			connectionURL="jdbc:mysql://localhost:3306/zhlemont"
+			userId="root" password="root" /> -->
+		<!-- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
+			connectionURL="jdbc:oracle:thin:@//10.4.33.100:1521/orcl"
+			userId="itos2" password="itos2" /> -->
+		<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
+			connectionURL="jdbc:oracle:thin:@//10.241.95.150:1521/itos"
+			userId="itos1" password="123456" />
+		<!-- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
+			connectionURL="jdbc:oracle:thin:@//10.0.115.108:1521/orcl"
+			userId="itsm" password="itsm" /> -->
+		<!-- <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
+			connectionURL="jdbc:oracle:thin:@//172.17.0.2:1521/xe"
+			userId="itos2" password="itos2" /> -->
+		<!-- java类型处理器 
+	        用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
+	        使用自定义类型转换器MyJavaTypeResolver
+    	-->
+	    <javaTypeResolver type="com.shawn.common.mybatisGeneratorConfig.MyJavaTypeResolver">
+	        <property name="forceBigDecimals" value="true"/>
+	    </javaTypeResolver>
+		
+		 <!-- java模型创建器,是必须要的元素
+        	负责:1,key类(见context的defaultModelType);
+        		 2,java类;
+        		 3,查询类
+        	targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制;
+        	targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录
+     	-->
+		<javaModelGenerator targetPackage="com.shawn.model.entity" targetProject="" >
+			<!--  for MyBatis3/MyBatis3Simple
+            	自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter;
+         	-->
+        	<property name="constructorBased" value="false"/>
+        	<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
+        	<property name="enableSubPackages" value="false"/>
+        	 <!-- for MyBatis3 / MyBatis3Simple
+            	是否创建一个不可变的类,如果为true,
+            	那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类
+         		-->
+        	<property name="immutable" value="false"/>
+        	<!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
+        	<property name="trimStrings" value="true"/>
+		</javaModelGenerator>
+		
+	    <!-- 生成SQL map的XML文件生成器,
+	        注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口),
+	            或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置
+	        targetPackage/targetProject:同javaModelGenerator
+	     -->
+		<sqlMapGenerator targetPackage="com.shawn.repository.mybatis" targetProject="" />
+		
+		<!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 
+	        targetPackage/targetProject:同javaModelGenerator
+	        type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
+	            1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
+	            2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中;
+	            3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
+	        注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER
+	    	-->
+			<javaClientGenerator targetPackage="com.shawn.repository"
+				targetProject="" type="XMLMAPPER" />
+			
+			<!-- 选择一个table来生成相关文件,可以有一个或多个table,必须要有table元素
+	        选择的table会生成一下文件:
+	        1,SQL map文件
+	        2,生成一个主键类;
+	        3,除了BLOB和主键的其他字段的类;
+	        4,包含BLOB的类;
+	        5,一个用户生成动态查询的条件类(selectByExample, deleteByExample),可选;
+	        6,Mapper接口(可选)
+	
+	        tableName(必要):要生成对象的表名;
+	        注意:大小写敏感问题。正常情况下,MBG会自动的去识别数据库标识符的大小写敏感度,在一般情况下,MBG会
+	            根据设置的schema,catalog或tablename去查询数据表,按照下面的流程:
+	            1,如果schema,catalog或tablename中有空格,那么设置的是什么格式,就精确的使用指定的大小写格式去查询;
+	            2,否则,如果数据库的标识符使用大写的,那么MBG自动把表名变成大写再查找;
+	            3,否则,如果数据库的标识符使用小写的,那么MBG自动把表名变成小写再查找;
+	            4,否则,使用指定的大小写格式查询;
+	        另外的,如果在创建表的时候,使用的""把数据库对象规定大小写,就算数据库标识符是使用的大写,在这种情况下也会使用给定的大小写来创建表名;
+	        这个时候,请设置delimitIdentifiers="true"即可保留大小写格式;
+	
+	        可选:
+	        1,schema:数据库的schema;
+	        2,catalog:数据库的catalog;
+	        3,alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName
+	        4,domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;
+	        5,enableInsert(默认true):指定是否生成insert语句;
+	        6,enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);
+	        7,enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句;
+	        8,enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);
+	        9,enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);
+	        10,enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句;
+	        11,enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询);
+	        12,enableUpdateByExample(默认true):MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);
+	        13,modelType:参考context元素的defaultModelType,相当于覆盖;
+	        14,delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性)
+	        15,delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来。默认为false,delimitIdentifiers参考context的属性
+	
+	        注意,table里面很多参数都是对javaModelGenerator,context等元素的默认属性的一个复写;
+	     -->
+  
+		<!-- <table schema="itos2" catalog="orcl" tableName="HR_POT_USER"></table> -->
+		<table schema="itos1" catalog="itos" tableName="hr_pot_favorite_pages"></table>
+  		
+	</context>
+	
+</generatorConfiguration>

+ 144 - 0
generatorConfig-write_mysql.xml

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
+<!-- 配置生成器 -->
+<generatorConfiguration>
+	<!-- 指定驱动的路径 -->
+<!-- 	<classPathEntry location="E:\apache-maven-3.3.9\repo\com\oracle\ojdbc6\10.2.0.1.0\ojdbc6-10.2.0.1.0.jar"/> -->
+	<classPathEntry location="/Users/wuhs/workplace/maven/repo/mysql/mysql-connector-java/5.1.46/mysql-connector-java-5.1.46.jar" />
+
+	<!-- 
+    context:生成一组对象的环境 
+    id:必选,上下文id,用于在生成错误时提示
+    defaultModelType:指定生成对象的样式
+        1,conditional:类似hierarchical;
+        2,flat:所有内容(主键,blob)等全部生成在一个对象中;
+        3,hierarchical:主键生成一个XXKey对象(key class),Blob等单独生成一个对象,其他简单属性在一个对象中(record class)
+    targetRuntime:
+        1,MyBatis3:默认的值,生成基于MyBatis3.x以上版本的内容,包括XXXBySample;
+        2,MyBatis3Simple:类似MyBatis3,只是不生成XXXBySample;
+    introspectedColumnImpl:类全限定名,用于扩展MBG
+	-->
+	<context id="context1" defaultModelType="flat" targetRuntime="MyBatis3">
+	  	<!-- 
+	  		自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
+        一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
+     	-->
+    	<property name="autoDelimitKeywords" value="false"/>
+    	<!-- 生成的Java文件的编码 -->
+    	<property name="javaFileEncoding" value="UTF-8"/>
+    	<!-- 格式化java代码 -->
+    	<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
+    	<!-- 格式化XML代码 -->
+    	<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
+    	<!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
+		<property name="beginningDelimiter" value="`" />
+		<property name="endingDelimiter" value="`" />
+		
+		<!-- 利用mybatis.generator插件功能,自定义mysql分页功能 -->
+		<plugin type="com.shawn.common.mybatisGeneratorConfig.MySQLLimitPlugin"/>
+		<!-- 利用mybatis.generator插件功能,自定义oracle分页功能 -->
+		<!-- <plugin type="com.shawn.common.mybatisGeneratorConfig.OraclePaginationPlugin"/> -->
+		
+		<!-- 默认设置,去掉type即可 -->
+		<commentGenerator type="com.shawn.common.mybatisGeneratorConfig.MyCommentGenerator">
+			<!-- 去掉日期注释 -->
+	        <!-- <property name="suppressDate" value="true"/> -->
+	        <!-- 去掉所有注释 -->
+	        <!-- <property name="suppressAllComments" value="true" /> -->
+    	</commentGenerator>
+
+		<!-- 数据源 mysql-->
+		<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://47.112.127.131:3306/mianhuatang" userId="hboxs" password="hboxs@mysql" />
+		<!-- java类型处理器
+	        用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
+	        使用自定义类型转换器MyJavaTypeResolver
+    	-->
+	    <javaTypeResolver type="com.shawn.common.mybatisGeneratorConfig.MyJavaTypeResolver">
+	        <property name="forceBigDecimals" value="true"/>
+	    </javaTypeResolver>
+		
+		 <!-- java模型创建器,是必须要的元素
+        	负责:1,key类(见context的defaultModelType);
+        		 2,java类;
+        		 3,查询类
+        	targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制;
+        	targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录
+     	-->
+		<javaModelGenerator targetPackage="com.shawn.model.entity" targetProject="" >
+			<!--  for MyBatis3/MyBatis3Simple
+            	自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter;
+         	-->
+        	<property name="constructorBased" value="false"/>
+        	<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
+        	<property name="enableSubPackages" value="false"/>
+        	 <!-- for MyBatis3 / MyBatis3Simple
+            	是否创建一个不可变的类,如果为true,
+            	那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类
+         		-->
+        	<property name="immutable" value="false"/>
+        	<!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
+        	<property name="trimStrings" value="true"/>
+		</javaModelGenerator>
+		
+	    <!-- 生成SQL map的XML文件生成器,
+	        注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口),
+	            或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置
+	        targetPackage/targetProject:同javaModelGenerator
+	     -->
+		<sqlMapGenerator targetPackage="com.shawn.repository.mybatis" targetProject="" />
+		
+		<!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 
+	        targetPackage/targetProject:同javaModelGenerator
+	        type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
+	            1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
+	            2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中;
+	            3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
+	        注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER
+	    	-->
+			<javaClientGenerator targetPackage="com.shawn.repository"
+				targetProject="" type="XMLMAPPER" />
+			
+			<!-- 选择一个table来生成相关文件,可以有一个或多个table,必须要有table元素
+	        选择的table会生成一下文件:
+	        1,SQL map文件
+	        2,生成一个主键类;
+	        3,除了BLOB和主键的其他字段的类;
+	        4,包含BLOB的类;
+	        5,一个用户生成动态查询的条件类(selectByExample, deleteByExample),可选;
+	        6,Mapper接口(可选)
+	
+	        tableName(必要):要生成对象的表名;
+	        注意:大小写敏感问题。正常情况下,MBG会自动的去识别数据库标识符的大小写敏感度,在一般情况下,MBG会
+	            根据设置的schema,catalog或tablename去查询数据表,按照下面的流程:
+	            1,如果schema,catalog或tablename中有空格,那么设置的是什么格式,就精确的使用指定的大小写格式去查询;
+	            2,否则,如果数据库的标识符使用大写的,那么MBG自动把表名变成大写再查找;
+	            3,否则,如果数据库的标识符使用小写的,那么MBG自动把表名变成小写再查找;
+	            4,否则,使用指定的大小写格式查询;
+	        另外的,如果在创建表的时候,使用的""把数据库对象规定大小写,就算数据库标识符是使用的大写,在这种情况下也会使用给定的大小写来创建表名;
+	        这个时候,请设置delimitIdentifiers="true"即可保留大小写格式;
+	
+	        可选:
+	        1,schema:数据库的schema;
+	        2,catalog:数据库的catalog;
+	        3,alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName
+	        4,domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;
+	        5,enableInsert(默认true):指定是否生成insert语句;
+	        6,enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);
+	        7,enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句;
+	        8,enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);
+	        9,enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);
+	        10,enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句;
+	        11,enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询);
+	        12,enableUpdateByExample(默认true):MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);
+	        13,modelType:参考context元素的defaultModelType,相当于覆盖;
+	        14,delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性)
+	        15,delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来。默认为false,delimitIdentifiers参考context的属性
+	
+	        注意,table里面很多参数都是对javaModelGenerator,context等元素的默认属性的一个复写;
+	     -->
+  
+		<!-- <table schema="itos1" catalog="itos" tableName="HR_TASK_RELATION"></table> -->
+		<table tableName="t_sugar_do"></table>
+	</context>
+	
+</generatorConfiguration>

+ 234 - 0
pom.xml

@@ -0,0 +1,234 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.shawn</groupId>
+    <artifactId>TestServer</artifactId>
+    <version>1.0.0</version>
+	<packaging>jar</packaging>
+	<!-- <packaging>war</packaging> -->
+	
+    <!-- Metadata of the project -->
+    <name>TestServer</name>
+    <description>A back-end RESTful framework, integrated by Spring Boot and MyBatis</description>
+
+    <!-- Inherit defaults from Spring Boot -->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>1.4.2.RELEASE</version>
+    </parent>
+
+    <properties>
+        <!-- Generic properties -->
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+        <!-- Other properties -->
+        <mybatis-spring-boot-starter.version>1.1.1</mybatis-spring-boot-starter.version>
+        <mysql-connector-java.version>5.1.40</mysql-connector-java.version>
+        <commons-lang3.version>3.4</commons-lang3.version>
+        <commons-collections4.version>4.1</commons-collections4.version>
+        <spring.version>4.3.4.RELEASE</spring.version>
+    </properties>
+
+    <dependencies>
+        <!-- Spring and Spring Boot dependencies -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>  
+	            <exclusion>  
+	                <groupId>org.springframework.boot</groupId>  
+	                <artifactId>spring-boot-starter-tomcat</artifactId>
+	            </exclusion>  
+           </exclusions>  
+        </dependency>
+        
+		
+		<!--修改Tomcat依赖时态,本地开发依然可以调用内嵌tomcat-->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-tomcat</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!-- Spring Security Oauth2 -->
+        <dependency>
+            <groupId>org.springframework.security.oauth</groupId>
+            <artifactId>spring-security-oauth2</artifactId>
+        </dependency>
+
+        <!-- MyBatis -->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>${mybatis-spring-boot-starter.version}</version>
+        </dependency>
+        <!-- 数据库连接池 -->
+		<dependency>
+		    <groupId>com.alibaba</groupId>
+		    <artifactId>druid</artifactId>
+		    <version>1.0.29</version>
+		</dependency>
+        <!-- MySQL -->
+        <!-- <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>${mysql-connector-java.version}</version>
+        </dependency> -->
+
+        <!-- Databases - Uses HSQL by default -->
+        <!-- <dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <scope>runtime</scope>
+        </dependency> -->
+        
+		<!--Oracle JDBC Driver-->
+<!--            <dependency>-->
+<!--                <groupId>com.oracle</groupId>-->
+<!--                <artifactId>ojdbc6</artifactId>-->
+<!--                <version>10.2.0.1.0</version>-->
+<!--            </dependency>-->
+		
+		<!--postgresql JDBC Driver-->	
+		<!-- <dependency>
+			<groupId>org.postgresql</groupId>
+			<artifactId>postgresql</artifactId>
+			<version>42.0.0</version>
+		</dependency> -->
+		
+		<!--spark hive-jdbc -->
+        <!-- <dependency>
+            <groupId>org.apache.spark</groupId>
+            <artifactId>spark-hive-thriftserver_2.11</artifactId>
+            <version>2.0.1</version>
+            <exclusions>
+            	<exclusion>
+            		<groupId>org.slf4j</groupId>
+            		<artifactId>slf4j-log4j12</artifactId>
+            	</exclusion>
+            </exclusions>
+        </dependency> -->
+		
+        <!-- Lombok - Make Java look less redundant -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <!-- <scope>provided</scope> -->
+        </dependency>
+
+        <!-- Apache Commons -->
+        <dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.6</version>
+		</dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>${commons-collections4.version}</version>
+        </dependency>
+        <!--mybatis代码生成  -->
+        <dependency>
+		    <groupId>org.mybatis.generator</groupId>
+		    <artifactId>mybatis-generator-maven-plugin</artifactId>
+		    <version>1.3.5</version>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.apache.velocity</groupId>
+			<artifactId>velocity</artifactId>
+			<version>1.7</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.maven</groupId>
+			<artifactId>maven-project</artifactId>
+			<version>3.0-alpha-2</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.maven</groupId>
+			<artifactId>maven-plugin-api</artifactId>
+			<version>3.0.4</version>
+		</dependency>
+		<!-- <dependency>  
+		    <groupId>myjar</groupId>
+		    <artifactId>CodeGenerator</artifactId>
+		     <version>0.0.1</version>
+		</dependency> -->
+	<dependency>
+		    <groupId>org.apache.poi</groupId>
+		    <artifactId>poi</artifactId>
+		    <version>3.12</version>
+		</dependency>
+		<dependency>
+		    <groupId>org.apache.poi</groupId>
+		    <artifactId>poi-ooxml</artifactId>
+		    <version>3.12</version>
+		</dependency>
+		<dependency>      
+		    <groupId>net.sf.json-lib</groupId>     
+		    <artifactId>json-lib</artifactId>      
+		    <version>2.4</version>
+		    <classifier>jdk15</classifier>        
+		</dependency>
+		 <dependency>
+		    <groupId>org.apache.httpcomponents</groupId>
+		    <artifactId>httpclient</artifactId>
+		    <version>4.5.2</version>
+		</dependency>
+		<dependency>
+		    <groupId>com.alibaba</groupId>
+		    <artifactId>fastjson</artifactId>
+		    <version>1.2.46</version>
+		</dependency>
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger2</artifactId>
+			<version>2.8.0</version>
+		</dependency>
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger-ui</artifactId>
+			<version>2.8.0</version>
+		</dependency>
+		
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- Package the project as an executable jar -->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <!-- Set the character encoding for the JVM -->
+                <configuration>
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 23 - 0
src/main/java/com/shawn/Application.java

@@ -0,0 +1,23 @@
+package com.shawn;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+/**
+ * SpringBoot-MyBatis Application.
+ * @author 吴洪双
+ */
+@SpringBootApplication
+public class Application extends SpringBootServletInitializer{
+	@Override
+	protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
+		return application.sources(Application.class);
+	}
+	
+    public static void main(String[] args) throws Exception {
+        SpringApplication.run(Application.class, args);
+    }
+
+}

+ 30 - 0
src/main/java/com/shawn/common/dbConfig/DynamicDataSource.java

@@ -0,0 +1,30 @@
+package com.shawn.common.dbConfig;
+
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+import com.shawn.constant.DatabaseType;
+
+public class DynamicDataSource extends AbstractRoutingDataSource {
+	//保存一个线程安全的DatabaseType 容器
+	private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();
+	
+	public static void setDatabaseType(DatabaseType type){
+		contextHolder.set(type);
+	}
+	
+	public static DatabaseType getDatabaseType(){
+		return contextHolder.get();
+	}
+	
+	@Override
+	protected Object determineCurrentLookupKey() {
+		return getDatabaseType();
+	}
+
+	
+	public static void clearDataSourceType() {
+        contextHolder.remove();
+    }
+
+
+}

+ 127 - 0
src/main/java/com/shawn/common/dbConfig/MyBatisConfig.java

@@ -0,0 +1,127 @@
+package com.shawn.common.dbConfig;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+import com.shawn.constant.DatabaseType;
+
+
+/*
+ * springboot 默认集成mybatis的基本入口  
+ * 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
+ * 2)创建SqlSessionFactory
+ * 3)配置事务管理器除非需要使用事务否则不用配置
+ */
+@Configuration // 该注解类似于spring配置文件
+@EnableTransactionManagement //开启事务用的注解
+//@MapperScan("com.shawn.repository")//必须加这个,不加报错,如果不加,也可以在每个mapper上添加@Mapper注释
+@MapperScan(basePackages="com/shawn/repository")
+public class MyBatisConfig {
+	
+	@Autowired
+	private Environment env;
+	 /**
+     * 创建数据源(数据源的名称:方法名可以取为XXXDataSource(),XXX为数据库名称,该名称也就是数据源的名称)
+     */
+    @Bean
+    public DataSource dataSource_db1() throws Exception {
+        Properties props = new Properties();
+        props.put("driverClassName", env.getProperty("jdbc.driverClassName"));
+        props.put("url", env.getProperty("jdbc.url"));
+        props.put("username", env.getProperty("jdbc.username"));
+        props.put("password", env.getProperty("jdbc.password"));
+        
+        props.put("initialSize", "5");//初始化连接数量 
+        props.put("maxActive", "10");//最大并发连接数
+        props.put("minIdle", "3");//最小空闲连接数
+        props.put("maxWait", "60000");//配置获取连接等待超时的时间
+		
+        return DruidDataSourceFactory.createDataSource(props);
+    }
+
+    @Bean
+    public DataSource dataSource_db2() throws Exception {
+        Properties props = new Properties();
+        props.put("driverClassName", env.getProperty("jdbc2.driverClassName"));
+        props.put("url", env.getProperty("jdbc2.url"));
+        props.put("username", env.getProperty("jdbc2.username"));
+        props.put("password", env.getProperty("jdbc2.password"));
+        return DruidDataSourceFactory.createDataSource(props);
+    }
+    @Bean
+    public DataSource dataSource_db3() throws Exception {
+    	Properties props = new Properties();
+    	props.put("driverClassName", env.getProperty("jdbc3.driverClassName"));
+    	props.put("url", env.getProperty("jdbc3.url"));
+    	props.put("username", env.getProperty("jdbc3.username"));
+    	props.put("password", env.getProperty("jdbc3.password"));
+    	return DruidDataSourceFactory.createDataSource(props);
+    }
+
+    /**
+     * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
+     * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
+     * @Lazy(true) 延时初始化,避免循环引用
+     */
+    @Bean
+    @Primary
+    public DynamicDataSource dataSource(@Qualifier("dataSource_db1") @Lazy(true) DataSource dataSource_db1,
+            @Qualifier("dataSource_db2") @Lazy(true) DataSource dataSource_db2,
+            @Qualifier("dataSource_db3") @Lazy(true) DataSource dataSource_db3) {
+        Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DatabaseType.db1, dataSource_db1);
+        targetDataSources.put(DatabaseType.db2, dataSource_db2);
+        targetDataSources.put(DatabaseType.db3, dataSource_db3);
+        DynamicDataSource dataSource = new DynamicDataSource();
+        dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
+        dataSource.setDefaultTargetDataSource(dataSource_db1);// 默认的datasource设置为myTestDbDataSource
+
+        return dataSource;
+    }
+
+    /**
+     * 根据数据源创建SqlSessionFactory
+     */
+    @Bean
+    public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
+        SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
+        fb.setDataSource(ds);// 指定数据源(这个必须有,否则报错)
+     // 下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
+        fb.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package"));// 指定基包
+        fb.setMapperLocations(
+                new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapper-locations")));
+
+        return fb.getObject();
+    }
+
+    /**
+     * 配置事务管理器
+     */
+    @Bean
+    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
+        return new DataSourceTransactionManager(dataSource);
+    }
+
+}
+
+
+
+

+ 10 - 0
src/main/java/com/shawn/common/myAnnotation/CamelCaseToUnderscore.java

@@ -0,0 +1,10 @@
+package com.shawn.common.myAnnotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+@Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.ANNOTATION_TYPE})  
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CamelCaseToUnderscore {
+
+}

+ 39 - 0
src/main/java/com/shawn/common/myAnnotation/CamelCaseToUnderscoreFormatAnnotationFormatterFactory.java

@@ -0,0 +1,39 @@
+package com.shawn.common.myAnnotation;
+
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.format.AnnotationFormatterFactory;
+import org.springframework.format.Parser;
+import org.springframework.format.Printer;
+
+public class CamelCaseToUnderscoreFormatAnnotationFormatterFactory 
+implements AnnotationFormatterFactory<CamelCaseToUnderscore>{//①指定可以解析/格式化的字段注解类型
+	private final Set<Class<?>> fieldTypes;  
+    private final CamelCaseToUnderscoreFormatter formatter;  
+    public CamelCaseToUnderscoreFormatAnnotationFormatterFactory() {  
+        Set<Class<?>> set = new HashSet<Class<?>>();  
+        set.add(String.class);  
+        this.fieldTypes = set;  
+        this.formatter = new CamelCaseToUnderscoreFormatter();//此处使用之前定义的Formatter实现  
+    }  
+    
+    //②指定可以被解析/格式化的字段类型集合  
+    @Override  
+    public Set<Class<?>> getFieldTypes() {  
+        return fieldTypes;  
+    }  
+    //③根据注解信息和字段类型获取解析器  
+    @Override  
+    public Parser<?> getParser(CamelCaseToUnderscore annotation, Class<?> fieldType) {  
+        return formatter;  
+    }  
+    //④根据注解信息和字段类型获取格式化器  
+    @Override     
+    public Printer<?> getPrinter(CamelCaseToUnderscore annotation, Class<?> fieldType) {  
+        return formatter;  
+    }  
+
+
+}

+ 51 - 0
src/main/java/com/shawn/common/myAnnotation/CamelCaseToUnderscoreFormatter.java

@@ -0,0 +1,51 @@
+package com.shawn.common.myAnnotation;
+
+import java.text.ParseException;
+import java.util.Locale;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.format.Formatter;
+
+public class CamelCaseToUnderscoreFormatter implements Formatter<String> {
+
+	@Override
+	public String print(String paramT, Locale paramLocale) {
+		return convertCamelCaseToUnderscore(paramT);
+	}
+
+	@Override
+	public String parse(String paramString, Locale paramLocale) throws ParseException {
+		// TODO Auto-generated method stub
+		return convertCamelCaseToUnderscore(paramString);
+	}
+
+	public static String convertCamelCaseToUnderscore(String str) {
+		String result = "";
+		String[] parts = str.split(",");
+		for (int i = 0; i < parts.length; i++) {
+			String part = parts[i];
+			String[] fields = part.split(" ");
+			for (String field : fields) {
+				field = field.trim();
+				String _str = StringUtils.upperCase(field);
+				if(!"ASC".equals(StringUtils.upperCase(field))&&!"DESC".equals(StringUtils.upperCase(field))) {
+					String[] strings = StringUtils.splitByCharacterTypeCamelCase(field);
+					_str = StringUtils.join(strings, "_");
+					_str = StringUtils.upperCase(_str);
+				}
+				System.out.println(_str);
+				result = result + " " + _str;
+			}
+			if(i+1!= parts.length) {
+				result = result + ",";
+			}
+		}
+		
+		return result;
+	}
+	
+//	public static void main(String[] args) {
+//		String result = convertCamelCaseToUnderscore("myFi desc,myEntity asc");
+//		System.out.println(result);
+//	}
+}

+ 55 - 0
src/main/java/com/shawn/common/myAnnotation/GenHtml.java

@@ -0,0 +1,55 @@
+package com.shawn.common.myAnnotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+@Target({ java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD,
+		java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface GenHtml {
+	/**
+	 * 字段描述
+	 * 
+	 * @return
+	 */
+	String description();
+
+	/**
+	 * 是否为主键
+	 */
+	boolean isPrimaryKey() default false;
+	/**
+	 * 作为查询条件展示
+	 */
+	boolean isSearch() default true;
+	/**
+	 * 作为表格字段展示
+	 */
+	boolean isTable() default true;
+	/**
+	 * 控件值,checkbox、radioButton专用
+	 */
+	String[] valueList() default {};
+	/**
+	 * 控件标签,checkbox、radioButton专用
+	 */
+	String[] labelList() default {};
+	
+	/**
+	 * 控件类型
+	 */
+	SearchType searchType() default SearchType.input;
+	
+	
+	public static enum SearchType {
+		input , textarea ,dropdown, multiSelect , checkbox ,radioButton ,inputSwitch,date,time,dateTime,dateRange ;
+
+		private SearchType() {
+		}
+	}
+	
+
+}

+ 13 - 0
src/main/java/com/shawn/common/myAnnotation/HtmlHead.java

@@ -0,0 +1,13 @@
+package com.shawn.common.myAnnotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+@Target({ java.lang.annotation.ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HtmlHead {
+	String value();
+}

+ 37 - 0
src/main/java/com/shawn/common/myFormat/DateSerializer.java

@@ -0,0 +1,37 @@
+package com.shawn.common.myFormat;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+/**
+ * @author wuhs
+ * 解决json日期绑定问题:
+ *Can not deserialize value of type java.util.Date from String "2017-10-31 14:51:18": not a valid representation (error: Failed to parse Date value '2017-10-31 14:51:18': Can not parse date "2017-10-31 14:51:18Z": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSS'Z''
+ *
+ *使用方法:在需要绑定的字段加 @JsonDeserialize(using=DateSerializer.class)
+ */
+public class DateSerializer extends JsonDeserializer<Date> {
+
+    private SimpleDateFormat dateFormat = new SimpleDateFormat(
+            "yyyy-MM-dd HH:mm:ss");
+
+    @Override
+    public Date deserialize(JsonParser paramJsonParser,
+            DeserializationContext paramDeserializationContext)
+            throws IOException, JsonProcessingException {
+        String str = paramJsonParser.getText().trim();
+        try {
+            return dateFormat.parse(str);
+        } catch (ParseException e) {
+
+        }
+        return paramDeserializationContext.parseDate(str);
+    }
+}

+ 304 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/MyCommentGenerator.java

@@ -0,0 +1,304 @@
+package com.shawn.common.mybatisGeneratorConfig;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import org.mybatis.generator.api.CommentGenerator;
+import org.mybatis.generator.api.IntrospectedColumn;
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.dom.java.CompilationUnit;
+import org.mybatis.generator.api.dom.java.Field;
+import org.mybatis.generator.api.dom.java.InnerClass;
+import org.mybatis.generator.api.dom.java.InnerEnum;
+import org.mybatis.generator.api.dom.java.JavaElement;
+import org.mybatis.generator.api.dom.java.Method;
+import org.mybatis.generator.api.dom.java.Parameter;
+import org.mybatis.generator.api.dom.java.TopLevelClass;
+import org.mybatis.generator.api.dom.xml.XmlElement;
+import org.mybatis.generator.config.MergeConstants;
+import org.mybatis.generator.config.PropertyRegistry;
+import org.mybatis.generator.internal.util.StringUtility;
+/**
+ * 
+* @ClassName: MyCommentGenerator 
+* @Description: mybatis generator 自定义comment生成器 (自定义注释)
+* @author 吴洪双
+* @date 2017年4月17日 下午6:06:29 
+*
+ */
+public class MyCommentGenerator implements CommentGenerator {
+
+    private Properties properties;
+    private Properties systemPro;
+    private boolean suppressDate;
+    private boolean suppressAllComments;
+    private String currentDateStr;
+
+    public MyCommentGenerator() {
+        super();
+        properties = new Properties();
+        systemPro = System.getProperties();
+        suppressDate = false;
+        suppressAllComments = false;
+        currentDateStr = (new SimpleDateFormat("yyyy-MM-dd")).format(new Date());
+    }
+
+    public void addJavaFileComment(CompilationUnit compilationUnit) {
+        // add no file level comments by default
+        return;
+    }
+
+    /**
+     * Adds a suitable comment to warn users that the element was generated, and
+     * when it was generated.
+     */
+    public void addComment(XmlElement xmlElement) {
+        return;
+    }
+
+    public void addRootComment(XmlElement rootElement) {
+        // add no document level comments by default
+        return;
+    }
+
+    public void addConfigurationProperties(Properties properties) {
+        this.properties.putAll(properties);
+
+        suppressDate = StringUtility.isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
+
+        suppressAllComments = StringUtility.isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
+    }
+
+    /**
+     * This method adds the custom javadoc tag for. You may do nothing if you do
+     * not wish to include the Javadoc tag - however, if you do not include the
+     * Javadoc tag then the Java merge capability of the eclipse plugin will
+     * break.
+     *
+     * @param javaElement the java element
+     */
+    protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
+        javaElement.addJavaDocLine(" *");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(MergeConstants.NEW_ELEMENT_TAG);
+        if (markAsDoNotDelete) {
+            sb.append(" do_not_delete_during_merge");
+        }
+        String s = getDateString();
+        if (s != null) {
+            sb.append(' ');
+            sb.append(s);
+        }
+        javaElement.addJavaDocLine(sb.toString());
+    }
+
+    /**
+     * This method returns a formated date string to include in the Javadoc tag
+     * and XML comments. You may return null if you do not want the date in
+     * these documentation elements.
+     *
+     * @return a string representing the current timestamp, or null
+     */
+    protected String getDateString() {
+        String result = null;
+        if (!suppressDate) {
+            result = currentDateStr;
+        }
+        return result;
+    }
+
+    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
+        if (suppressAllComments) {
+            return;
+        }
+        if(null!=introspectedTable.getFullyQualifiedTable()){
+        	
+        	StringBuilder sb = new StringBuilder();
+        	innerClass.addJavaDocLine("/**");
+        	sb.append(" * ");
+        	sb.append(introspectedTable.getFullyQualifiedTable());
+        	sb.append(" ");
+        	sb.append(getDateString());
+        	innerClass.addJavaDocLine(sb.toString());
+        	innerClass.addJavaDocLine(" */");
+        }
+    }
+
+    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
+        if (suppressAllComments) {
+            return;
+        }
+        if(null!=introspectedTable.getFullyQualifiedTable()){
+        	StringBuilder sb = new StringBuilder();
+        	
+        	innerEnum.addJavaDocLine("/**");
+        	//      addJavadocTag(innerEnum, false);
+        	sb.append(" * ");
+        	sb.append(introspectedTable.getFullyQualifiedTable());
+        	innerEnum.addJavaDocLine(sb.toString());
+        	innerEnum.addJavaDocLine(" */");
+        }
+    }
+    public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
+        if (suppressAllComments) {
+            return;
+        }
+        if(null!=introspectedTable.getFullyQualifiedTable()){
+        	
+        	StringBuilder sb = new StringBuilder();
+        	
+        	field.addJavaDocLine("/**");
+        	sb.append(" * ");
+        	sb.append(introspectedTable.getFullyQualifiedTable());
+        	field.addJavaDocLine(sb.toString());
+        	field.addJavaDocLine(" */");
+        }
+    }
+    
+    public void addFieldComment(Field field, IntrospectedTable introspectedTable,
+                                IntrospectedColumn introspectedColumn) {
+        if (suppressAllComments) {
+            return;
+        }
+        if(null!=introspectedColumn.getRemarks()){
+        	
+        	StringBuilder sb = new StringBuilder();
+        	
+        	field.addJavaDocLine("/**");
+        	sb.append(" * ");
+        	sb.append(introspectedColumn.getRemarks());
+        	field.addJavaDocLine(sb.toString());
+        	
+        	//      addJavadocTag(field, false);
+        	
+        	field.addJavaDocLine(" */");
+        }
+        /*//添加注解
+    	String desc = null==introspectedColumn.getRemarks()?field.getName():introspectedColumn.getRemarks();
+    	String genHtmlAnnotation = "@GenHtml(description=\""+desc+"\"";
+    	
+    	List<IntrospectedColumn> primaryKeyList = introspectedTable.getPrimaryKeyColumns();
+    	for (IntrospectedColumn primaryKey : primaryKeyList) {
+			if(primaryKey.getJavaProperty().equals(introspectedColumn.getJavaProperty())) {
+				genHtmlAnnotation = genHtmlAnnotation+",isPrimaryKey=true";
+			}
+		}
+    	genHtmlAnnotation = genHtmlAnnotation+",isSearch=true";
+    	genHtmlAnnotation = genHtmlAnnotation+",isTable=true";
+    	if(introspectedColumn.getFullyQualifiedJavaType().getShortName().equals("Date")) {
+    		genHtmlAnnotation = genHtmlAnnotation+",searchType=SearchType.dateTime";
+    		field.addAnnotation("@DateTimeFormat(pattern=\"yyyy-MM-dd HH:mm:ss\")");
+    		field.addAnnotation("@JsonDeserialize(using=DateSerializer.class)");
+    		
+    	}else {
+    		genHtmlAnnotation = genHtmlAnnotation+",searchType=SearchType.input";
+    	}
+    	genHtmlAnnotation = genHtmlAnnotation+")";
+    	
+    	field.addAnnotation(genHtmlAnnotation);*/
+    }
+
+
+    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
+    	/*//添加注解
+    	String desc = null==introspectedTable.getRemarks()?introspectedTable.getFullyQualifiedTable().getDomainObjectName():introspectedTable.getRemarks();
+    	topLevelClass.addAnnotation("@HtmlHead(\""+desc+"\")");
+    	//添加import
+    	topLevelClass.addImportedType("com.shawn.common.myAnnotation.GenHtml");
+    	topLevelClass.addImportedType("com.shawn.common.myAnnotation.HtmlHead");
+    	topLevelClass.addImportedType("com.shawn.common.myAnnotation.GenHtml.SearchType");
+    	topLevelClass.addImportedType("org.springframework.format.annotation.DateTimeFormat");*/
+    }
+
+    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
+        if (suppressAllComments) {
+            return;
+        }
+        //      method.addJavaDocLine("/**");
+        //      addJavadocTag(method, false);
+        //      method.addJavaDocLine(" */");
+    }
+
+    public void addGetterComment(Method method, IntrospectedTable introspectedTable,
+                                 IntrospectedColumn introspectedColumn) {
+        if (suppressAllComments) {
+            return;
+        }
+        if(null!=introspectedColumn.getRemarks()){
+        	
+        	method.addJavaDocLine("/**");
+        	
+        	StringBuilder sb = new StringBuilder();
+        	sb.append(" * ");
+        	sb.append(introspectedColumn.getRemarks());
+        	method.addJavaDocLine(sb.toString());
+        	
+        	sb.setLength(0);
+        	sb.append(" * @return ");
+        	sb.append(introspectedColumn.getActualColumnName());
+        	sb.append(" ");
+        	sb.append(introspectedColumn.getRemarks());
+        	method.addJavaDocLine(sb.toString());
+        	
+        	//      addJavadocTag(method, false);
+        	
+        	method.addJavaDocLine(" */");
+        }
+    }
+
+    public void addSetterComment(Method method, IntrospectedTable introspectedTable,
+                                 IntrospectedColumn introspectedColumn) {
+        if (suppressAllComments) {
+            return;
+        }
+
+        if(null!=introspectedColumn.getRemarks()){
+        	
+        	method.addJavaDocLine("/**");
+        	StringBuilder sb = new StringBuilder();
+        	sb.append(" * ");
+        	sb.append(introspectedColumn.getRemarks());
+        	method.addJavaDocLine(sb.toString());
+        	
+        	Parameter parm = method.getParameters().get(0);
+        	sb.setLength(0);
+        	sb.append(" * @param ");
+        	sb.append(parm.getName());
+        	sb.append(" ");
+        	sb.append(introspectedColumn.getRemarks());
+        	method.addJavaDocLine(sb.toString());
+        	
+        	//      addJavadocTag(method, false);
+        	
+        	method.addJavaDocLine(" */");
+        }
+    }
+
+    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
+        if (suppressAllComments) {
+            return;
+        }
+
+        if(null!=introspectedTable.getFullyQualifiedTable()){
+        	
+        	StringBuilder sb = new StringBuilder();
+        	
+        	innerClass.addJavaDocLine("/**");
+        	sb.append(" * ");
+        	sb.append(introspectedTable.getFullyQualifiedTable());
+        	innerClass.addJavaDocLine(sb.toString());
+        	
+        	sb.setLength(0);
+        	sb.append(" * @author ");
+        	sb.append(systemPro.getProperty("user.name"));
+        	sb.append(" ");
+        	sb.append(currentDateStr);
+        	
+        	//      addJavadocTag(innerClass, markAsDoNotDelete);
+        	
+        	innerClass.addJavaDocLine(" */");
+        }
+    }
+}

+ 51 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/MyJavaTypeResolver.java

@@ -0,0 +1,51 @@
+package com.shawn.common.mybatisGeneratorConfig;
+
+import java.sql.Types;
+
+import org.mybatis.generator.api.IntrospectedColumn;
+import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
+import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
+
+/**
+ * @ClassName: MyJavaTypeResolver
+ * @Description: 重写mybatis generator 的类型转换,强制将 DECIMAL、NUMERIC 类型转换为java long类型
+ * @author 吴洪双
+ * @date 2017年4月17日 下午3:53:01
+ *
+ */
+public class MyJavaTypeResolver extends JavaTypeResolverDefaultImpl {
+
+	@Override
+	public FullyQualifiedJavaType calculateJavaType(IntrospectedColumn introspectedColumn) {
+		// TODO Auto-generated method stub
+		FullyQualifiedJavaType answer;
+		JdbcTypeInformation jdbcTypeInformation = typeMap.get(introspectedColumn.getJdbcType());
+
+		switch (introspectedColumn.getJdbcType()) {
+		case Types.DECIMAL:
+		case Types.NUMERIC:
+			if (introspectedColumn.getScale() > 0) {// 如果包含小数点则转换成float
+				answer = new FullyQualifiedJavaType(Float.class.getName());
+			} else {
+				/*
+				 * if ( introspectedColumn.getLength() > 18 || forceBigDecimals) { answer = new
+				 * FullyQualifiedJavaType(BigDecimal.class .getName()); } else if
+				 * (introspectedColumn.getLength() > 9) { answer = new
+				 * FullyQualifiedJavaType(Long.class.getName()); } else if
+				 * (introspectedColumn.getLength() > 4) { answer = new
+				 * FullyQualifiedJavaType(Integer.class.getName()); } else { answer = new
+				 * FullyQualifiedJavaType(Short.class.getName()); }
+				 */
+				answer = new FullyQualifiedJavaType(Long.class.getName());
+			}
+			break;
+
+		default:
+			answer = jdbcTypeInformation.getFullyQualifiedJavaType();
+			break;
+		}
+
+		return answer;
+	}
+
+}

+ 284 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/MyPluginAdapter.java

@@ -0,0 +1,284 @@
+package com.shawn.common.mybatisGeneratorConfig;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.project.MavenProject;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+import org.mybatis.generator.api.IntrospectedColumn;
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.Plugin;
+import org.mybatis.generator.api.PluginAdapter;
+import org.mybatis.generator.api.ShellCallback;
+import org.mybatis.generator.api.dom.java.Field;
+import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
+import org.mybatis.generator.api.dom.java.JavaVisibility;
+import org.mybatis.generator.api.dom.java.Method;
+import org.mybatis.generator.api.dom.java.Parameter;
+import org.mybatis.generator.api.dom.java.PrimitiveTypeWrapper;
+import org.mybatis.generator.api.dom.java.TopLevelClass;
+import org.mybatis.generator.api.dom.xml.Attribute;
+import org.mybatis.generator.api.dom.xml.Document;
+import org.mybatis.generator.api.dom.xml.TextElement;
+import org.mybatis.generator.api.dom.xml.XmlElement;
+import org.mybatis.generator.exception.ShellException;
+import org.mybatis.generator.internal.DefaultShellCallback;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.shawn.common.mybatisGeneratorConfig.codeGenerator.MyBatisGeneratorMojo;
+import com.shawn.common.mybatisGeneratorConfig.codeGenerator.TextUtil;
+import com.shawn.web.exception.MyException;
+
+/**
+* @ClassName: MyPluginAdapter 
+* @Description: mybatis generator 自定义PluginAdapter
+* @author 吴洪双
+* @date 2017年4月17日 下午3:44:44 
+*
+ */
+public abstract class MyPluginAdapter extends PluginAdapter{
+	@Override
+    public boolean validate(List<String> list) {
+        return true;
+    }
+	/**
+     * 为每个Example类添加limit和offset属性已经set、get方法
+     */
+    @Override
+    public abstract boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable);
+    /**
+     * 为Mapper.xml的selectByExample添加limit
+     */
+    @Override
+    public abstract boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
+            IntrospectedTable introspectedTable);
+    /**
+     * 为xml拼接新sql
+     */
+    @Override  
+    public boolean sqlMapDocumentGenerated(Document document,  
+            IntrospectedTable introspectedTable) {  
+        XmlElement parentElement = document.getRootElement();  
+        
+        XmlElement insertBatchElement = creatInsertBatchXml_mysql(introspectedTable);
+//        XmlElement insertBatchElement = creatInsertBatchXml_oracle(introspectedTable);
+        parentElement.addElement(insertBatchElement);
+        
+        XmlElement deleteBatchElement = creatDeleteBatchXml(introspectedTable);
+        if(null!=deleteBatchElement) {
+        	parentElement.addElement(deleteBatchElement);  
+        }
+        
+        XmlElement updateBatchElement = creatUpdateBatchXml(introspectedTable);
+        if(null!=updateBatchElement) {
+        	parentElement.addElement(updateBatchElement);  
+        }
+        
+        return super.sqlMapDocumentGenerated(document, introspectedTable);  
+    }
+    
+//	@Override
+//	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable)
+//	{
+////		topLevelClass.setSuperClass("PageBean");//生成继承父类
+////		topLevelClass.addImportedType("com.shawn.model.bean.PageBean");
+//		topLevelClass.addImportedType("com.fasterxml.jackson.annotation.JsonIgnore");
+//		
+//		List<IntrospectedColumn> keyList =introspectedTable.getPrimaryKeyColumns();
+//		FullyQualifiedJavaType keyType = keyList.size()>0?keyList.get(0).getFullyQualifiedJavaType():FullyQualifiedJavaType.getStringInstance();
+//		IntrospectedColumn key = keyList.size()>0?keyList.get(0):null;
+//		String keyName = key==null?"":key.getJavaProperty();
+//		
+//		//生成主键set方法
+//		Method setPrimaryKey = new Method();
+//		setPrimaryKey.addJavaDocLine("/**自定义统一方法设置主键**/");
+//        setPrimaryKey.setVisibility(JavaVisibility.PUBLIC);
+//        setPrimaryKey.setName("setPrimaryKey");
+//        setPrimaryKey.addParameter(new Parameter(keyType, "primaryKey"));
+//        if("".equals(keyName)) {
+//        	topLevelClass.addImportedType("com.shawn.web.exception.MyException");
+//        	setPrimaryKey.addBodyLine("throw new MyException(\"该实体不存在主键,请检查表设计或重写setPrimaryKey方法\");");
+//        }else {
+//        	setPrimaryKey.addBodyLine("set"+StringUtils.upperCase(keyName.substring(0, 1))+keyName.substring(1)+"(primaryKey);");
+//        }
+//        topLevelClass.addMethod(setPrimaryKey);
+//
+//        //生成主键get方法
+//        Method getPrimaryKey = new Method();
+//        getPrimaryKey.addJavaDocLine("/**自定义统一方法获取主键**/");
+//        getPrimaryKey.addJavaDocLine("@JsonIgnore");
+//        getPrimaryKey.setVisibility(JavaVisibility.PUBLIC);
+//        getPrimaryKey.setReturnType(keyType);
+//        getPrimaryKey.setName("getPrimaryKey");
+//        if("".equals(keyName)) {
+//        	topLevelClass.addImportedType("com.shawn.web.exception.MyException");
+//        	getPrimaryKey.addBodyLine("throw new MyException(\"该实体不存在主键,请检查表设计或重写getPrimaryKey方法\");");
+//        }else {
+//        	getPrimaryKey.addBodyLine("return get"+StringUtils.upperCase(keyName.substring(0, 1))+keyName.substring(1)+"();");
+//        }
+//    	topLevelClass.addMethod(getPrimaryKey);
+//    	
+//    	//生成 主键判断方法
+//		Method hasPrimaryKey = new Method();
+//        hasPrimaryKey.addJavaDocLine("/**判断该实体是否存在主键**/");
+//        hasPrimaryKey.setVisibility(JavaVisibility.PUBLIC);
+//        hasPrimaryKey.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
+//        hasPrimaryKey.setName("hasPrimaryKey");
+//        if(introspectedTable.hasPrimaryKeyColumns()) {
+//        	hasPrimaryKey.addBodyLine("return true;");
+//        }else {
+//        	hasPrimaryKey.addBodyLine("return false;");
+//        }
+//        topLevelClass.addMethod(hasPrimaryKey);
+//
+//        return true;
+//	}
+    
+    /**
+     * 生成批量新增xml
+     */
+	public XmlElement creatInsertBatchXml_mysql(IntrospectedTable introspectedTable) {
+    	String tableName = introspectedTable.getTableConfiguration().getTableName();
+    	List<IntrospectedColumn> columnList = introspectedTable.getAllColumns();
+    	String sql = "";
+    	String sql2 = "";
+    	for (IntrospectedColumn column : columnList) {
+    		sql = sql+"#{item."+column.getJavaProperty()+",jdbcType="+column.getJdbcTypeName()+"},";
+    		sql2 = sql2+column.getActualColumnName()+",";
+		}
+    	sql = sql.substring(0, sql.length()-1);
+    	sql2 = sql2.substring(0, sql2.length()-1);
+
+
+    	XmlElement insertBatchElement = new XmlElement("insert");
+    	insertBatchElement.addAttribute(new Attribute("id","insertBatch"));
+    	insertBatchElement.addAttribute(new Attribute("parameterType","java.util.List"));
+    	insertBatchElement.addElement(new TextElement(
+    			"insert into "+tableName+" ("+sql2+") VALUES"
+    			));
+    	XmlElement foreach = new XmlElement("foreach");
+    	foreach.addAttribute(new Attribute("collection","list"));
+    	foreach.addAttribute(new Attribute("item","item"));
+    	foreach.addAttribute(new Attribute("index","index"));
+    	foreach.addAttribute(new Attribute("separator",","));
+
+    	foreach.addElement(new TextElement(
+    			"( "+sql.toString()+" )"
+    			));
+    	insertBatchElement.addElement(foreach);
+		return insertBatchElement;
+    }
+	public XmlElement creatInsertBatchXml_oracle(IntrospectedTable introspectedTable) {
+		String tableName = introspectedTable.getTableConfiguration().getTableName();
+		List<IntrospectedColumn> columnList = introspectedTable.getAllColumns();
+		String sql = "";
+		String sql2 = "";
+		for (IntrospectedColumn column : columnList) {
+			sql = sql+"#{item."+column.getJavaProperty()+",jdbcType="+column.getJdbcTypeName()+"},";
+			sql2 = sql2+column.getActualColumnName()+",";
+		}
+		sql = sql.substring(0, sql.length()-1);
+		sql2 = sql2.substring(0, sql2.length()-1);
+
+
+		XmlElement insertBatchElement = new XmlElement("insert");
+		insertBatchElement.addAttribute(new Attribute("id","insertBatch"));
+		insertBatchElement.addAttribute(new Attribute("parameterType","java.util.List"));
+		insertBatchElement.addElement(new TextElement(
+				"insert into "+tableName+" ("+sql2+")"
+				));
+		XmlElement foreach = new XmlElement("foreach");
+		foreach.addAttribute(new Attribute("collection","list"));
+		foreach.addAttribute(new Attribute("item","item"));
+		foreach.addAttribute(new Attribute("index","index"));
+		foreach.addAttribute(new Attribute("separator","union all"));
+
+		foreach.addElement(new TextElement(
+				"select "+sql.toString()+" from dual"
+				));
+		insertBatchElement.addElement(foreach);
+		return insertBatchElement;
+	}
+    /**
+     * 生成批量删除xml(需要主键)
+     */
+    public XmlElement creatDeleteBatchXml(IntrospectedTable introspectedTable) {
+    	if(introspectedTable.hasPrimaryKeyColumns()) {
+    		String tableName = introspectedTable.getTableConfiguration().getTableName();
+    		List<IntrospectedColumn> primaryKeyList = introspectedTable.getPrimaryKeyColumns();
+    		
+    		XmlElement deleteBatchElement = new XmlElement("delete");  
+    		deleteBatchElement.addAttribute(new Attribute("id","deleteBatchByIdList"));  
+    		deleteBatchElement.addAttribute(new Attribute("parameterType","java.util.List")); 
+    		deleteBatchElement.addElement(new TextElement(
+    				"DELETE FROM "+tableName+" where "+ primaryKeyList.get(0).getActualColumnName()+ " in "
+    				));
+    		XmlElement foreach = new XmlElement("foreach");
+    		foreach.addAttribute(new Attribute("collection","list"));  
+    		foreach.addAttribute(new Attribute("item","item"));  
+    		foreach.addAttribute(new Attribute("open","("));  
+    		foreach.addAttribute(new Attribute("separator",",")); 
+    		foreach.addAttribute(new Attribute("close",")")); 
+    		foreach.addElement(new TextElement("#{item}"));
+    		
+    		deleteBatchElement.addElement(foreach);
+    		return deleteBatchElement;
+    	}else {
+    		return null;
+    	}
+    }
+    /**
+     * 生成批量修改xml(需要主键)
+     */
+    public XmlElement creatUpdateBatchXml(IntrospectedTable introspectedTable) {
+    	if(introspectedTable.hasPrimaryKeyColumns()) {
+    		String tableName = introspectedTable.getTableConfiguration().getTableName();
+    		List<IntrospectedColumn> columnList = introspectedTable.getAllColumns();
+    		List<IntrospectedColumn> primaryKeyList = introspectedTable.getPrimaryKeyColumns();
+    		
+    		XmlElement updateBatchElement = new XmlElement("update");  
+    		updateBatchElement.addAttribute(new Attribute("id","updateBatchByIdList"));  
+    		updateBatchElement.addAttribute(new Attribute("parameterType","com.shawn.model.param."+TextUtil.convertUnderscoreToCamelCase(tableName)+"Param")); 
+    		updateBatchElement.addElement(new TextElement(
+    				"update "+tableName
+    				));
+    		XmlElement trim = new XmlElement("trim");
+    		trim.addAttribute(new Attribute("prefix","set"));  
+    		trim.addAttribute(new Attribute("suffixOverrides",","));  
+    		for (IntrospectedColumn column : columnList) {
+    			XmlElement ifDom = new XmlElement("if");  
+    			ifDom.addAttribute(new Attribute("test", column.getJavaProperty()+" != null"));  
+    			ifDom.addElement(new TextElement(column.getActualColumnName()+" = #{"+column.getJavaProperty()+"},")); 
+    			trim.addElement(ifDom);
+    		}
+    		updateBatchElement.addElement(trim);
+    		updateBatchElement.addElement(new TextElement(" where "+ primaryKeyList.get(0).getActualColumnName()+ " in "));
+    		
+    		XmlElement foreach = new XmlElement("foreach");
+    		foreach.addAttribute(new Attribute("collection","primaryKeyList"));  
+    		foreach.addAttribute(new Attribute("item","item"));  
+    		foreach.addAttribute(new Attribute("open","("));  
+    		foreach.addAttribute(new Attribute("separator",",")); 
+    		foreach.addAttribute(new Attribute("close",")")); 
+    		foreach.addElement(new TextElement("#{item}"));
+    		
+    		updateBatchElement.addElement(foreach);
+    		return updateBatchElement;
+    	}else {
+    		return null;
+    	}
+    }
+    
+}

+ 98 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/MySQLLimitPlugin.java

@@ -0,0 +1,98 @@
+package com.shawn.common.mybatisGeneratorConfig;
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.dom.java.Field;
+import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
+import org.mybatis.generator.api.dom.java.JavaVisibility;
+import org.mybatis.generator.api.dom.java.Method;
+import org.mybatis.generator.api.dom.java.Parameter;
+import org.mybatis.generator.api.dom.java.PrimitiveTypeWrapper;
+import org.mybatis.generator.api.dom.java.TopLevelClass;
+import org.mybatis.generator.api.dom.xml.Attribute;
+import org.mybatis.generator.api.dom.xml.TextElement;
+import org.mybatis.generator.api.dom.xml.XmlElement;
+/**
+* @ClassName: MySQLLimitPlugin 
+* @Description: mybatis generator 自定义mysql分页插件
+* @author 吴洪双
+* @date 2017年4月17日 下午3:45:56 
+*
+ */
+public class MySQLLimitPlugin  extends MyPluginAdapter{
+
+    /**
+     * 为每个Example类添加limit和offset属性已经set、get方法
+     */
+    @Override
+    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
+
+        PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();
+
+        Field limit = new Field();
+        limit.setName("limit");
+        limit.setVisibility(JavaVisibility.PRIVATE);
+        limit.setType(integerWrapper);
+        topLevelClass.addField(limit);
+
+        Method setLimit = new Method();
+        setLimit.setVisibility(JavaVisibility.PUBLIC);
+        setLimit.setName("setLimit");
+        setLimit.addParameter(new Parameter(integerWrapper, "limit"));
+        setLimit.addBodyLine("this.limit = limit;");
+        topLevelClass.addMethod(setLimit);
+
+        Method getLimit = new Method();
+        getLimit.setVisibility(JavaVisibility.PUBLIC);
+        getLimit.setReturnType(integerWrapper);
+        getLimit.setName("getLimit");
+        getLimit.addBodyLine("return limit;");
+        topLevelClass.addMethod(getLimit);
+
+        Field offset = new Field();
+        offset.setName("offset");
+        offset.setVisibility(JavaVisibility.PRIVATE);
+        offset.setType(integerWrapper);
+        topLevelClass.addField(offset);
+
+        Method setOffset = new Method();
+        setOffset.setVisibility(JavaVisibility.PUBLIC);
+        setOffset.setName("setOffset");
+        setOffset.addParameter(new Parameter(integerWrapper, "offset"));
+        setOffset.addBodyLine("this.offset = offset;");
+        topLevelClass.addMethod(setOffset);
+
+        Method getOffset = new Method();
+        getOffset.setVisibility(JavaVisibility.PUBLIC);
+        getOffset.setReturnType(integerWrapper);
+        getOffset.setName("getOffset");
+        getOffset.addBodyLine("return offset;");
+        topLevelClass.addMethod(getOffset);
+
+        return true;
+    }
+
+    /**
+     * 为Mapper.xml的selectByExample添加limit
+     */
+    @Override
+    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
+            IntrospectedTable introspectedTable) {
+
+        XmlElement ifLimitNotNullElement = new XmlElement("if");
+        ifLimitNotNullElement.addAttribute(new Attribute("test", "limit != null"));
+
+        XmlElement ifOffsetNotNullElement = new XmlElement("if");
+        ifOffsetNotNullElement.addAttribute(new Attribute("test", "offset != null"));
+        ifOffsetNotNullElement.addElement(new TextElement("limit ${offset}, ${limit}"));
+        ifLimitNotNullElement.addElement(ifOffsetNotNullElement);
+
+        XmlElement ifOffsetNullElement = new XmlElement("if");
+        ifOffsetNullElement.addAttribute(new Attribute("test", "offset == null"));
+        ifOffsetNullElement.addElement(new TextElement("limit ${limit}"));
+        ifLimitNotNullElement.addElement(ifOffsetNullElement);
+
+        element.addElement(ifLimitNotNullElement);
+
+        return true;
+    }
+    
+}

+ 148 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/OraclePaginationPlugin.java

@@ -0,0 +1,148 @@
+package com.shawn.common.mybatisGeneratorConfig;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.project.MavenProject;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+import org.mybatis.generator.api.IntrospectedColumn;
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.Plugin;
+import org.mybatis.generator.api.PluginAdapter;
+import org.mybatis.generator.api.ShellCallback;
+import org.mybatis.generator.api.dom.java.Field;
+import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
+import org.mybatis.generator.api.dom.java.JavaVisibility;
+import org.mybatis.generator.api.dom.java.Method;
+import org.mybatis.generator.api.dom.java.Parameter;
+import org.mybatis.generator.api.dom.java.PrimitiveTypeWrapper;
+import org.mybatis.generator.api.dom.java.TopLevelClass;
+import org.mybatis.generator.api.dom.xml.Attribute;
+import org.mybatis.generator.api.dom.xml.Document;
+import org.mybatis.generator.api.dom.xml.TextElement;
+import org.mybatis.generator.api.dom.xml.XmlElement;
+import org.mybatis.generator.exception.ShellException;
+import org.mybatis.generator.internal.DefaultShellCallback;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.shawn.common.mybatisGeneratorConfig.codeGenerator.MyBatisGeneratorMojo;
+import com.shawn.common.mybatisGeneratorConfig.codeGenerator.TextUtil;
+import com.shawn.web.exception.MyException;
+
+/**
+* @ClassName: OraclePaginationPlugin 
+* @Description: mybatis generator 自定义oracle分页插件
+* @author 吴洪双
+* @date 2017年4月17日 下午3:44:44 
+*
+ */
+public class OraclePaginationPlugin extends MyPluginAdapter{
+    /**
+     * 为每个Example类添加limit和offset属性已经set、get方法
+     */
+    @Override
+    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
+    	PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();
+        Field limit = new Field();
+        limit.setName("limit");
+        limit.setVisibility(JavaVisibility.PRIVATE);
+        limit.setType(integerWrapper);
+        topLevelClass.addField(limit);
+
+        Method setLimit = new Method();
+        setLimit.setVisibility(JavaVisibility.PUBLIC);
+        setLimit.setName("setLimit");
+        setLimit.addParameter(new Parameter(integerWrapper, "limit"));
+        setLimit.addBodyLine("this.limit = limit;");
+        topLevelClass.addMethod(setLimit);
+
+        Method getLimit = new Method();
+        getLimit.setVisibility(JavaVisibility.PUBLIC);
+        getLimit.setReturnType(integerWrapper);
+        getLimit.setName("getLimit");
+        getLimit.addBodyLine("return limit;");
+        topLevelClass.addMethod(getLimit);
+
+        Field offset = new Field();
+        offset.setName("offset");
+        offset.setVisibility(JavaVisibility.PRIVATE);
+        offset.setType(integerWrapper);
+        topLevelClass.addField(offset);
+
+        Method setOffset = new Method();
+        setOffset.setVisibility(JavaVisibility.PUBLIC);
+        setOffset.setName("setOffset");
+        setOffset.addParameter(new Parameter(integerWrapper, "offset"));
+        setOffset.addBodyLine("this.offset = offset;");
+        topLevelClass.addMethod(setOffset);
+
+        Method getOffset = new Method();
+        getOffset.setVisibility(JavaVisibility.PUBLIC);
+        getOffset.setReturnType(integerWrapper);
+        getOffset.setName("getOffset");
+        getOffset.addBodyLine("return offset;");
+        topLevelClass.addMethod(getOffset);
+
+        return true;
+    }
+    /**
+     * 为Mapper.xml的selectByExample添加limit
+     */
+    @Override
+    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
+            IntrospectedTable introspectedTable) {
+
+    	XmlElement pageStart = new XmlElement("include"); //$NON-NLS-1$     
+        pageStart.addAttribute(new Attribute("refid", "OracleDialectPrefix"));  
+        element.getElements().add(0, pageStart);  
+  
+        XmlElement isNotNullElement = new XmlElement("include"); //$NON-NLS-1$     
+        isNotNullElement.addAttribute(new Attribute("refid",  
+                "OracleDialectSuffix"));  
+        element.getElements().add(isNotNullElement);  
+  
+        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element,  
+                introspectedTable);
+    }
+    
+    @Override  
+    public boolean sqlMapDocumentGenerated(Document document,  
+            IntrospectedTable introspectedTable) {  
+        XmlElement parentElement = document.getRootElement();  
+        // 产生分页语句前半部分  
+        XmlElement paginationPrefixElement = new XmlElement("sql");  
+        paginationPrefixElement.addAttribute(new Attribute("id",  
+                "OracleDialectPrefix"));  
+        XmlElement pageStart = new XmlElement("if");  
+        pageStart.addAttribute(new Attribute("test", "limit != null"));  
+        pageStart.addElement(new TextElement(  
+                "select * from ( select row_.*, rownum rownum_ from ( "));  
+        paginationPrefixElement.addElement(pageStart);  
+        parentElement.addElement(paginationPrefixElement);  
+  
+        // 产生分页语句后半部分  
+        XmlElement paginationSuffixElement = new XmlElement("sql");  
+        paginationSuffixElement.addAttribute(new Attribute("id",  
+                "OracleDialectSuffix"));  
+        XmlElement pageEnd = new XmlElement("if");  
+        pageEnd.addAttribute(new Attribute("test", "limit != null"));  
+        pageEnd.addElement(new TextElement(  
+        		"<![CDATA[ ) row_  WHERE rownum <= (#{offset} + #{limit} )) WHERE rownum_ >= (#{offset} +1 ) ]]>"));  
+        paginationSuffixElement.addElement(pageEnd);  
+        parentElement.addElement(paginationSuffixElement);  
+  
+        return super.sqlMapDocumentGenerated(document, introspectedTable);  
+    }
+}

+ 44 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/HtmlField.java

@@ -0,0 +1,44 @@
+package com.shawn.common.mybatisGeneratorConfig.codeGenerator;
+
+import java.util.List;
+import java.util.Map;
+
+import com.shawn.common.myAnnotation.GenHtml.SearchType;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+@SuppressWarnings("serial")
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class HtmlField {
+	/**
+	 * 字段名称
+	 */
+	String fieldName;
+	/**
+	 * 字段描述
+	 */
+	String description;
+	/**
+	 * 作为查询条件展示
+	 */
+	boolean isSearch;
+	/**
+	 * 作为表格字段展示
+	 */
+	boolean isTable;
+	/**
+	 * 控件类型
+	 */
+	SearchType searchType;
+	/**
+	 * 控件值,checkbox、radioButton专用
+	 */
+	List<Map<String,String>> dataList;
+}

+ 48 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/MavenProgressCallback.java

@@ -0,0 +1,48 @@
+/*
+ *  Copyright 2009 The Apache Software Foundation
+ *
+ *  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 com.shawn.common.mybatisGeneratorConfig.codeGenerator;
+
+import org.apache.maven.plugin.logging.Log;
+import org.mybatis.generator.internal.NullProgressCallback;
+
+/**
+ * This callback logs progress messages with the Maven logger
+ * 
+ * @author Jeff Butler
+ *
+ */
+public class MavenProgressCallback extends NullProgressCallback {
+
+    private Log log;
+    private boolean verbose;
+    
+    /**
+     * 
+     */
+    public MavenProgressCallback(Log log, boolean verbose) {
+        super();
+        this.log = log;
+        this.verbose = verbose;
+    }
+
+    @Override
+    public void startTask(String subTaskName) {
+        if (verbose) {
+            log.info(subTaskName);
+        }
+    }
+}

+ 82 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/MavenShellCallback.java

@@ -0,0 +1,82 @@
+/*
+ *  Copyright 2009 The Apache Software Foundation
+ *
+ *  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 com.shawn.common.mybatisGeneratorConfig.codeGenerator;
+
+import java.io.File;
+import java.util.StringTokenizer;
+
+import org.mybatis.generator.exception.ShellException;
+import org.mybatis.generator.internal.DefaultShellCallback;
+import org.mybatis.generator.internal.util.messages.Messages;
+
+/**
+ * @author Jeff Butler
+ */
+public class MavenShellCallback extends DefaultShellCallback {
+    private MyBatisGeneratorMojo mybatisGeneratorMojo;
+
+    /**
+     * @param overwrite
+     */
+    public MavenShellCallback(MyBatisGeneratorMojo mybatisGeneratorMojo, boolean overwrite) {
+        super(overwrite);
+        this.mybatisGeneratorMojo = mybatisGeneratorMojo;
+    }
+
+    @Override
+    public File getDirectory(String targetProject, String targetPackage)
+            throws ShellException {
+        if (!"MAVEN".equals(targetProject)) {
+            return super.getDirectory(targetProject, targetPackage);
+        }
+        
+        // targetProject is the output directory from the MyBatis generator
+        // Mojo. It will be created if necessary
+        //
+        // targetPackage is interpreted as a sub directory, but in package
+        // format (with dots instead of slashes).  The sub directory will be created
+        // if it does not already exist
+        
+        File project = mybatisGeneratorMojo.getOutputDirectory();
+        if (!project.exists()) {
+            project.mkdirs();
+        }
+        
+        if (!project.isDirectory()) {
+            throw new ShellException(Messages.getString("Warning.9", //$NON-NLS-1$
+                    project.getAbsolutePath()));
+        }
+        
+        StringBuilder sb = new StringBuilder();
+        StringTokenizer st = new StringTokenizer(targetPackage, "."); //$NON-NLS-1$
+        while (st.hasMoreTokens()) {
+            sb.append(st.nextToken());
+            sb.append(File.separatorChar);
+        }
+        
+        File directory = new File(project, sb.toString());
+        if (!directory.isDirectory()) {
+            boolean rc = directory.mkdirs();
+            if (!rc) {
+                throw new ShellException(Messages.getString("Warning.10", //$NON-NLS-1$
+                        directory.getAbsolutePath()));
+            }
+        }
+        
+        return directory;
+    }
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1076 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/MyBatisGeneratorMojo.java


+ 202 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/SqlScriptRunner.java

@@ -0,0 +1,202 @@
+/*
+ * Copyright 2009 The Apache Software Foundation.
+ *
+ * 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 com.shawn.common.mybatisGeneratorConfig.codeGenerator;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.mybatis.generator.internal.util.StringUtility;
+import org.mybatis.generator.internal.util.messages.Messages;
+
+/**
+ * This class is used to execute an SQL script before a code generation
+ * run if necessary.  Note that this class mainly exists to support the
+ * MyBatis Generator build.  It is intentionally not documented and not
+ * supported.
+ * 
+ * @author Jeff Butler
+ */
+public class SqlScriptRunner {
+    private String driver;
+    private String url;
+    private String userid;
+    private String password;
+    private String sourceFile;
+    private Log log;
+
+    public SqlScriptRunner(String sourceFile, String driver, String url,
+            String userId, String password) throws MojoExecutionException {
+        
+        if (!StringUtility.stringHasValue(sourceFile)) {
+            throw new MojoExecutionException("SQL script file is required");
+        }
+        
+        if (!StringUtility.stringHasValue(driver)) {
+            throw new MojoExecutionException("JDBC Driver is required");
+        }
+        
+        if (!StringUtility.stringHasValue(url)) {
+            throw new MojoExecutionException("JDBC URL is required");
+        }
+        
+        this.sourceFile = sourceFile;
+        this.driver = driver;
+        this.url = url;
+        this.userid = userId;
+        this.password = password;
+    }
+
+    public void executeScript() throws MojoExecutionException {
+
+        Connection connection = null;
+
+        try {
+            Class.forName(driver);
+            connection = DriverManager.getConnection(url, userid, password);
+
+            Statement statement = connection.createStatement();
+
+            BufferedReader br = getScriptReader();
+
+            String sql;
+
+            while ((sql = readStatement(br)) != null) {
+                statement.execute(sql);
+            }
+
+            closeStatement(statement);
+            connection.commit();
+            br.close();
+        } catch (ClassNotFoundException e) {
+            throw new MojoExecutionException("Class not found: " + e.getMessage());
+        } catch (FileNotFoundException e) {
+            throw new MojoExecutionException("File note found: " + sourceFile);
+        } catch (SQLException e) {
+            throw new MojoExecutionException("SqlException: " + e.getMessage(), e);
+        } catch (IOException e) {
+            throw new MojoExecutionException("IOException: " + e.getMessage(), e);
+        } finally {
+            closeConnection(connection);
+        }
+    }
+
+    public String getDriver() {
+        return driver;
+    }
+
+    public void setDriver(String driver) {
+        this.driver = driver;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    private void closeConnection(Connection connection) {
+        if (connection != null) {
+            try {
+                connection.close();
+            } catch (SQLException e) {
+                // ignore
+                ;
+            }
+        }
+    }
+
+    private void closeStatement(Statement statement) {
+        if (statement != null) {
+            try {
+                statement.close();
+            } catch (SQLException e) {
+                // ignore
+                ;
+            }
+        }
+    }
+
+    private String readStatement(BufferedReader br) throws IOException {
+        StringBuffer sb = new StringBuffer();
+
+        String line;
+
+        while ((line = br.readLine()) != null) {
+            if (line.startsWith("--")) { //$NON-NLS-1$
+                continue;
+            }
+
+            if (!StringUtility.stringHasValue(line)) {
+                continue;
+            }
+
+            if (line.endsWith(";")) { //$NON-NLS-1$
+                sb.append(line.substring(0, line.length() - 1));
+                break;
+            } else {
+                sb.append(' ');
+                sb.append(line);
+            }
+        }
+
+        String s = sb.toString().trim();
+
+        if (s.length() > 0) {
+            log.debug((Messages.getString("Progress.13", s))); //$NON-NLS-1$
+        }
+
+        return s.length() > 0 ? s : null;
+    }
+
+    public void setLog(Log log) {
+        this.log = log;
+    }
+    
+    private BufferedReader getScriptReader() throws MojoExecutionException, FileNotFoundException {
+        BufferedReader answer;
+        
+        if (sourceFile.startsWith("classpath:")) {
+            String resource = sourceFile.substring("classpath:".length());
+            InputStream is = 
+                Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
+            if (is == null) {
+                throw new MojoExecutionException("SQL script file does not exist: " + resource);
+            }
+            answer = new BufferedReader(new InputStreamReader(is));
+        } else {
+            File file = new File(sourceFile);
+            if (!file.exists()) {
+                throw new MojoExecutionException("SQL script file does not exist");
+            }
+            answer = new BufferedReader(new FileReader(file));
+        }
+        
+        return answer;
+    }
+}

+ 119 - 0
src/main/java/com/shawn/common/mybatisGeneratorConfig/codeGenerator/TextUtil.java

@@ -0,0 +1,119 @@
+/**
+ *
+ */
+package com.shawn.common.mybatisGeneratorConfig.codeGenerator;
+
+import java.io.StringWriter;
+import java.util.Map;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+import lombok.extern.apachecommons.CommonsLog;
+
+/**
+ * 处理文本
+ *
+ * @author John.Lee
+ */
+@CommonsLog
+public class TextUtil {
+
+  /**
+   * 驼峰转下划线
+   *
+   * @Description
+   * @author John.Lee
+   * @param str
+   * @return
+   */
+  public static String convertCamelCaseToUnderscore(String str) {
+
+    String[] strings = StringUtils.splitByCharacterTypeCamelCase(str);
+
+    String _str = StringUtils.join(strings, "_");
+
+    _str = StringUtils.lowerCase(_str);
+
+    return _str;
+  }
+
+  /**
+   * 下划线转驼峰
+   *
+   * @Description
+   * @author John.Lee
+   * @param str
+   * @return
+   */
+  public static String convertUnderscoreToCamelCase(String str) {
+    if (str == null) {
+      return null;
+    }
+    String[] strings = str.split("_");
+    StringBuilder sb = new StringBuilder();
+    for (String _str : strings) {
+      sb.append(StringUtils.upperCase(_str.substring(0, 1)) + StringUtils.lowerCase(_str.substring(1)));
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * firstLowerCase:首字母小写
+   */
+  public static String firstLowerCase(String fldName) {
+    String first = fldName.substring(0, 1).toLowerCase();
+    String rest = fldName.substring(1, fldName.length());
+    String newStr = new StringBuffer(first).append(rest).toString();
+    return newStr;
+  }
+  /**
+   * firstLowerCase:首字母大写
+   */
+  public static String firstUpperCase(String fldName) {
+	  String first = fldName.substring(0, 1).toUpperCase();
+	  String rest = fldName.substring(1, fldName.length());
+	  String newStr = new StringBuffer(first).append(rest).toString();
+	  return newStr;
+  }
+
+  /**
+   * velocityMerge:传入模板,返回字符串. <br/>
+   *
+   * @author:李强 Date: 2016年5月17日 下午2:20:22
+   * @param templePath 模板路径
+   * @param map 参数
+   * @return
+   * @since JDK 1.7
+   */
+  public static String velocityMerge(String templePath, Map<String, Object> map) {
+    VelocityEngine ve = new VelocityEngine();
+    ve.setProperty(Velocity.RESOURCE_LOADER, "class");
+    ve.setProperty("class.resource.loader.class",
+        "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+    ve.setProperty("input.encoding", "utf-8");
+    ve.setProperty("output.encoding", "utf-8");
+    try {
+      ve.init();
+      Template t = ve.getTemplate(templePath);
+      VelocityContext context = new VelocityContext();
+
+      for (Map.Entry<String, Object> entry : map.entrySet()) {
+        context.put(entry.getKey(), entry.getValue());
+      }
+
+      StringWriter writer = new StringWriter();
+      t.merge(context, writer);
+      writer.flush();
+      writer.close();
+
+      return writer.toString();
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+    }
+
+    return null;
+  }
+}

+ 66 - 0
src/main/java/com/shawn/common/webConfig/CorsConfig.java

@@ -0,0 +1,66 @@
+package com.shawn.common.webConfig;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import com.shawn.common.myAnnotation.CamelCaseToUnderscoreFormatAnnotationFormatterFactory;
+import com.shawn.common.myAnnotation.CamelCaseToUnderscoreFormatter;
+
+/**
+ * @author 吴洪双 允许跨越
+ */
+@Configuration
+@EnableWebMvc
+public class CorsConfig extends WebMvcConfigurerAdapter {
+	private CorsConfiguration buildConfig() {
+		CorsConfiguration corsConfiguration = new CorsConfiguration();
+		corsConfiguration.addAllowedOrigin("*"); // 1
+		corsConfiguration.addAllowedHeader("*"); // 2
+		corsConfiguration.addAllowedMethod("*"); // 3
+		return corsConfiguration;
+	}
+
+	@Bean
+	public CorsFilter corsFilter() {
+		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+		source.registerCorsConfiguration("/**", buildConfig()); // 4
+		return new CorsFilter(source);
+	}
+
+	@Bean
+	public Converter<String, Date> addNewConvert() {
+		return new Converter<String, Date>() {
+			@Override
+			public Date convert(String source) {
+				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+				Date date = null;
+				try {
+					date = sdf.parse((String) source);
+				} catch (ParseException e) {
+					e.printStackTrace();
+				}
+				return date;
+			}
+		};
+	}
+
+	/**
+	 * 增加自定义Formatters
+	 */
+	@Override
+	public void addFormatters(FormatterRegistry registry) {
+		//添加    param条件注解Formatters
+		registry.addFormatterForFieldAnnotation(new CamelCaseToUnderscoreFormatAnnotationFormatterFactory());
+	}
+}

+ 16 - 0
src/main/java/com/shawn/constant/DatabaseType.java

@@ -0,0 +1,16 @@
+package com.shawn.constant;
+
+public enum DatabaseType {
+	/**
+	 * Oracle
+	 */
+	db1,
+	/**
+	 * spark hive
+	 */
+	db2,
+	/**
+	 * postgresql
+	 */
+	db3
+}

+ 19 - 0
src/main/java/com/shawn/constant/ErrorCode.java

@@ -0,0 +1,19 @@
+package com.shawn.constant;
+
+/**
+ * @author 吴洪双
+ */
+public class ErrorCode {
+
+    public static final int SERVER_INTERNAL_ERROR = 1000;
+    public static final int PARAMETER_MISSING_ERROR = 1001;
+    public static final int PARAMETER_ILLEGAL_ERROR = 1002;
+    public static final int RESOURCE_NOT_FOUND_ERROR = 1003;
+
+    /**
+     * Prevent instantiation
+     */
+    private ErrorCode() {
+    }
+
+}

+ 78 - 0
src/main/java/com/shawn/constant/OprTypeEnum.java

@@ -0,0 +1,78 @@
+package com.shawn.constant;
+
+public enum OprTypeEnum {
+	OPR_DISABLED_USER("/AdOprDetl/disabledByUser","禁用用户", "1","PUT"), 
+	OPR_ENABLED_USER("/AdOprDetl/enabledByUser","启用用户", "2","PUT"), 
+	OPR_ADD_USER("/AdOprDetl/addUser","新增用户", "3","POST"), 
+	OPR_UPDATE_USER("/AdOprDetl/updateUserOu","更新用户", "4","PUT"), 
+	OPR_RESET_PWD("/AdOprDetl/resetPwd","重置密码", "5","PUT");
+//	OPR_SELECT_NODE("/AdOprDetl/selectByNode","查询节点", "6","GET");
+    
+	private String requestUrl;
+    private String oprName;
+    private String oprType;
+    private String method;
+
+    private OprTypeEnum(String requestUrl,String oprName, String oprType,String method) {
+    	this.requestUrl = requestUrl;
+        this.oprName = oprName;
+        this.oprType = oprType;
+        this.setMethod(method);
+    }
+    
+    public static String getOprType(String requestUrl,String method) {
+        for (OprTypeEnum c : OprTypeEnum.values()) {
+            if (requestUrl.contains(c.getRequestUrl()) && method.toUpperCase().equals(c.getMethod())) {
+                return c.getOprType();
+            }
+        }
+        return null;
+    }
+    public static String getOprName(String oprType) {
+        for (OprTypeEnum c : OprTypeEnum.values()) {
+            if (oprType.contains(c.getOprType())) {
+                return c.getOprName();
+            }
+        }
+        return null;
+    }
+
+
+	public String getRequestUrl() {
+		return requestUrl;
+	}
+
+
+	public void setRequestUrl(String requestUrl) {
+		this.requestUrl = requestUrl;
+	}
+
+
+	public String getOprName() {
+		return oprName;
+	}
+
+
+	public void setOprName(String oprName) {
+		this.oprName = oprName;
+	}
+
+
+	public String getOprType() {
+		return oprType;
+	}
+
+
+	public void setOprType(String oprType) {
+		this.oprType = oprType;
+	}
+
+	public String getMethod() {
+		return method;
+	}
+
+	public void setMethod(String method) {
+		this.method = method;
+	}
+    
+}

+ 19 - 0
src/main/java/com/shawn/constant/PageConstant.java

@@ -0,0 +1,19 @@
+package com.shawn.constant;
+
+/**
+ * @author 吴洪双
+ */
+public class PageConstant {
+
+    public static final int PAGE = 1; // 页码
+    public static final int LIMIT = 10; // 每页条数
+    public static final int OFFSET = 0; // 第几条起
+    public static final String ORDER = "asc"; // 排序
+
+    /**
+     * Prevent instantiation
+     */
+    private PageConstant() {
+    }
+
+}

+ 31 - 0
src/main/java/com/shawn/model/bean/PageBean.java

@@ -0,0 +1,31 @@
+package com.shawn.model.bean;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+
+/**
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class PageBean {
+	@JsonIgnore
+    protected String orderByClause;
+    @JsonIgnore
+    protected boolean distinct;
+    @JsonIgnore
+    private Integer limit;
+    @JsonIgnore
+    private Integer offset;
+
+	
+}

+ 26 - 0
src/main/java/com/shawn/model/dto/Error.java

@@ -0,0 +1,26 @@
+package com.shawn.model.dto;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class Error implements Serializable {
+
+    private static final long serialVersionUID = 7660756960387438399L;
+
+    private int code; // Error code
+    private String message; // Error message
+
+}

+ 25 - 0
src/main/java/com/shawn/model/dto/HttpResult.java

@@ -0,0 +1,25 @@
+package com.shawn.model.dto;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class HttpResult implements Serializable {
+
+	private static final long serialVersionUID = 8387149586319662675L;
+	private boolean code=true; // Error code
+    private String message; // Error message
+    private int status; // Error message
+}

+ 29 - 0
src/main/java/com/shawn/model/dto/PaginatedResult.java

@@ -0,0 +1,29 @@
+package com.shawn.model.dto;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class PaginatedResult implements Serializable {
+
+    private static final long serialVersionUID = 6191745064790884707L;
+
+    private boolean code; // Error code
+    private int currentPage; // 当前页数
+    private int totalPage; // 总页数
+    private int total; // 总条数
+    private Object data; // Paginated resources
+
+}

+ 26 - 0
src/main/java/com/shawn/model/dto/ResultMessage.java

@@ -0,0 +1,26 @@
+package com.shawn.model.dto;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class ResultMessage implements Serializable {
+	
+    private static final long serialVersionUID = 7660756960387438399L;
+    private boolean code; // Error code
+    private String message; // Error message
+    private Object data; // Error message
+
+}

+ 58 - 0
src/main/java/com/shawn/monitor/PerformanceMonitor.java

@@ -0,0 +1,58 @@
+package com.shawn.monitor;
+
+import lombok.extern.apachecommons.CommonsLog;
+import org.apache.commons.lang3.time.StopWatch;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 吴洪双
+ */
+@CommonsLog
+@Aspect
+@Component
+public class PerformanceMonitor {
+
+    /**
+     * A join point is in the controller layer if the method is
+     * modified by public and defined in a type in the
+     * com.shawn.service package or any sub-package under that
+     * and modified by public.
+     */
+    @Pointcut("execution(public * com.shawn.web.controller..*(..))")
+    private void controllerLayer() {
+    }
+
+    /**
+     * Monitor the elapsed time of method on controller layer, in
+     * order to detect performance problems as soon as possible.
+     * If elapsed time > 1 s, log it as an error. Otherwise, log it
+     * as an info.
+     */
+    @Around("controllerLayer()")
+    public Object monitorElapsedTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
+        // Timing the method in controller layer
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start();
+        Object result = proceedingJoinPoint.proceed();
+        stopWatch.stop();
+
+        // Log the elapsed time
+        double elapsedTime = stopWatch.getTime() / 1000.0;
+        Signature signature = proceedingJoinPoint.getSignature();
+        String infoString = "[" + signature.toShortString() + "][Elapsed time: " + elapsedTime + " s]";
+        if (elapsedTime > 1) {
+            log.error(infoString + "[Note that it's time consuming!]");
+        } else {
+            log.info(infoString);
+        }
+
+        // Return the result
+        return result;
+    }
+
+}

+ 54 - 0
src/main/java/com/shawn/monitor/RepositoryMonitor.java

@@ -0,0 +1,54 @@
+package com.shawn.monitor;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+import lombok.extern.apachecommons.CommonsLog;
+/**
+* @ClassName: RepositoryMonitor 
+* @Description: TODO(利用AOP切换数据源) 
+* @author 吴洪双
+* @date 2017年3月31日 下午5:36:26 
+*
+ */
+@CommonsLog
+@Aspect
+@Component
+public class RepositoryMonitor {
+	 	@Pointcut("execution(* com.shawn.repository..*(..))")
+	    public void allCell() {
+	    }
+	 	@Pointcut("execution(* com.shawn.repository.HRTape*.*(..))")
+	 	public void tapeCell() {
+	 	}
+	 	@Pointcut("execution(* com.shawn.repository.BookRepository.*(..))")
+	 	public void bookCell() {
+	 	}
+
+	    /**
+	     * 使用定义切点表达式的方法进行切点表达式的引入
+	     */
+	    /*@Before("allCell()")
+	    public void setDataSourceKey(JoinPoint point) {
+	        if (point.getTarget() instanceof BookRepository) {
+	        	DynamicDataSource.setDatabaseType(DatabaseType.db3);
+	        } else {// 连接点所属的类实例是UserDao(当然,这一步也可以不写,因为defaultTargertDataSource就是该类所用的mytestdb)
+	        	DynamicDataSource.setDatabaseType(DatabaseType.db1);
+	        }
+	    }	*/
+	    /*@Before("bookCell()")
+	    public void setDataSourceKey(JoinPoint point) {
+	    	//获取方法名
+	    	String methodName = point.getSignature().getName();
+	    	if(point.toString().contains("select")){//查找用hive
+	    		DynamicDataSource.setDatabaseType(DatabaseType.db2);
+	    		log.debug("DatabaseType.db2");
+	    	}else{//增删改用postgresql
+	    		DynamicDataSource.setDatabaseType(DatabaseType.db3);
+	    		log.debug("DatabaseType.db3");
+	    	}
+	    }	*/
+	    
+	    
+}

+ 63 - 0
src/main/java/com/shawn/monitor/ServiceMonitor.java

@@ -0,0 +1,63 @@
+package com.shawn.monitor;
+
+import com.shawn.web.exception.MyException;
+import com.shawn.web.exception.ParamNotFoundException;
+import com.shawn.web.exception.ServerInternalErrorException;
+import lombok.extern.apachecommons.CommonsLog;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import java.security.Principal;
+import java.util.Arrays;
+
+/**
+ * @author 吴洪双
+ */
+@CommonsLog
+@Aspect
+@Component
+public class ServiceMonitor {
+
+    /**
+     * A join point is in the service layer if the method is defined
+     * in a type in the com.shawn.service package or any sub-package
+     * under that.
+     */
+    @Pointcut("execution(* com.shawn.service..*(..))")
+    private void serviceLayer() {
+    }
+
+    /**
+     * Monitor whether exception is thrown in service layer. If exception
+     * has been thrown, in order to detecting it conveniently, log the
+     * situation where it happened. Then create a server internal error
+     * exception and throw it out.
+     */
+    @AfterThrowing(pointcut = "com.shawn.monitor.ServiceMonitor.serviceLayer()", throwing = "e")
+    public void monitorException(JoinPoint joinPoint, Throwable e) {
+        // Log the situation where exception happened
+        Object[] args = joinPoint.getArgs();
+        Signature signature = joinPoint.getSignature();
+        log.error("[" + signature.toShortString() + "]" + Arrays.toString(args) + "[" + e.toString() + "]");
+        if(e instanceof DuplicateKeyException){
+        	throw new MyException("违反唯一约束条件");
+        }
+        if(e instanceof MyException){
+        	throw new MyException(e.getMessage());
+        }
+        if(e instanceof ParamNotFoundException){
+        	throw new MyException(e.getMessage());
+        }
+        
+        // Throw a new server internal error exception
+        throw new ServerInternalErrorException();
+    }
+}

+ 10 - 0
src/main/java/com/shawn/repository/GetNoMapper.java

@@ -0,0 +1,10 @@
+package com.shawn.repository;
+
+import java.util.Map;
+
+
+public interface GetNoMapper {
+	public Integer getNo( Map<String,String> map);
+	
+	public Integer checkDB();
+}

+ 39 - 0
src/main/java/com/shawn/repository/base/BaseDaoInterface.java

@@ -0,0 +1,39 @@
+package com.shawn.repository.base;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface BaseDaoInterface<ENTITY,ENTITYExample,ENTITYParam, ID extends Serializable> {
+	
+	long countByExample(ENTITYExample example);
+
+    int deleteByExample(ENTITYExample example);
+
+    int deleteByPrimaryKey(ID id);
+
+    int insert(ENTITY record);
+
+    int insertSelective(ENTITY record);
+    
+    List<ENTITY> selectByExample(ENTITYExample example);
+
+    ENTITY selectByPrimaryKey(ID id);
+
+    int updateByExampleSelective(@Param("record") ENTITY record, @Param("example") ENTITYExample example);
+
+    int updateByExample(@Param("record") ENTITY record, @Param("example") ENTITYExample example);
+
+    int updateByPrimaryKeySelective(ENTITY record);
+    
+    int updateByPrimaryKey(ENTITY record);
+	
+    int deleteBatchByIdList(List primaryKeyList);
+    
+    int insertBatch(List<ENTITY> entityList);
+    
+    int updateBatchByIdList(ENTITYParam entity);
+}

+ 66 - 0
src/main/java/com/shawn/security/AuthorizationServerConfiguration.java

@@ -0,0 +1,66 @@
+/*package com.shawn.security;
+
+import com.shawn.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
+import org.springframework.security.oauth2.provider.token.TokenStore;
+import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
+
+*//**
+ * @author Xiaoyue Xiao
+ *//*
+@Configuration
+@EnableAuthorizationServer
+public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
+
+    @Autowired
+    private TokenStore tokenStore;
+
+    @Autowired
+    private AuthenticationManager authenticationManager;
+
+    @Autowired
+    private UserService userService;
+
+    @Override
+    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+        clients
+            .inMemory()
+                .withClient("client")
+                    .authorizedGrantTypes("password", "refresh_token")
+                    .scopes("read", "write")
+                    .secret("fucksecurity");
+    }
+
+    @Override
+    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+        endpoints
+            .tokenStore(tokenStore)
+            .authenticationManager(authenticationManager)
+            .userDetailsService(userService);
+    }
+
+    @Bean
+    public TokenStore tokenStore() {
+        return new InMemoryTokenStore();
+    }
+
+    @Bean
+    @Primary
+    public DefaultTokenServices tokenServices() {
+        DefaultTokenServices tokenServices = new DefaultTokenServices();
+        tokenServices.setSupportRefreshToken(true); // support refresh token
+        tokenServices.setTokenStore(tokenStore); // use in-memory token store
+        return tokenServices;
+    }
+
+}
+*/

+ 25 - 0
src/main/java/com/shawn/security/ResourceServerConfiguration.java

@@ -0,0 +1,25 @@
+package com.shawn.security;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+
+/**
+ * @author 吴洪双
+ */
+@Configuration
+@EnableResourceServer
+public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http
+            .authorizeRequests()
+//                .antMatchers("/users/**").authenticated()
+//                .antMatchers(HttpMethod.GET, "/books/**").permitAll()
+                .anyRequest().permitAll();
+    }
+
+}

+ 24 - 0
src/main/java/com/shawn/security/WebSecurityConfiguration.java

@@ -0,0 +1,24 @@
+/*package com.shawn.security;
+
+import com.shawn.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
+
+@Configuration
+public class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
+
+    private final UserService userService;
+
+    @Autowired
+    public WebSecurityConfiguration(UserService userService) {
+        this.userService = userService;
+    }
+
+    @Override
+    public void init(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(userService);
+    }
+
+}*/

+ 128 - 0
src/main/java/com/shawn/service/base/BaseService.java

@@ -0,0 +1,128 @@
+package com.shawn.service.base;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.shawn.repository.base.BaseDaoInterface;
+
+@Service
+public abstract class BaseService<ENTITY,ENTITYExample,ENTITYParam, ID extends Serializable> {
+	@Autowired
+	GetNoServiceImpl getNoServiceImpl;
+	
+	protected BaseDaoInterface<ENTITY,ENTITYExample,ENTITYParam, ID> baseDAO;
+	@Autowired
+	public BaseService(BaseDaoInterface<ENTITY,ENTITYExample,ENTITYParam, ID> dao){
+		baseDAO = dao;
+	}
+	/**
+	 * 自定义获取model 表的名称
+	 */
+	protected abstract String getResourceName();
+	
+	/**
+	 * 将ENTITYE转为ENTITYExample
+	 */
+//	public abstract ENTITYExample param2Example(Object param);
+	
+	/**
+	 * 生成唯一id
+	 * @param tableName 表名
+	 * @return
+	 */
+	public String generateUniqueID(String tableName) {
+		return getNoServiceImpl.getNo(tableName);
+	}
+	/**
+	 * 生成唯一id
+	 * 根据getResourceName 作为表名
+	 * @return
+	 */
+	public String generateUniqueID() {
+		return getNoServiceImpl.getNo(getResourceName());
+	}
+	/**
+	 * 测试数据库连接
+	 */
+	public Integer checkDB() {
+		return getNoServiceImpl.checkDB();
+	}
+	/**
+	 * 新增
+	 */
+	@Transactional
+	public Integer insert(ENTITY entity) {
+//		return baseDAO.insertSelective(entity);
+		return baseDAO.insert(entity);
+	}
+	/**
+	 * 根据id删除
+	 */
+	@Transactional
+	public Integer deleteById(ID id) {
+		return baseDAO.deleteByPrimaryKey(id);
+	}
+	/**
+	 * 根据条件删除
+	 */
+	@Transactional
+	public Integer deleteByOption(ENTITYExample example) {
+		return baseDAO.deleteByExample(example);
+	}
+	/**
+	 * 根据条件查找总条数
+	 */
+	public Long selectCount(ENTITYExample example){
+		return baseDAO.countByExample(example);
+	}
+	/**
+	 * 根据条件查找,List<ENTITY>
+	 */
+	public List<ENTITY> selectByOption(ENTITYExample example){
+        return baseDAO.selectByExample(example);
+	}
+	/**
+	 * 根据id查找,返回Optional<ENTITY>
+	 */
+	public Optional<ENTITY> selectById(ID id) {
+		return  Optional.ofNullable(baseDAO.selectByPrimaryKey(id));
+	}
+	/**
+	 * 根据id查找,返回实体
+	 */
+	public ENTITY selectEntityById(ID id) {
+		return  baseDAO.selectByPrimaryKey(id);
+	}
+	/**
+	 * 根据id更新,更新字段为空时,则不更新该字段
+	 */
+	@Transactional
+	public boolean updateById(ENTITY entity) {
+		return baseDAO.updateByPrimaryKeySelective(entity)>0;
+	}
+	/**
+	 * 根据条件更新,更新字段为空时,则不更新该字段
+	 */
+	@Transactional
+	public boolean updateByOption(@Param("record") ENTITY record, @Param("example") ENTITYExample example) {
+		return baseDAO.updateByExampleSelective(record,example)>0;
+	}
+	@Transactional
+	public int deleteBatchByIdList(List primaryKeyList) {
+		return baseDAO.deleteBatchByIdList(primaryKeyList);
+	}
+	@Transactional
+	public int insertBatch(List<ENTITY> entityList){
+		return baseDAO.insertBatch(entityList);
+	}
+	@Transactional
+	public int updateBatchByIdList(ENTITYParam entity){
+		return baseDAO.updateBatchByIdList(entity);
+	}
+}

+ 74 - 0
src/main/java/com/shawn/service/base/BaseServiceInterface.java

@@ -0,0 +1,74 @@
+package com.shawn.service.base;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.ibatis.annotations.Param;
+
+
+public interface BaseServiceInterface<ENTITY,ENTITYExample,ENTITYParam, ID extends Serializable> {
+	/**
+	 * 新增
+	 */
+	public Integer insert(ENTITY entity);
+	/**
+	 * 根据id删除
+	 */
+	public Integer deleteById(ID id);
+	/**
+	 * 根据条件删除
+	 */
+	public Integer deleteByOption(ENTITYExample example);
+	/**
+	 * 根据条件查找总条数
+	 */
+	public Long selectCount(ENTITYExample example);
+	/**
+	 * 根据条件查找,List<ENTITY>
+	 */
+	public List<ENTITY> selectByOption(ENTITYExample example);
+	/**
+	 * 根据id查找,返回Optional<ENTITY>
+	 */
+	public Optional<ENTITY> selectById(ID id);
+	/**
+	 * 根据id查找,返回实体
+	 */
+	public ENTITY selectEntityById(ID id);
+	/**
+	 * 根据id更新,更新字段为空时,则不更新该字段
+	 */
+	public boolean updateById(ENTITY entity);
+	/**
+	 * 根据条件更新,更新字段为空时,则不更新该字段
+	 */
+	public boolean updateByOption(@Param("record") ENTITY record, @Param("example") ENTITYExample example);
+	
+	public int deleteBatchByIdList(List primaryKeyList);
+    
+	public int insertBatch(List<ENTITY> entityList);
+    
+	public int updateBatchByIdList(ENTITYParam entity);
+	/**
+	 * 测试数据库连接
+	 */
+	public Integer checkDB();
+	/**
+	 * 自定义获取model 表的名称
+	 */
+	public String getResourceName();
+	
+	/**
+	 * 生成唯一id
+	 * @param tableName 表名
+	 * @return
+	 */
+	public String generateUniqueID(String tableName);
+	/**
+	 * 生成唯一id
+	 * 根据getResourceName 作为表名
+	 * @return
+	 */
+	public String generateUniqueID();
+}

+ 102 - 0
src/main/java/com/shawn/service/base/GetNoServiceImpl.java

@@ -0,0 +1,102 @@
+package com.shawn.service.base;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.shawn.repository.GetNoMapper;
+
+import lombok.extern.apachecommons.CommonsLog;
+@CommonsLog
+@Service
+public class GetNoServiceImpl {
+	@Autowired
+	GetNoMapper getNoMapper;
+	private final static HashMap<String,Integer[]> map = new HashMap<String,Integer[]>();
+	public final static String format4 = "yyyyMMdd";
+	static {
+		map.put("AdOprDetl",  new Integer[]{2,8});
+		map.put("AdAuthConf",  new Integer[]{2,8});
+			}
+	
+	public static HashMap<String,Integer[]> getTables(){
+		return map;
+	}
+	 public static String getDate_d(Long l_d,String format){
+         SimpleDateFormat   sdf  = new SimpleDateFormat(format);
+         Date dd = new Date(l_d.longValue());
+         return sdf.format(dd);
+ }
+	
+	@Transactional
+	public String getNo(String modelName) {
+		
+		// TODO Auto-generated method stub
+		StringBuilder sbuf = new StringBuilder();
+		//String id = "";
+		GetNoServiceImpl gn = new GetNoServiceImpl();
+		if(map.containsKey(modelName)){
+			
+			HashMap<String, Integer[]> tables = gn.getTables();
+			int seqtype = tables.get(modelName)[0];
+			int length = tables.get(modelName)[1];
+			String today = gn.getDate_d(Long.valueOf(System.currentTimeMillis()), gn.format4);
+	
+		      
+		  Map<String,String> map = new HashMap<String,String>();
+	      map.put("tableName", modelName);
+	      map.put("today", today);
+	      getNoMapper.getNo(map);
+	      Integer id = Integer.parseInt(map.get("sn"));
+		   
+			sbuf.append(today);
+			sbuf.append(seqtype);
+			sbuf.append(gn.leftFill(id.toString(), length, "0"));
+	
+		}else{
+			throw new RuntimeException("数据库序列号不存在!" + modelName);
+		}
+		
+		log.info(sbuf.toString()+"=====sbuf.toString()======");
+		return sbuf.toString();
+	}
+	/**
+	 * 按字节长度左补位
+	 * 
+	 * @param src
+	 * @param count
+	 * @param in
+	 * @return
+	 **/
+	public static String leftFill(String src, int count, String in) {
+		if (count > 0) {
+			if (src.getBytes().length < count) {
+				String fills = "";
+				if (in == null || in.equals(""))
+					in = "0";
+				for (int i = 0; i < count; i++)
+					fills = fills + in;
+
+				return fills.substring(0, fills.getBytes().length
+						- src.getBytes().length)
+						+ src;
+			} else {
+				return src;
+			}
+		} else {
+			return src;
+		}
+	}
+	
+	/**
+	 * 测试数据库连接
+	 */
+	public Integer checkDB() {
+		return getNoMapper.checkDB();
+	}
+}

+ 104 - 0
src/main/java/com/shawn/util/BeanUtils.java

@@ -0,0 +1,104 @@
+package com.shawn.util;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+
+/**
+ * 
+ * 类说明:实体类赋值
+ * @author 吴洪双
+ * 2016年5月25日上午9:55:16
+ */
+public class BeanUtils {
+    /**
+     * 
+     * 方法说明:获取空属性
+     * @author 吴洪双
+     * 2016年5月25日上午9:56:43
+     * @param source
+     * @return
+     */
+    public static String[] getNullPropertyNames (Object source) {
+    	 final BeanWrapper src = new BeanWrapperImpl(source);
+    	 java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
+
+    	 Set<String> emptyNames = new HashSet<String>();
+    	 for(java.beans.PropertyDescriptor pd : pds) {
+	    	 Object srcValue = src.getPropertyValue(pd.getName());
+	    	 if (srcValue == null) emptyNames.add(pd.getName());
+    	 }
+    	 String[] result = new String[emptyNames.size()];
+    	 return emptyNames.toArray(result);
+    }
+    /**
+     * 
+     * 方法说明:忽略空值
+     * @author 吴洪双
+     * 2016年5月25日上午9:57:18
+     * @param src
+     * @param target
+     */
+    public static void copyPropertiesIgnoreNull(Object src, Object target,boolean flag){
+    	if(flag){
+    		org.springframework.beans.BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
+    	}else{
+    		org.springframework.beans.BeanUtils.copyProperties(src, target);
+    	}
+    }
+//    public static void main(String[] args) {
+//    	AdUser ad = new AdUser();
+//		Map m = new HashMap();
+//		m.put("userName", "2123");
+//		m.put("accountName", "333");
+//		BeanUtils.map2entity(m, ad);
+//		System.out.println(ad.getAccountName());
+//	}
+    
+    public static void map2entity(Map map,Object obj) {
+    	try {
+    		Method[] methods = obj.getClass().getDeclaredMethods();
+    		if(methods!=null&&methods.length>0) {
+	    		for(Method method : methods) {
+	    			if(method.getName().startsWith("set")) {
+	    				String key = method.getName().replace("set", "");
+	    				key = key.substring(0, 1).toLowerCase().concat(key.substring(1));
+	    				Object value = map.get(key);
+	    				if(value == null || value.equals("N/A")) {
+	    					continue;
+	    				}
+	    				method.invoke(obj, value);
+	    			}
+	    		}
+    		}
+    	}catch(Exception e) {
+    		e.printStackTrace();
+    	}
+    }
+    
+    public static void entity2Map(Object obj,Map map) {
+    	try {
+    		Method[] methods = obj.getClass().getDeclaredMethods();
+    		if(methods!=null&&methods.length>0) {
+	    		for(Method method : methods) {
+	    			if(method.getName().startsWith("get")) {
+	    				String key = method.getName().replace("get", "");
+	    				key = key.substring(0, 1).toLowerCase().concat(key.substring(1));
+	    				
+	    				Object value = method.invoke(obj);
+	    				if(value == null || value.equals("N/A")) {
+	    					continue;
+	    				}
+	    				map.put(key, value);
+	    			}
+	    		}
+    		}
+    	}catch(Exception e) {
+    		e.printStackTrace();
+    	}
+    }
+    
+}

+ 249 - 0
src/main/java/com/shawn/util/DateUtils.java

@@ -0,0 +1,249 @@
+package com.shawn.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DateUtils
+{
+  public static final String PATTERN_MMdd = "MMdd";
+  public static final String PATTERN_yyyyMMdd = "yyyyMMdd";
+  public static final String PATTERN_yyyyMMddHHmmss = "yyyyMMddHHmmss";
+  public static final String PATTERN_yyyyMMddHHmmssSSS = "yyyyMMddHHmmssSSS";
+  public static final String PATTERN_yyyy_MM_dd = "yyyy-MM-dd";
+  public static final String PATTERN_yyyy_M_d = "yyyy-M-d";
+  public static final String PATTERN_yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
+  public static final String PATTERN_yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
+  public static final String PATTERN_HH_mm_ss = "HH:mm:ss";
+  public static final String PATTERN_HHmmss = "HHmmss";
+  public static final Map<String, String> mapChDate = new HashMap<String, String>();
+
+  public static Date getNextday(Date now)
+  {
+    Calendar calendar = Calendar.getInstance();
+    calendar.setTime(now);
+    calendar.add(5, 1);
+    return calendar.getTime();
+  }
+  
+  public static Date getPreday(Date now)
+  {
+    Calendar calendar = Calendar.getInstance();
+    calendar.setTime(now);
+    calendar.add(5, -1);
+    return calendar.getTime();
+  }
+
+  public static String formatDate_ch(Date date)
+  {
+    if(date==null){
+   	 throw new IllegalArgumentException("需要转换的对象为空");
+    }
+    String str = formatDate(date, "MMdd");
+    str = (String)mapChDate.get(str.substring(0, 2)) + str.substring(2);
+    return str;
+  }
+
+  public static String formatDate(Date date, String pattern)
+  {
+    if(date==null){
+        return "";
+    }
+    SimpleDateFormat sdf = null;
+    if (pattern == null)
+      sdf = new SimpleDateFormat();
+    else {
+      sdf = new SimpleDateFormat(pattern);
+    }
+    return sdf.format(date);
+  }
+
+  public static String formatDate(Date date) {
+    SimpleDateFormat sdf = new SimpleDateFormat();
+    return sdf.format(date);
+  }
+
+  public static Date parseDate(String source, String pattern) throws ParseException
+  {
+    SimpleDateFormat sdf = null;
+    if (pattern == null)
+      sdf = new SimpleDateFormat();
+    else {
+      sdf = new SimpleDateFormat(pattern);
+    }
+    return sdf.parse(source);
+  }
+
+  public static Date parseDate(String source) throws ParseException {
+    SimpleDateFormat sdf = new SimpleDateFormat();
+    return sdf.parse(source);
+  }
+
+  public static Date parseDate(String source, Date defaultDate) {
+    try {
+      SimpleDateFormat sdf = new SimpleDateFormat();
+      return sdf.parse(source);
+    }
+    catch (ParseException e)
+    {
+    }
+    return defaultDate;
+  }
+
+  public static Date parseDate(String source, String pattern, Date defaultDate) {
+    try {
+      SimpleDateFormat sdf = null;
+      if (pattern == null)
+        sdf = new SimpleDateFormat();
+      else {
+        sdf = new SimpleDateFormat(pattern);
+      }
+      return sdf.parse(source);
+    }
+    catch (ParseException e) {
+    }
+    return defaultDate;
+  }
+
+  public static boolean tryParse(String source) throws ParseException {
+    try {
+      Integer.parseInt(source);
+      return true;
+    } catch (NumberFormatException e) {
+    }
+    return false;
+  }
+
+  public static Date changeDate(Date date, TimeType timeType, int amount)
+  {
+    if ((date == null) || (timeType == null) || (amount == 0)) {
+      return date;
+    }
+    Calendar c = Calendar.getInstance();
+    c.setTime(date);
+    c.add(timeType.getValue(), amount);
+    return c.getTime();
+  }
+
+  public static boolean isSameDay(Date date1, Date date2)
+  {
+    if ((date1 == null) || (date2 == null)) {
+      throw new IllegalArgumentException("The date must not be null");
+    }
+    Calendar cal1 = Calendar.getInstance();
+    cal1.setTime(date1);
+    Calendar cal2 = Calendar.getInstance();
+    cal2.setTime(date2);
+    return isSameDay(cal1, cal2);
+  }
+
+  public static boolean isSameDay(Calendar cal1, Calendar cal2)
+  {
+    if ((cal1 == null) || (cal2 == null)) {
+      throw new IllegalArgumentException("The date must not be null");
+    }
+    return (cal1.get(0) == cal2.get(0)) && (cal1.get(1) == cal2.get(1)) && (cal1.get(6) == cal2.get(6));
+  }
+
+  /** @deprecated */
+  public static Date add(Date date, int calendarField, int amount)
+  {
+    if (date == null) {
+      throw new IllegalArgumentException("The date must not be null");
+    }
+    Calendar c = Calendar.getInstance();
+    c.setTime(date);
+    c.add(calendarField, amount);
+    return c.getTime();
+  }
+
+  public static Date addYears(Date date, int amount)
+  {
+    return add(date, 1, amount);
+  }
+
+  public static Date addMonths(Date date, int amount)
+  {
+    return add(date, 2, amount);
+  }
+
+  public static Date addWeeks(Date date, int amount)
+  {
+    return add(date, 3, amount);
+  }
+
+  public static Date addDays(Date date, int amount)
+  {
+    return add(date, 5, amount);
+  }
+
+  public static Date addHours(Date date, int amount)
+  {
+    return add(date, 11, amount);
+  }
+
+  public static Date addMinutes(Date date, int amount)
+  {
+    return add(date, 12, amount);
+  }
+
+  public static Date addSeconds(Date date, int amount)
+  {
+    return add(date, 13, amount);
+  }
+
+  public static Date addMilliseconds(Date date, int amount)
+  {
+    return add(date, 14, amount);
+  }
+
+  static
+  {
+    mapChDate.put("01", "一月");
+    mapChDate.put("02", "二月");
+    mapChDate.put("03", "三月");
+    mapChDate.put("04", "四月");
+    mapChDate.put("05", "五月");
+    mapChDate.put("06", "六月");
+    mapChDate.put("07", "七月");
+    mapChDate.put("08", "八月");
+    mapChDate.put("09", "九月");
+    mapChDate.put("10", "十月");
+    mapChDate.put("11", "十一月");
+    mapChDate.put("12", "十二月");
+  }
+
+  public static enum TimeType
+  {
+    SECOND(13), MINUTE(12), HOUR(10), DAY(5), 
+    WEEK(4), MONTH(2), 
+    YEAR(1);
+
+    private int value;
+
+    private TimeType(int value) {
+      this.value = value;
+    }
+
+    public int getValue() {
+      return this.value;
+    }
+  }
+  /**
+   * 
+   * 毛龙飞
+   * @Description 获取日期的后几天
+   * @param d
+   * @param day
+   * @return
+   */
+  public static Date getDateAfter(Date d, int day) {  
+      Calendar now = Calendar.getInstance();  
+      now.setTime(d);  
+      now.set(Calendar.DATE, now.get(Calendar.DATE) + day);  
+      return now.getTime();  
+  }
+}

+ 162 - 0
src/main/java/com/shawn/util/DiskClassLoader.java

@@ -0,0 +1,162 @@
+package com.shawn.util;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import com.shawn.web.exception.MyException;
+
+import java.lang.reflect.InvocationTargetException;
+/**
+ * 自定义类加载器
+ * @author wuhs
+ */
+public class DiskClassLoader extends ClassLoader {
+
+    private String mLibPath;
+    private String splitString="/";
+    
+    public DiskClassLoader(){}
+    
+    public DiskClassLoader(ClassLoader parent) { super(parent); }
+    
+    public DiskClassLoader(String path,String splitString) {
+    	this.splitString = splitString;
+    	this.mLibPath = path;
+    }
+    
+    /**
+     * 递归查找目录下面匹配的类
+     * @param filePath 递归的目录
+     * @param name 包名+类名
+     * @return
+     */
+    public String findClassesInPathByName(String filePath,String name) {
+    	String fileName = getFileName(name);
+    	String result = "";
+        // 获取此包的目录 建立一个File
+    		File dir = new File(filePath);
+    		// 如果不存在或者 也不是目录就直接返回
+    		if (!dir.exists() || !dir.isDirectory()) {
+    			// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
+    			throw new MyException("用户定义包名 " + filePath + " 下没有任何文件");
+    		}
+    		// 如果存在 就获取包下的所有文件 包括目录
+    		File[] dirfiles = dir.listFiles(new FileFilter() {
+    			// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
+    			public boolean accept(File file) {
+    				return (file.isDirectory()) || (file.getName().endsWith(".class"));
+    			}
+    		});
+        		
+    		
+    	// 循环所有文件
+   		for (File file : dirfiles) {
+//   			System.out.println(filePath+ "\\" + file.getName()+";"+className);
+   			// 如果是目录 则继续扫描
+   			if (file.isDirectory()) {
+   				String childResult = findClassesInPathByName(filePath + this.splitString + file.getName(), name);
+   				if(!"".equals(childResult)) {
+   					result = childResult;
+   					break;
+   				}
+   			} else {
+   				//根据包名和类名确定唯一
+   				if(fileName.equals(file.getName()) && (filePath+this.splitString + file.getName()).contains(name.replace(".", this.splitString))) {
+//   					System.out.println(filePath+"\\" + file.getName());
+//   					System.out.println(name.replace(".", "\\"));
+   					result = filePath;
+   					break;
+   				}
+   			}
+   		}
+		return result;
+	}
+    
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+    	
+    	String fileName = getFileName(name);
+    	
+    	String filePath = findClassesInPathByName(mLibPath,name);	
+    	
+    	if("".equals(filePath) ) {
+    		throw new MyException("找不到该类:"+name);
+    	}
+    	
+        File file = new File(filePath,fileName);
+
+        try {
+            FileInputStream is = new FileInputStream(file);
+
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            int len = 0;
+            try {
+                while ((len = is.read()) != -1) {
+                    bos.write(len);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+            byte[] data = bos.toByteArray();
+            is.close();
+            bos.close();
+
+            return defineClass(name,data,0,data.length);
+
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        return super.findClass(name);
+    }
+
+    //获取要加载 的class文件名
+    private String getFileName(String name) {
+        // TODO Auto-generated method stub
+        int index = name.lastIndexOf('.');
+        if(index == -1){ 
+            return name+".class";
+        }else{
+            return name.substring(index+1)+".class";
+        }
+    }
+
+    
+   /* public static void main(String[] args) {
+        // TODO Auto-generated method stub
+
+        //创建自定义classloader对象。
+        DiskClassLoader diskLoader = new DiskClassLoader("D:\\lib");
+        try {
+            //加载class文件
+            Class c = diskLoader.loadClass("com.frank.test.Test");
+
+            if(c != null){
+                try {
+                    Object obj = c.newInstance();
+                    Method method = c.getDeclaredMethod("say",null);
+                    //通过反射调用Test类的say方法
+                    method.invoke(obj, null);
+                } catch (InstantiationException | IllegalAccessException 
+                        | NoSuchMethodException
+                        | SecurityException | 
+                        IllegalArgumentException | 
+                        InvocationTargetException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        } catch (ClassNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }*/
+    
+}

+ 153 - 0
src/main/java/com/shawn/util/DomainEquals.java

@@ -0,0 +1,153 @@
+package com.shawn.util;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import lombok.extern.apachecommons.CommonsLog;
+/**
+ * 比较2个对象的值是否对等
+ * @author wuhs
+ */
+@CommonsLog
+public class DomainEquals {
+	public DomainEquals() {
+    }
+
+    /**
+     * 比较两个BEAN或MAP对象的值是否相等 
+     * 如果是BEAN与MAP对象比较时MAP中的key值应与BEAN的属性值名称相同且字段数目要一致
+     * @param source
+     * @param target
+     * @return
+     */
+    public static boolean domainEquals(Object source, Object target) {
+        if (source == null || target == null) {
+            return false;
+        }
+        boolean rv = true;
+        if (source instanceof Map) {
+            rv = mapOfSrc(source, target, rv);
+        } else {
+            rv = classOfSrc(source, target, rv);
+        }
+//        log.info("THE EQUALS RESULT IS " + rv);
+        return rv;
+    }
+
+    /**
+     * 源目标为MAP类型时
+     * @param source
+     * @param target
+     * @param rv
+     * @return
+     */
+    private static boolean mapOfSrc(Object source, Object target, boolean rv) {
+        HashMap<String, String> map = new HashMap<String, String>();
+        map = (HashMap) source;
+        for (String key : map.keySet()) {
+            if (target instanceof Map) {
+                HashMap<String, String> tarMap = new HashMap<String, String>();
+                tarMap = (HashMap) target;
+                if(tarMap.get(key)==null){
+                    rv = false;
+                    break;
+                }
+                if (!map.get(key).equals(tarMap.get(key))) {
+                    rv = false;
+                    break;
+                }
+            } else {
+                String tarValue = getClassValue(target, key) == null ? "" : getClassValue(target, key).toString();
+                if (!tarValue.equals(map.get(key))) {
+                    rv = false;
+                    break;
+                }
+            }
+        }
+        return rv;
+    }
+
+    /**
+     * 源目标为非MAP类型时
+     * @param source
+     * @param target
+     * @param rv
+     * @return
+     */
+    private static boolean classOfSrc(Object source, Object target, boolean rv) {
+        Class<?> srcClass = source.getClass();
+        Field[] fields = srcClass.getDeclaredFields();
+        for (Field field : fields) {
+            String nameKey = field.getName();
+            if (target instanceof Map) {
+                HashMap<String, String> tarMap = new HashMap<String, String>();
+                tarMap = (HashMap) target;
+                String srcValue = getClassValue(source, nameKey) == null ? "" : getClassValue(source, nameKey)
+                        .toString();
+                if(tarMap.get(nameKey)==null){
+                    rv = false;
+                    break;
+                }
+                if (!tarMap.get(nameKey).equals(srcValue)) {
+                    rv = false;
+                    break;
+                }
+            } else {
+                String srcValue = getClassValue(source, nameKey) == null ? "" : getClassValue(source, nameKey)
+                        .toString();
+                String tarValue = getClassValue(target, nameKey) == null ? "" : getClassValue(target, nameKey)
+                        .toString();
+                if (!srcValue.equals(tarValue)) {
+                    rv = false;
+                    break;
+                }
+            }
+        }
+        return rv;
+    }
+
+    /**
+     * 根据字段名称取值
+     * @param obj
+     * @param fieldName
+     * @return
+     */
+    public static Object getClassValue(Object obj, String fieldName) {
+        if (obj == null) {
+            return null;
+        }
+        try {
+            Class beanClass = obj.getClass();
+            Method[] ms = beanClass.getMethods();
+            for (int i = 0; i < ms.length; i++) {
+                // 非get方法不取
+                if (!ms[i].getName().startsWith("get")) {
+                    continue;
+                }
+                Object objValue = null;
+                try {
+                    objValue = ms[i].invoke(obj, new Object[] {});
+                } catch (Exception e) {
+                	log.info("反射取值出错:" + e.toString());
+                    continue;
+                }
+                if (objValue == null) {
+                    continue;
+                }
+                if (ms[i].getName().toUpperCase().equals(fieldName.toUpperCase())
+                        || ms[i].getName().substring(3).toUpperCase().equals(fieldName.toUpperCase())) {
+                    return objValue;
+                } else if (fieldName.toUpperCase().equals("SID")
+                        && (ms[i].getName().toUpperCase().equals("ID") || ms[i].getName().substring(3).toUpperCase()
+                                .equals("ID"))) {
+                    return objValue;
+                }
+            }
+        } catch (Exception e) {
+            // logger.info("取方法出错!" + e.toString());
+        }
+        return null;
+    }
+
+}

+ 490 - 0
src/main/java/com/shawn/util/FgObjectUtil.java

@@ -0,0 +1,490 @@
+package com.shawn.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.shawn.web.exception.ParamNotFoundException;
+
+
+/**
+ * 
+ * 类说明:对象操作  
+ * @author 吴洪双
+ * 2016年1月13日上午10:57:51
+ */
+public class FgObjectUtil implements Serializable{
+	
+	private static final long serialVersionUID = 455370045995076257L;
+	
+	private static Logger logger = LoggerFactory.getLogger(FgObjectUtil.class);
+	/**
+	 * 递归获取所有父类的属性
+	 * @return
+	 */
+	public static ArrayList<Field> getAllFields(Class<?> object,ArrayList<Field> fieldList){
+		Class<?> supperClass = object.getSuperclass();
+		if(supperClass!=null){
+			Field[] fields = supperClass.getDeclaredFields();
+			for (Field field : fields) {
+				fieldList.add(field);
+			}
+			
+			return getAllFields(supperClass,fieldList);
+		}else{
+			return fieldList;
+		}
+	}
+	/**
+	 * 递归获取所有父类的方法
+	 * @return
+	 */
+	public static ArrayList<Method> getAllMethods(Class<?> object,ArrayList<Method> methodList){
+		Class<?> supperClass = object.getSuperclass();
+		if(supperClass!=null){
+			
+			Method[] methods = supperClass.getMethods();
+			for (Method method : methods) {
+				methodList.add(method);
+			}
+			
+			return getAllMethods(supperClass,methodList);
+		}else{
+			return methodList;
+		}
+	}
+	
+	/**
+	 * 
+	 * 方法说明:对象非空校验
+	 * @author 吴洪双
+	 * 2016年1月13日下午4:52:04
+	 * @param object
+	 * @throws NoSuchMethodException
+	 * @throws SecurityException
+	 * @throws Exception
+	 * @throws ParamNotFoundException
+	 */
+	public static void objectNullOrEmpty(Object object) throws ParamNotFoundException{
+		if (object != null ) {// if (object!=null
+			try{
+				// 拿到该类
+				Class<?> clz = object.getClass();
+				// 获取实体类的所有属性,返回Field数组
+				Field[] fields = clz.getDeclaredFields();
+				ArrayList<Field> fieldList= new ArrayList<Field>();
+				for (Field field : fields) {
+					fieldList.add(field);
+				}
+				//获取实体类所有父类的属性
+				fieldList = getAllFields(clz,fieldList);
+				
+				for (Field field : fieldList) {// --for() begin
+					if("serialVersionUID".equals(field.getName())){
+						continue;
+					}
+					// 如果类型是String
+					if (field.getGenericType().toString().equals("class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名
+						// 拿到该属性的gettet方法
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						String val = (String) m.invoke(object);// 调用getter方法获取属性值
+						if(val==null || val.length() == 0){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Date
+					if (field.getGenericType().toString().equals("class java.util.Date")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Date val = (Date) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Integer
+					if (field.getGenericType().toString().equals("class java.lang.Integer")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Integer val = (Integer) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Double
+					if (field.getGenericType().toString().equals("class java.lang.Double")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Double val = (Double) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Boolean 是封装类
+					if (field.getGenericType().toString().equals("class java.lang.Boolean")) {
+						Method m = (Method) object.getClass().getMethod(field.getName());
+						Boolean val = (Boolean) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是boolean 基本数据类型不一样 这里有点说名如果定义名是 isXXX的 那就全都是isXXX的
+					// 反射找不到getter的具体名
+					if (field.getGenericType().toString().equals("boolean")) {
+						Method m = (Method) object.getClass().getMethod(field.getName());
+						Boolean val = (Boolean) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Short
+					if (field.getGenericType().toString().equals("class java.lang.Short")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Short val = (Short) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					//如果是枚举类型
+					if(field.getGenericType().toString().contains(".bean.enums.")){
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						if(m.invoke(object) == null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					//其他类型
+					Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+					if(m.invoke(object) == null){
+						logger.debug(field.getName()+"is null");
+						throw new ParamNotFoundException(field.getName());
+					}
+				}
+			} catch (NoSuchMethodException e) {
+				e.printStackTrace();
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			} catch (ParamNotFoundException e) {
+				throw e;
+			} catch (Exception e){
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 * 
+	 * 方法说明:非包含的参数校验
+	 * @author 吴洪双
+	 * 2016年1月13日下午5:27:15
+	 * @param object
+	 * @param del
+	 * @throws NoSuchMethodException
+	 * @throws SecurityException
+	 * @throws Exception
+	 * @throws ParamNotFoundException
+	 */
+	public static void objectNullOrEmptyDel(Object object,String del) throws ParamNotFoundException{
+		if (object != null ) {// if (object!=null
+			try{
+				// 拿到该类
+				Class<?> clz = object.getClass();
+				// 获取实体类的所有属性,返回Field数组
+				Field[] fields = clz.getDeclaredFields();
+				ArrayList<Field> fieldList= new ArrayList<Field>();
+				for (Field field : fields) {
+					fieldList.add(field);
+				}
+				//获取实体类所有父类的属性
+				fieldList = getAllFields(clz,fieldList);
+				
+				for (Field field : fieldList) {// --for() begin
+					if(del.contains(field.getName()+"$") || "serialVersionUID".equals(field.getName())){
+						continue;
+					}
+					// 如果类型是String
+					if (field.getGenericType().toString().equals("class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名
+						// 拿到该属性的gettet方法
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						String val = (String) m.invoke(object);// 调用getter方法获取属性值
+						if(val==null || val.length() == 0){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Date
+					if (field.getGenericType().toString().equals("class java.util.Date")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Date val = (Date) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Integer
+					if (field.getGenericType().toString().equals("class java.lang.Integer")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Integer val = (Integer) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Double
+					if (field.getGenericType().toString().equals("class java.lang.Double")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Double val = (Double) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Boolean 是封装类
+					if (field.getGenericType().toString().equals("class java.lang.Boolean")) {
+						Method m = (Method) object.getClass().getMethod(field.getName());
+						Boolean val = (Boolean) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是boolean 基本数据类型不一样 这里有点说名如果定义名是 isXXX的 那就全都是isXXX的
+					// 反射找不到getter的具体名
+					if (field.getGenericType().toString().equals("boolean")) {
+						Method m = (Method) object.getClass().getMethod(field.getName());
+						Boolean val = (Boolean) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Short
+					if (field.getGenericType().toString().equals("class java.lang.Short")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Short val = (Short) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					//如果是枚举类型
+					if(field.getGenericType().toString().contains(".bean.enums.")){
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						if(m.invoke(object) == null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					//其他类型
+					Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+					if(m.invoke(object) == null){
+						logger.debug(field.getName()+"is null");
+						throw new ParamNotFoundException(field.getName());
+					}
+				}
+			} catch (NoSuchMethodException e) {
+				e.printStackTrace();
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			} catch (ParamNotFoundException e) {
+				throw e;
+			} catch (Exception e){
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 * 
+	 * 方法说明:包含的参数校验
+	 * @author 吴洪双
+	 * 2016年1月13日下午5:26:41
+	 * @param object
+	 * @param sel
+	 * @throws NoSuchMethodException
+	 * @throws SecurityException
+	 * @throws Exception
+	 * @throws ParamNotFoundException
+	 */
+	public static void objectNullOrEmptySel(Object object,String sel) throws ParamNotFoundException{
+		if (object != null ) {// if (object!=null
+			try{
+				// 拿到该类
+				Class<?> clz = object.getClass();
+				// 获取实体类的所有属性,返回Field数组
+				Field[] fields = clz.getDeclaredFields();
+				ArrayList<Field> fieldList= new ArrayList<Field>();
+				for (Field field : fields) {
+					fieldList.add(field);
+				}
+				//获取实体类所有父类的属性
+				fieldList = getAllFields(clz,fieldList);
+				
+				for (Field field : fieldList) {// --for() begin
+					if(!sel.contains(field.getName()+"$") || "serialVersionUID".equals(field.getName())){
+						continue;
+					}
+					// 如果类型是String
+					if (field.getGenericType().toString().equals("class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名
+						// 拿到该属性的gettet方法
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						String val = (String) m.invoke(object);// 调用getter方法获取属性值
+						if(val==null || val.length() == 0){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Date
+					if (field.getGenericType().toString().equals("class java.util.Date")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Date val = (Date) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Integer
+					if (field.getGenericType().toString().equals("class java.lang.Integer")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Integer val = (Integer) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Double
+					if (field.getGenericType().toString().equals("class java.lang.Double")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Double val = (Double) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Boolean 是封装类
+					if (field.getGenericType().toString().equals("class java.lang.Boolean")) {
+						Method m = (Method) object.getClass().getMethod(field.getName());
+						Boolean val = (Boolean) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+" is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是boolean 基本数据类型不一样 这里有点说名如果定义名是 isXXX的 那就全都是isXXX的
+					// 反射找不到getter的具体名
+					if (field.getGenericType().toString().equals("boolean")) {
+						Method m = (Method) object.getClass().getMethod(field.getName());
+						Boolean val = (Boolean) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					// 如果类型是Short
+					if (field.getGenericType().toString().equals("class java.lang.Short")) {
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						Short val = (Short) m.invoke(object);
+						if(val==null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					//如果是枚举类型
+					if(field.getGenericType().toString().contains(".bean.enums.")){
+						Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+						if(m.invoke(object) == null){
+							logger.debug(field.getName()+"is null");
+							throw new ParamNotFoundException(field.getName());
+						}
+						continue;
+					}
+					//其他类型
+					Method m = (Method) object.getClass().getMethod("get" + getMethodName(field.getName()));
+					if(m.invoke(object) == null){
+						logger.debug(field.getName()+"is null");
+						throw new ParamNotFoundException(field.getName());
+					}
+				}
+			} catch (NoSuchMethodException e) {
+				e.printStackTrace();
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			} catch (ParamNotFoundException e) {
+				throw e;
+			} catch (Exception e){
+				e.printStackTrace();
+			}
+		}
+		
+	}
+	
+	/**
+	 * 
+	 * 方法说明:返回方法名称   把一个字符串的第一个字母大写、效率是最高的、
+	 * @author 吴洪双
+	 * 2016年1月13日上午11:12:41
+	 * @param fildeName
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getMethodName(String fildeName) throws Exception {
+		byte[] items = fildeName.getBytes();
+		items[0] = (byte) ((char) items[0] - 'a' + 'A');
+		return new String(items);
+	}
+
+	public static Class getPropertyType(Object property) {
+		if(property instanceof String) {
+			return String.class;
+		}
+		else if(property instanceof Integer) {
+			return Integer.class;
+		}
+		else if(property instanceof Long) {
+			return Long.class;
+		}
+		else if(property instanceof Double) {
+			return Double.class;
+		}
+		else if(property instanceof Date) {
+			return Date.class;
+		}
+		else if(property instanceof Boolean) {
+			return Boolean.class;
+		}
+		else {
+			return String.class;
+		}
+	}
+}

+ 42 - 0
src/main/java/com/shawn/util/ListUtils.java

@@ -0,0 +1,42 @@
+package com.shawn.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
+
+public class ListUtils {
+	public static boolean constains(List list,Object node) {
+		CollectionUtils.exists(list, new Predicate() {
+			@Override
+			public boolean evaluate(Object object) {
+				return false;
+			}
+		});
+		
+		return true;
+	}
+//	public static void main(String[] args) {
+//		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+//		Map<String, Object> map = new HashMap<String, Object>();
+//		map.put("a", "2");
+//		map.put("b", "3");
+//		
+//		Map<String, Object> map2 = new HashMap<String, Object>();
+//		map2.put("a", "1");
+//		map2.put("b", "1");
+//		list.add(map2);
+//		list.add(map);
+//		Map<String, Object> m = (Map<String, Object>) CollectionUtils.find(list, new Predicate() {
+//			@Override
+//			public boolean evaluate(Object object) {
+//				String str = String.valueOf(((Map<String,Object>)object).get("a"));
+//				return str.equals("2");
+//			}
+//		});
+//		System.out.println(m==null);
+//	}
+}

+ 70 - 0
src/main/java/com/shawn/util/PackageUtil.java

@@ -0,0 +1,70 @@
+package com.shawn.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashSet;
+import java.util.Set;
+/**
+ * 获取文件下的所有class
+ * @author wuhs
+ *
+ */
+public class PackageUtil {
+	
+	/*public static void main(String[] args) {
+		DiskClassLoader diskLoader = new DiskClassLoader("D:\\workplace\\javaWorkplace\\DirectiveServer\\target\\classes\\com\\shawn\\model\\entity");
+		Set<Class<?>> classes = new HashSet<Class<?>>();
+		findAndAddClassesInPackageByFile(diskLoader,"com.shawn.model.entity", "D:\\workplace\\javaWorkplace\\DirectiveServer\\target\\classes\\com\\shawn\\model\\entity", false, classes);
+		System.out.println(classes);
+	}*/
+	
+	/**
+	 * 以文件的形式来获取包下的所有Class
+	 * 
+	 * @param packageName
+	 * @param packagePath
+	 * @param recursive 递归查找所有子目录
+	 * @param classes
+	 * @param fileType 1:class,2:java
+	 */
+	public static void findAndAddClassesInPackageByFile(DiskClassLoader diskLoader,String packageName, String packagePath, final boolean recursive,
+			Set<Class<?>> classes) {
+		// 获取此包的目录 建立一个File
+		File dir = new File(packagePath);
+		// 如果不存在或者 也不是目录就直接返回
+		if (!dir.exists() || !dir.isDirectory()) {
+			// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
+			return;
+		}
+		// 如果存在 就获取包下的所有文件 包括目录
+		File[] dirfiles = dir.listFiles(new FileFilter() {
+			// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
+			public boolean accept(File file) {
+				return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
+			}
+		});
+		// 循环所有文件
+		for (File file : dirfiles) {
+			// 如果是目录 则继续扫描
+			if (file.isDirectory()) {
+				findAndAddClassesInPackageByFile(diskLoader,packageName + "." + file.getName(), file.getAbsolutePath(), recursive,
+						classes);
+			} else {
+				// 如果是java类文件 去掉后面的.class 只留下类名
+				String className= file.getName().substring(0, file.getName().length() - 6);
+				try {
+					// 添加到集合中去
+//					 classes.add(Class.forName(packageName + '.' + className));
+					// 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
+//					classes.add(diskLoader.loadClass(className));
+					classes.add(diskLoader.loadClass(packageName + '.' + className));
+				} catch (ClassNotFoundException e) {
+					// log.error("添加用户自定义视图类错误 找不到此类的.class文件");
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+}

+ 103 - 0
src/main/java/com/shawn/util/PageUtil.java

@@ -0,0 +1,103 @@
+package com.shawn.util;
+
+import com.shawn.web.exception.ParameterIllegalException;
+
+/**
+ * @author 吴洪双
+ */
+public class PageUtil {
+
+    /**
+     * Calculate offset for LIMIT clause in SQL. If page < 1, it will return 0.
+     *
+     * @param page    page number
+     * @param perPage size of per page
+     * @return offset
+     */
+    public static int calculateOffset(int page, int perPage) {
+        return calculateOffset(page, perPage, 0);
+    }
+
+    /**
+     * Calculate offset for LIMIT clause in SQL. If page < 1, it will return defaultValue.
+     *
+     * @param page         page number
+     * @param perPage      size of per page
+     * @param defaultValue default return value, if page < 1
+     * @return offset
+     */
+    public static int calculateOffset(int page, int perPage, int defaultValue) {
+        return page < 1 ? defaultValue : (page - 1) * perPage;
+    }
+
+    /**
+     * Calculate total number of pages.
+     *
+     * @param rowCount count of rows
+     * @param perPage  size of per page
+     * @return total number of pages
+     */
+    public static int calculateTotalPage(int rowCount, int perPage) {
+        return (rowCount % perPage == 0) ? (rowCount / perPage) : (rowCount / perPage + 1);
+    }
+
+    /**
+     * Parse page from String to int.
+     *
+     * @param pageString   origin
+     * @param defaultValue default page, if pageString == null
+     * @return parsed page
+     */
+    public static int parsePage(String pageString, int defaultValue) {
+        return parseParameter(pageString, defaultValue);
+    }
+
+    /**
+     * Parse size of per page from String to int.
+     *
+     * @param perPageString origin
+     * @param defaultValue  default size of per page, if perPageString == null
+     * @return parsed size of per page
+     */
+    public static int parsePerPage(String perPageString, int defaultValue) {
+        return parsePage(perPageString, defaultValue);
+    }
+    public static int parsePerPage(Integer perPageInteger, int defaultValue) {
+    	return parsePage(perPageInteger.toString(), defaultValue);
+    }
+    
+    public static int parseOffset(String offsetString, int defaultValue) {
+    	return parsePage(offsetString, defaultValue);
+    }
+    public static int parseOffset(Integer offsetInteger, int defaultValue) {
+    	return parsePage(offsetInteger.toString(), defaultValue);
+    }
+
+    /**
+     * A helper method, parsing parameter about pagination.
+     * If the string is null, return the default value.
+     * If the string is not a number or the number < 1,
+     * throw a parameter illegal exception.
+     *
+     * @param parameterString origin
+     * @param defaultValue default value, if parameterString == null
+     * @return parsed parameter
+     */
+    private static int parseParameter(String parameterString, int defaultValue) {
+        if (parameterString == null) {
+            return defaultValue;
+        }
+
+        int parameter;
+        try {
+            parameter = Integer.parseInt(parameterString);
+        } catch (Exception e) {
+            throw new ParameterIllegalException();
+        }
+        if (parameter < 0) {
+            throw new ParameterIllegalException();
+        }
+        return parameter;
+    }
+
+}

+ 138 - 0
src/main/java/com/shawn/util/ProjectOutputClass.java

@@ -0,0 +1,138 @@
+package com.shawn.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+
+/**
+ *根据svn日志导出增量包
+ *使用教程请看
+ *https://blog.csdn.net/wind_rocku/article/details/78882250
+ * @author wuhs
+ */
+public class ProjectOutputClass {
+
+	/**
+	 * 拷贝文件
+	 * 
+	 * @param logFile
+	 *            想要读取svn日志的文件对象
+	 * @param appDir
+	 *            工程所在的文件夹的路径
+	 * @param desDir
+	 *            导出所在文件夹的路径
+	 * @return 返回文件内容
+	 */
+	public static String copyFiles(File logFile, String appDir, String desDir,String projectName) {
+		StringBuilder result = new StringBuilder();
+		try {
+			BufferedReader br = new BufferedReader(new FileReader(logFile));// 构造一个BufferedReader类来读取文件
+			String s = null;
+			int size = 1;
+			while ((s = br.readLine()) != null) {// 使用readLine方法,一次读一行
+				int index = s.indexOf("/"+projectName);
+				if (index < 0) {
+					continue;
+				}
+				System.out.println(s);
+				s = s.substring(index + projectName.length()+1);
+				String targetFile = s.substring(s.lastIndexOf("/")+1);//文件全名
+				targetFile.replace(".java", ".class");
+				String targetFileName = s.substring(s.lastIndexOf("/")+1);//文件名称
+				s = s.replace(targetFileName, "");
+				String targetFileNameSuffix = targetFileName.substring(targetFileName.lastIndexOf("."));//文件后缀
+				if(!"".equals(targetFileNameSuffix)) {
+					targetFileName = targetFileName.replace(targetFileNameSuffix, "");
+				}
+				targetFileNameSuffix = ".java".equals(targetFileNameSuffix)?".class":targetFileNameSuffix;
+				// 把java文件路径替换成编译好的classes文件的路径
+				if (s.contains("/src/main/java/")) {
+					s = s.replace("/src/main/java/", "/target/classes/");
+				}
+				if (s.contains("/src/main/resources/")) {
+					s = s.replace("/src/main/resources/", "/target/classes/");
+				}
+				
+				// 过滤掉重复的源文件目录
+				/*if (result.indexOf(s) > -1) {
+					continue;
+				}*/
+				String desStr = desDir + s.replace("/target/classes/", "/");
+				File srcFile = new File(appDir + s); // 源文件对象 所在文件夹
+				
+				if (!(srcFile.exists())) { // 判断源文件夹是否存在
+					System.out.println(appDir + s + "文件夹不存在.......");
+					continue;
+				}
+				
+				File [] files = srcFile.listFiles();//源文件对象 所在文件夹 下的所有文件
+				for (File file : files) {
+					if(file.isDirectory()) {
+						continue;
+					}
+					String compareFileName = file.getName();//对比的文件名
+					String compareFileSuffix = compareFileName.substring(compareFileName.lastIndexOf("."));//对比的文件名后缀
+					compareFileName = compareFileName.replace(compareFileSuffix, "");
+					
+					if(compareFileSuffix.equals(targetFileNameSuffix) && (targetFileName.equals(compareFileName) || compareFileName.contains(targetFileName+"$"))) {
+						File destFile = new File(desStr + file.getName()); // 目标文件对象
+						if (!(destFile.exists())) { // 判断目标文件是否存在
+							/*desStr = desStr.substring(0, desStr.lastIndexOf("/"));
+							File dir = new File(desStr);
+							// 创建文件夹
+							if (!dir.exists()) {
+								dir.mkdirs();
+							}*/
+							// 检测是否存在目录
+							if (!destFile.getParentFile().exists()) {
+								destFile.getParentFile().mkdirs();
+							}
+							// 创建文件
+							destFile.createNewFile(); // 如果不存在则创建新文件
+						}
+						// 使用源文件对象创建文件输入流对象
+						FileInputStream fis = new FileInputStream(file);
+						// 使用目标文件对象创建文件输出流对象
+						FileOutputStream fos = new FileOutputStream(destFile);
+						byte[] buf = new byte[(int) file.length()]; // 创建字节数组,作为临时缓冲
+						System.out.println("开始复制文件..." + size);
+						// while (fis.read(buf) != -1) { //循环从文件输入流中读取数据
+						fis.read(buf);
+						fos.write(buf); // 写入到文件输出流中
+						// }
+						System.out.println("文件:" + file.getName());
+						System.out.println("文件复制成功!");
+						fis.close(); // 关闭流
+						fos.close();
+						result.append(s + System.lineSeparator());
+						size++;
+					}
+				}
+			}
+			size--;
+			System.out.println("文件复制总数: " + size + "个!");
+			br.close();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return result.toString();
+	}
+
+	public static void main(String[] args) {
+		// 工程所在的文件夹
+//		String appDir = "/Users/wuhs/workplace/javaWorkplace/PortalServer";
+		String appDir = "/Users/wuhs/workplace/javaWorkplace/webflow";
+//		String appDir = "/Users/wuhs/workplace/javaWorkplace/FlowableServer";
+		// 导出所在文件夹
+//		String desDir = "/Users/wuhs/Desktop/portal20180728/PortalServer-1.0.0/WEB-INF/classes";
+		String desDir = "/Users/wuhs/Desktop/webflow201801128/webflow-1.0.0/WEB-INF/classes";
+//		String desDir = "/Users/wuhs/Desktop/flowable20180918/FlowableServer-1.0.0/WEB-INF/classes";
+		// svn日志存放位置
+		File logFile = new File("/Users/wuhs/Desktop/changeLog.txt");
+		String projectName = appDir.substring(appDir.lastIndexOf("/")+1);//项目名称
+		copyFiles(logFile, appDir, desDir,projectName);
+	}
+
+}

+ 72 - 0
src/main/java/com/shawn/util/ReadLog.java

@@ -0,0 +1,72 @@
+package com.shawn.util;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ReadLog {
+
+	public static void readLog(String logFile) {
+		InputStreamReader isr = null;
+		BufferedReader reader = null;
+		try {
+			// 以行为单位读取文件内容,一次读一整行
+			isr = new InputStreamReader(new FileInputStream(logFile), "UTF-8");
+			reader = new BufferedReader(isr);
+			String tempString = null;
+			List<String> resultList = new ArrayList<String>();
+			// 一次读入一行,直到读入null为文件结束
+			while ((tempString = reader.readLine()) != null) {
+				// 显示行号
+				int index = tempString.indexOf("type~add^dbsyid~");
+				if (index < 0) {
+					continue;
+				}
+				StringBuffer result = new StringBuffer();
+				result.append(tempString);
+				tempString = reader.readLine(); // 继续读下一行
+				result.append(tempString);
+
+				String startTime = result.substring(0, 17);
+				String seq = result.substring(result.indexOf("docno~") + 6, result.indexOf("docno~") + 6 + 16);
+				String fromuser = result.substring(result.indexOf("fromuser~") + 9,
+						result.indexOf("fromuser~") + 9 + 3);
+				String result2 = "时间:" + startTime + " 单号:" + seq + " 发起人:" + fromuser;
+//				System.out.println(result);
+				long i = resultList.stream().filter(e -> e.indexOf(seq)>0).count();
+				if(i<=0) {
+					resultList.add(result2);
+				}
+			}
+			
+			for (String string : resultList) {
+				System.out.println(string);
+			}
+			reader.close();
+			isr.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch (IOException e1) {
+				}
+			}
+			if (isr != null) {
+				try {
+					isr.close();
+				} catch (IOException e1) {
+				}
+			}
+		}
+	}
+
+	public static void main(String[] args) {
+		String logFile = "/Users/wuhs/Desktop/log3.txt";
+		readLog(logFile);
+	}
+}

+ 470 - 0
src/main/java/com/shawn/web/controller/base/BaseController.java

@@ -0,0 +1,470 @@
+package com.shawn.web.controller.base;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.shawn.constant.PageConstant;
+import com.shawn.model.bean.PageBean;
+import com.shawn.model.dto.PaginatedResult;
+import com.shawn.model.dto.ResultMessage;
+import com.shawn.service.base.BaseServiceInterface;
+import com.shawn.util.FgObjectUtil;
+import com.shawn.util.PageUtil;
+import com.shawn.web.exception.MyException;
+import com.shawn.web.exception.ResourceNotFoundException;
+
+import lombok.extern.apachecommons.CommonsLog;
+/*
+ * 一:@RequestParam 与 @RequestBody
+ * 1、@RequestParam 用来处理 content-type 为 application/x-www-form-urlencoded 编码的内容
+ * 2、@RequestBody 用来处理除content-type 为 application/x-www-form-urlencoded 编码的内容
+ * 如 application/json,application/xml 
+ * 
+ * 二:在不给定注解的情况下,参数默认是怎么绑定的?
+ * 1、若为简单类型:调用@RequestParam
+ * 2、若为复杂类型,如对象,调用@ModelAttribute
+ */
+@CommonsLog
+public abstract class BaseController<ENTITY, ENTITYExample,ENTITYParam, ID extends Serializable> {
+	protected BaseServiceInterface<ENTITY,ENTITYExample,ENTITYParam, ID> baseService;
+	public BaseController(BaseServiceInterface<ENTITY,ENTITYExample,ENTITYParam, ID> service){
+		this.baseService = service;
+	}
+	
+	/**
+	 * 自定义获取各model的id
+	 * @param entity
+	 * @return
+	 * @throws InvocationTargetException 
+	 * @throws IllegalArgumentException 
+	 * @throws IllegalAccessException 
+	 * @throws SecurityException 
+	 * @throws NoSuchMethodException 
+	 */
+	protected ID getEntityId(ENTITY entity) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+        Class entityClass = entity.getClass();
+        Method m = entityClass.getDeclaredMethod("getPrimaryKey");
+        m.setAccessible(true);//因为写成private 所以这里必须设置
+        return (ID)m.invoke(entity);
+	}
+	/**
+	 * 自定义设置各model的id
+	 * @param entity
+	 * @return
+	 * @throws InvocationTargetException 
+	 * @throws IllegalArgumentException 
+	 * @throws IllegalAccessException 
+	 * @throws SecurityException 
+	 * @throws NoSuchMethodException 
+	 */
+	protected void setEntityId(ENTITY entity,ID id) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+		Class entityClass = entity.getClass();
+        Method m = entityClass.getDeclaredMethod("hasPrimaryKey");
+        m.setAccessible(true);//因为写成private 所以这里必须设置
+        boolean flag = (boolean)m.invoke(entity);
+        if(flag) {
+        	Object property = getEntityId(entity);// 调用getter方法获取属性值
+        	Method m2 = entityClass.getDeclaredMethod("setPrimaryKey",FgObjectUtil.getPropertyType(property));
+        	m2.setAccessible(true);//因为写成private 所以这里必须设置
+        	m2.invoke(entity,id);
+        }
+		
+		/*if(id instanceof String) {
+			Method m = entityClass.getDeclaredMethod("setPrimaryKey",String.class);
+			m.setAccessible(true);//因为写成private 所以这里必须设置
+			m.invoke(entity,id);
+		}else if(id instanceof Long){
+			Method m = entityClass.getDeclaredMethod("setPrimaryKey",Long.class);
+			m.setAccessible(true);//因为写成private 所以这里必须设置
+			m.invoke(entity,id);
+		}else if(id instanceof Integer) {
+			Method m = entityClass.getDeclaredMethod("setPrimaryKey",Integer.class);
+			m.setAccessible(true);//因为写成private 所以这里必须设置
+			m.invoke(entity,id);
+		}*/
+	}
+	/**
+	 * 自定义new 一个实体对应的ENTITYExample
+	 * @return
+	 */
+	protected abstract ENTITYExample createNewExample();
+	/**
+	 * 自定义获取model 表的名称
+	 */
+	protected String getResourceName() {
+		return baseService.getResourceName();
+	}
+	
+	
+	/**
+	 * 根据id获取一条实体表记录
+	 * @param id
+	 * @return
+	 */
+    @GetMapping("/{id}")
+    public ResponseEntity<?> getEntityById(@PathVariable ID id) {
+    	ENTITY entity = baseService.selectEntityById(id);
+    	if(entity==null){
+    		throw new ResourceNotFoundException()
+			.setResourceName(getResourceName())
+			.setId(id.toString());
+    	}
+    	return ResponseEntity
+				.status(HttpStatus.OK)
+				.body(new ResultMessage()
+						.setCode(true)
+						.setData(entity)
+						.setMessage("SUCCESS"));
+    }
+    /**
+     * 校验数据库连接
+     * @return
+     */
+    @GetMapping("/checkDB")
+    public ResponseEntity<?> checkDB() {
+    	return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setData( baseService.checkDB())
+                        .setMessage("SUCCESS"));
+    }
+   
+    
+   
+    /**
+     * 新增实体表数据
+     * @param entity
+     * @return
+     * @throws SecurityException 
+     * @throws NoSuchMethodException 
+     * @throws InstantiationException 
+     * @throws InvocationTargetException 
+     * @throws IllegalArgumentException 
+     * @throws IllegalAccessException 
+     */
+    @PostMapping("/postEntity")
+    public ResponseEntity<?> postEntity(@RequestBody ENTITY entity) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
+    	Class entityClass = entity.getClass();
+    	setEntityId(entity, (ID)baseService.generateUniqueID());
+    	Integer i = baseService.insert(entity);
+    	return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setData(i)
+                        .setMessage("SUCCESS"));
+    }
+ 
+    /**
+     * 根据id 更新实体表
+     * @param id
+     * @param entity
+     * @return
+     * @throws SecurityException 
+     * @throws NoSuchMethodException 
+     * @throws InvocationTargetException 
+     * @throws IllegalArgumentException 
+     * @throws IllegalAccessException 
+     */
+    @PutMapping("/{id}")
+    public ResponseEntity<?> putEntity(@PathVariable ID id, @RequestBody ENTITY entity) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+    	log.debug("id:"+id);
+        assertEntityExist(id);
+        setEntityId(entity,id);
+        baseService.updateById(entity);
+
+        return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setData(entity)
+                        .setMessage("SUCCESS"));
+    }
+
+    /**
+     * 根据id删除实体表数据
+     * @param id
+     * @return
+     */
+    @DeleteMapping("/{id}")
+    public ResponseEntity<?> deleteEntity(@PathVariable ID id) {
+    	assertEntityExist(id);
+
+    	baseService.deleteById(id);
+
+    	return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setMessage("SUCCESS"));
+    }
+    
+    @GetMapping("/selectAllByPage")
+    public ResponseEntity<?> selectAllByPage(@RequestParam(value = "offset", required = false)String offsetString, 
+    		@RequestParam(value = "limit", required = false) String limitString, 
+    		@RequestParam(value = "order", required = false) String order ) 
+    				throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
+        // Parse request parameters
+        int offset = PageUtil.parseOffset(offsetString, PageConstant.OFFSET);
+        int limit = PageUtil.parsePerPage(limitString, PageConstant.LIMIT);
+        ENTITYExample example = createNewExample();
+        Class exampleClass = example.getClass();
+        Method m = exampleClass.getDeclaredMethod("setLimit", Integer.class);
+        m.setAccessible(true);//因为写成private 所以这里必须设置
+        m.invoke(exampleClass.newInstance(), limit);
+        
+        Method m2 = exampleClass.getDeclaredMethod("setOffset", Integer.class);
+        m2.setAccessible(true);//因为写成private 所以这里必须设置
+        m2.invoke(exampleClass.newInstance(), offset);
+        
+        return ResponseEntity
+                .ok(new PaginatedResult()
+                		.setCode(true)
+                        .setData(baseService.selectByOption(example))
+                        .setTotal(baseService.selectCount(null).intValue()));
+    }
+    /**
+     * 获取实体表所有数据
+     * @return
+     */
+    @GetMapping("/selectAll")
+    public ResponseEntity<?> selectAll() {
+    	
+		List<ENTITY>  entityList = baseService.selectByOption(null);
+		return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setData(entityList)
+                        .setMessage("SUCCESS"));
+		
+	}
+    /**
+     * 获取实体表总记录数
+     * @return
+     */
+    @GetMapping("/selectCount")
+    public ResponseEntity<?> getCount() {
+    	Long result = baseService.selectCount(null);
+    	return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setData(result)
+                        .setMessage("SUCCESS"));
+    }
+    
+	/**
+	 * 根据表字段条件查询单表数据
+	 * 只作用于单表,并且所有条件都为EqualTo
+	 * 字段加后缀_like,则做模糊查询
+	 * 字段加后缀_start,则做>=查询
+	 * 字段加后缀_end,则做<=查询
+	 * 
+	 */
+    @GetMapping("/selectEntityByEqualToOption")
+	public ResponseEntity<?> selectEntityByEqualToOption(ENTITYParam param) {
+		ENTITYExample example = (ENTITYExample) entity2example(param,createNewExample());
+		List<ENTITY>  entityList = baseService.selectByOption(example);
+		return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(true)
+                        .setData(entityList)
+                        .setMessage("SUCCESS"));
+	}
+    /**
+	 * 根据表字段条件查询单表数据
+	 * 只作用于单表,并且所有条件都为EqualTo
+	 * 字段加后缀_like,则做模糊查询
+	 * 字段加后缀_start,则做>=查询
+	 * 字段加后缀_end,则做<=查询
+	 * 
+	 */
+    @GetMapping("/selectEntityByEqualToOptionByPage")
+    public ResponseEntity<?> selectEntityByEqualToOptionByPage(ENTITYParam param) 
+    		throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
+        ENTITYExample example = (ENTITYExample) entity2example(param,createNewExample());
+        List<ENTITY>  entityList = baseService.selectByOption(example);
+        return ResponseEntity
+                .ok(new PaginatedResult()
+                		.setCode(true)
+                        .setData(entityList)
+                        .setTotal(baseService.selectCount(example).intValue()));
+    }
+    /**
+   	 * 批量更新
+   	 */
+   	@PutMapping("/updateBatchByIdList")
+   	public ResponseEntity<?> updateBatchByIdList(@RequestBody ENTITYParam param) {
+   		
+   		int i= baseService.updateBatchByIdList(param);
+       	return ResponseEntity
+                   .status(HttpStatus.OK)
+                   .body(new ResultMessage()
+                           .setCode(true)
+                           .setData(i)
+   						.setMessage("批量更新"+i+"条数据"));
+   		
+   	}
+   	/**
+   	 * 批量删除
+   	 * @throws InvocationTargetException 
+   	 * @throws IllegalArgumentException 
+   	 * @throws IllegalAccessException 
+   	 * @throws SecurityException 
+   	 * @throws NoSuchMethodException 
+   	 */
+   	@DeleteMapping("/deleteBatchByIdList")
+   	public ResponseEntity<?> deleteBatchByIdList(@RequestBody ENTITYParam param) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+   		Method method = (Method) param.getClass().getMethod("getPrimaryKeyList");
+           List primaryKeyList = (List)method.invoke(param);//获取主键list
+           
+   		int i= baseService.deleteBatchByIdList(primaryKeyList);
+   		return ResponseEntity
+   				.status(HttpStatus.OK)
+   				.body(new ResultMessage()
+   						.setCode(true)
+   						.setData(i)
+   						.setMessage("批量删除"+i+"条数据"));
+   		
+   	}
+   	/**
+   	 * 批量新增
+   	 * @throws ParseException 
+   	 * @throws SecurityException 
+   	 * @throws NoSuchMethodException 
+   	 * @throws InvocationTargetException 
+   	 * @throws IllegalArgumentException 
+   	 * @throws IllegalAccessException 
+   	 */
+   	@PostMapping("/batchInsert")
+   	public ResponseEntity<?> batchInsert(@RequestBody ENTITYParam param) throws ParseException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+   		Method method = (Method) param.getClass().getMethod("getEntityList");
+   		List<ENTITY> entityList = (List<ENTITY>)method.invoke(param);//获取实体list
+        for (ENTITY entity : entityList) {
+        	setEntityId(entity, (ID)baseService.generateUniqueID());
+		}
+   		int i= baseService.insertBatch(entityList);
+   		return ResponseEntity
+   				.status(HttpStatus.OK)
+   				.body(new ResultMessage()
+   						.setCode(true)
+   						.setData(i)
+   						.setMessage("批量新增"+i+"条数据"));
+   		
+   	}
+    /********************************** HELPER METHOD ***********************************/
+    protected ENTITY assertEntityExist(ID id) {
+    	return baseService
+                .selectById(id)
+                .orElseThrow(() -> new ResourceNotFoundException()
+                        .setResourceName(getResourceName())
+                        .setId(id.toString()));
+    }
+    
+    /**
+     * 将实体的字段自动转为example的EqualTo
+     * @param entity
+     * @param example
+     * @return
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+	protected Object entity2example(Object entity,Object example){
+    	try {
+	        Class exampleClass = example.getClass();
+	        Method createCriteriaMethod = (Method) exampleClass.getMethod("createCriteria");
+	        Object criteria = createCriteriaMethod.invoke(example);//生成criteria
+	        Class criteriaClass = criteria.getClass();
+	        
+	        //实体
+	        Class entityClass = entity.getClass();
+	        Field[] fields = entityClass.getDeclaredFields();
+	        
+			ArrayList<Field> fieldList= new ArrayList<Field>();
+			for (Field field : fields) {
+				fieldList.add(field);
+			}
+			//获取实体类所有父类的属性
+			fieldList = FgObjectUtil.getAllFields(entityClass,fieldList);
+	        
+	        for (Field field : fieldList) {
+	        	String nameKey = field.getName();
+	    		if("serialVersionUID".equals(nameKey)){
+					continue;
+				}
+	    		
+    			if("distinct".equals(nameKey)) {
+    				Method entityMethod = (Method) entityClass.getMethod("is" + FgObjectUtil.getMethodName(nameKey));
+        			Object  property = entityMethod.invoke(entity);// 调用getter方法获取属性值
+        			if(null ==property || "".equals(property)){
+        				continue;
+        			}
+        			Method m = exampleClass.getMethod("set"+ FgObjectUtil.getMethodName(nameKey), boolean.class);
+    		        m.invoke(example, property);
+    		        continue;
+    			}
+    			
+    			Method entityMethod = (Method) entityClass.getMethod("get" + FgObjectUtil.getMethodName(nameKey));
+    			Object  property = entityMethod.invoke(entity);// 调用getter方法获取属性值
+    			if(null ==property || "".equals(property)){
+    				continue;
+    			}
+    			
+    			if("orderByClause".equals(nameKey)||"limit".equals(nameKey)||"offset".equals(nameKey)) {
+	    			
+	    			Method m = exampleClass.getMethod("set"+ FgObjectUtil.getMethodName(nameKey), FgObjectUtil.getPropertyType(property));
+    		        m.invoke(example, property);
+	    			
+	    		}else if(nameKey.endsWith("_start")||nameKey.endsWith("_end")) {
+	    			String nameKey2 =nameKey.replace("_start", "").replace("_end", "");
+    				if(nameKey.endsWith("_start")) {
+    					Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey2)+"GreaterThanOrEqualTo",FgObjectUtil.getPropertyType(property));
+	    				criteriaMethod.invoke(criteria,property);
+    				}else {
+    					Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey2)+"LessThanOrEqualTo",FgObjectUtil.getPropertyType(property));
+	    				criteriaMethod.invoke(criteria,property);
+    				}
+	    				
+	    		}else if(nameKey.endsWith("_like")){
+	    			String nameKey2 =nameKey.replace("_like", "");
+    				//like 参数必须为string
+					Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey2)+"Like",String.class);
+    				criteriaMethod.invoke(criteria,"%"+property.toString()+"%");
+	    		}else {
+	    			try {
+	    				Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey)+"EqualTo",FgObjectUtil.getPropertyType(property));
+	    				criteriaMethod.invoke(criteria,property);
+					} catch (Exception e) {
+						log.debug("实体不存在该字段:"+nameKey);
+					}
+	    		}
+	    		
+	        }
+	        return example;  
+        } catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+		
+    }
+   
+}

+ 96 - 0
src/main/java/com/shawn/web/exception/ExceptionHandlerControllerAdvice.java

@@ -0,0 +1,96 @@
+package com.shawn.web.exception;
+
+import org.apache.catalina.servlet4preview.http.HttpServletRequest;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import com.shawn.constant.ErrorCode;
+import com.shawn.model.dto.Error;
+import com.shawn.model.dto.ResultMessage;
+
+import lombok.extern.apachecommons.CommonsLog;
+
+/**
+ * @author 吴洪双
+ */
+@CommonsLog
+@ControllerAdvice
+class ExceptionHandlerControllerAdvice {
+	
+	@ExceptionHandler(MyException.class)
+	public ResponseEntity<?> MyExceptionHandler(HttpServletRequest request, MyException e) {
+		logError(request, e);
+		
+		return ResponseEntity
+				.status(HttpStatus.OK)
+				.body(new ResultMessage()
+						.setCode(false)
+						.setMessage(e.getMessage())); 
+	}
+    @ExceptionHandler(ParamNotFoundException.class)
+    public ResponseEntity<?> paramNotFoundExceptionHandler(HttpServletRequest request, ParamNotFoundException e) {
+        logError(request, e);
+        
+        return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(new ResultMessage()
+                        .setCode(false)
+                        .setMessage(e.getMessage())); 
+   }
+    @ExceptionHandler(ResourceNotFoundException.class)
+    public ResponseEntity<?> resourceNotFoundExceptionHandler(HttpServletRequest request, ResourceNotFoundException e) {
+    	logError(request, e);
+    	
+    	return ResponseEntity
+    			.status(HttpStatus.OK)
+    			.body(new ResultMessage()
+    					.setCode(false)
+    					.setMessage(e.getMessage())); 
+    }
+
+    @ExceptionHandler(ParameterIllegalException.class)
+    public ResponseEntity<?> parameterIllegalExceptionHandler(HttpServletRequest request, ParameterIllegalException e) {
+        logError(request, e);
+
+        return ResponseEntity
+                .status(HttpStatus.BAD_REQUEST)//400
+                .body(new Error()
+                        .setCode(ErrorCode.PARAMETER_ILLEGAL_ERROR)
+                        .setMessage("An invalid value was specified for one of the query parameters in the request URL."));
+    }
+
+    @ExceptionHandler(ServerInternalErrorException.class)
+    public ResponseEntity<?> serverInternalErrorExceptionHandler(HttpServletRequest request, ServerInternalErrorException e) {
+        logError(request, e);
+
+        return ResponseEntity
+                .status(HttpStatus.INTERNAL_SERVER_ERROR)
+                .body(new Error()
+                        .setCode(ErrorCode.RESOURCE_NOT_FOUND_ERROR)//500
+                        .setMessage("The server encountered an internal error. Please retry the request."));
+    }
+
+    @ExceptionHandler(Exception.class)
+    public ResponseEntity<?> exceptionHandler(HttpServletRequest request, Exception e) {
+        logError(request, e);
+
+        return ResponseEntity
+                .status(HttpStatus.INTERNAL_SERVER_ERROR)
+                .body(new Error()
+                        .setCode(ErrorCode.SERVER_INTERNAL_ERROR)
+                        .setMessage("The server met an unexpected error. Please contact administrators."));
+    }
+
+    /********************************** HELPER METHOD **********************************/
+    private void logError(HttpServletRequest request, Exception e) {
+        log.error("[URI: " + request.getRequestURI() + "]"
+                + "[error: " + e.getMessage() + "]");
+    }
+    /*private void logInfo(HttpServletRequest request, Exception e) {
+    	log.info("[URI: " + request.getRequestURI() + "]"
+    			+ "[Info: " + e.getMessage() + "]");
+    }*/
+
+}

+ 24 - 0
src/main/java/com/shawn/web/exception/MyException.java

@@ -0,0 +1,24 @@
+package com.shawn.web.exception;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+/**
+ * 违反唯一约束条件
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@Setter
+@Getter
+public class MyException extends RuntimeException {
+
+    private static final long serialVersionUID = -2565431806475335331L;
+    
+    String message;
+    
+    public MyException(String message){
+    	this.message = message;
+    }
+    
+}

+ 25 - 0
src/main/java/com/shawn/web/exception/ParamNotFoundException.java

@@ -0,0 +1,25 @@
+package com.shawn.web.exception;
+
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+/**
+ * 参数不符或缺失时报错
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@Setter
+public class ParamNotFoundException extends RuntimeException {
+
+    private static final long serialVersionUID = -2565431806475335331L;
+
+    public ParamNotFoundException(String paramName){
+    	this.paramName = paramName;
+    }
+    private String paramName;
+    @Override
+    public String getMessage() {
+        return paramName + " is not null or empty";
+    }
+
+}

+ 10 - 0
src/main/java/com/shawn/web/exception/ParameterIllegalException.java

@@ -0,0 +1,10 @@
+package com.shawn.web.exception;
+
+/**
+ * @author 吴洪双
+ */
+public class ParameterIllegalException extends RuntimeException {
+
+    private static final long serialVersionUID = 8197086462208138875L;
+
+}

+ 24 - 0
src/main/java/com/shawn/web/exception/ResourceNotFoundException.java

@@ -0,0 +1,24 @@
+package com.shawn.web.exception;
+
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @author 吴洪双
+ */
+@Accessors(chain = true)
+@Setter
+public class ResourceNotFoundException extends RuntimeException {
+
+    private static final long serialVersionUID = -2565431806475335331L;
+
+    private String resourceName;
+    private String id;
+
+    @Override
+    public String getMessage() {
+        return StringUtils.capitalize(resourceName) + " with id " + id + " is not found.";
+    }
+
+}

+ 10 - 0
src/main/java/com/shawn/web/exception/ServerInternalErrorException.java

@@ -0,0 +1,10 @@
+package com.shawn.web.exception;
+
+/**
+ * @author 吴洪双
+ */
+public class ServerInternalErrorException extends RuntimeException {
+
+    private static final long serialVersionUID = -1168987160778410810L;
+
+}

+ 71 - 0
src/main/resources/application.properties

@@ -0,0 +1,71 @@
+### In-memory database ###
+#database=hsqldb
+#spring.datasource.schema=classpath*:db/${database}/schema.sql
+#spring.datasource.data=classpath*:db/${database}/data.sql
+
+### Database for MySQL ###
+#spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot_mybatis
+#spring.datasource.username=root
+#spring.datasource.password=root
+#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+
+### Database for Oracle ###
+jdbc.driverClassName =oracle.jdbc.driver.OracleDriver
+jdbc.url=jdbc:oracle:thin:@10.241.95.150:1521:itos
+jdbc.username=itos1
+jdbc.password=123456
+#jdbc.driverClassName =oracle.jdbc.driver.OracleDriver
+#jdbc.url=jdbc:oracle:thin:@portal.db.crb:1528:portal
+#jdbc.username=portal
+#jdbc.password=portal2017
+### Database for spark hive-jdbc ###
+jdbc2.driverClassName =org.apache.hive.jdbc.HiveDriver
+jdbc2.url=jdbc:hive2://10.241.14.21:10000/default
+jdbc2.username=sdbadmin
+jdbc2.password=sdbadmin
+### Database for postgresql ###
+jdbc3.driverClassName =org.postgresql.Driver
+jdbc3.url=jdbc:postgresql://10.241.14.21:5432/foo
+jdbc3.username=sdbadmin
+jdbc3.password=sdbadmin
+
+
+project.name=TestServer
+### Server ###
+#server.port=808z
+#server.context-path=/${project.name}
+#session最大超时时间(分钟),默认为30
+#server.session-timeout=60
+#该服务绑定ip地址,只有特殊需求才配置
+#server.address=192.168.16.11
+server.port=8081
+
+spring.http.encoding.force=true
+### MyBatis ###
+mybatis.mapper-locations=classpath*:com/shawn/repository/mybatis/*Mapper.xml
+mybatis.type-aliases-package=com.shawn.model
+
+### 格式化 输出的json中的date类型的数据格式 ###
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+
+### Logging ###
+ Log levels (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF)
+logging.level.root=INFO
+logging.level.org.springframework=INFO
+logging.level.org.springframework.web=INFO
+logging.level.org.mybatis=DEBUG
+logging.level.com.shawn=DEBUG
+# File output
+logging.path=/app/applogs/ad/AdServer.log
+logging.config=classpath:logConfig.xml
+
+ad.domain=DC=crbcoa,DC=com
+ad.adAddr=10.219.192.8
+ad.adminName=administrator@crbcoa.com
+ad.adminPwd=Aa123456
+#ad.keystore=C:\\Program Files\\Java\\jdk1.8.0_144\\bin\\security.keystore
+ad.keystore=/app/appsystems/ad/security.keystore
+ad.keystorePwd=123456
+ad.defaultPwd=Ad.123456
+

+ 39 - 0
src/main/resources/code_template_html/add.component.html.vm

@@ -0,0 +1,39 @@
+<p-dialog #dialogp header="新增${head}" [(visible)]="togglePanel" modal="modal" showEffect="fade" [width]="800">
+	<form [formGroup]="addForm" autocomplete="off" style="width:100%">
+	<div class="ui-g-12 form-group ui-fluid">
+#set($row = 1) 
+#foreach(${formField} in ${formFieldList})
+#if(($!{velocityCount} %2)==1)
+		<!-- row${row} -->
+#set($row = $row+1)
+		<div class="ui-g-12 ui-g-nopad">
+			<div class="ui-g-6 ui-g-nopad">
+	        	<div class="ui-g-4 ">
+	                <label for="input" class="input-label">${formField.description}</label>
+	            </div>
+	            <div class="ui-g-8 ">
+#parse("code_template_html/searchType.vm" )	            
+	            </div>
+	         </div>
+#else
+			<div class="ui-g-6 ui-g-nopad">
+	        	<div class="ui-g-4 ">
+	                <label for="input" class="input-label">${formField.description}</label>
+	            </div>
+	            <div class="ui-g-8 ">
+#parse("code_template_html/searchType.vm" )
+	            </div>
+	        </div>
+        </div>
+#end
+#end  
+#if(($!{formFieldList.size()} %2)==1) ##如果为基数,需要补</div>
+		</div>
+#end
+    </div>
+    </form>
+    <p-footer>
+   		<button type="button" pButton icon="fa-check" label="保存" (click)="onAddSubmit()"></button>
+        <button type="button" pButton icon="fa-toggle-on" (click)="togglePanel=false" label="关闭"></button>
+    </p-footer>
+</p-dialog>

+ 0 - 0
src/main/resources/code_template_html/add.component.scss.vm


+ 50 - 0
src/main/resources/code_template_html/add.component.ts.vm

@@ -0,0 +1,50 @@
+import { ${m1}Service } from '${ngPath}service/${m2}-service';
+import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+  selector: 'app-${m2}-add',
+  templateUrl: './${m2}-add.component.html',
+  styleUrls: ['./${m2}-add.component.scss']
+})
+export class ${m1}AddComponent implements OnInit {
+  @Output() refreshGrid = new EventEmitter<boolean>(); // 新增成功刷新列表
+  togglePanel = false;
+  addForm: FormGroup;
+  constructor(private fb: FormBuilder, private ${m2}Service: ${m1}Service) { }
+  
+  ngOnInit() {
+    this.addForm = this.fb.group({
+#foreach(${formField} in ${formFieldList})
+#if($formField.searchType =="multiSelect" or $formField.searchType =="dropdown")
+		${formField.fieldName}:[[], Validators.required], // ${formField.description}
+#else
+		${formField.fieldName}:['', Validators.required], // ${formField.description}
+#end
+#end
+    });
+  }
+  
+#foreach(${formField} in ${formFieldList})
+#if($formField.searchType =="multiSelect")
+  ${formField.fieldName}List = []; // ${formField.description}的数据集合
+#end
+#end
+  
+  toggle(data: any) {
+    this.addForm.reset();
+    this.togglePanel = data.show;
+  }
+  
+  onAddSubmit() {
+    if (!this.addForm.valid) {
+      this.${m2}Service.alertService.error('请检查输入项!');
+      return;
+    }
+    this.${m2}Service.addEntity(this.addForm.value).then(
+      rsp => rsp.code ? [this.refreshGrid.emit(true),
+      this.togglePanel = false,
+      this.${m2}Service.alertService.success('新增成功!')] :
+        this.${m2}Service.alertService.error('新增失败:' + rsp.message));
+  }
+}

+ 42 - 0
src/main/resources/code_template_html/edit.component.html.vm

@@ -0,0 +1,42 @@
+<p-dialog #dialogp header="修改${head}" [(visible)]="togglePanel" modal="modal" showEffect="fade" [width]="800">
+	<form [formGroup]="editForm" autocomplete="off" style="width:100%">
+		<div class="ui-g-12 form-group ui-fluid ui-g-nopad">
+#set($row = 1) 
+#foreach(${formField} in ${formFieldList})
+#if(($!{velocityCount} %2)==1)
+			<!-- row${row} -->
+#set($row = $row+1)
+			<div class="ui-g-12 ui-g-nopad">
+				<div class="ui-g-6 ui-g-nopad">
+		        	<div class="ui-g-4 ">
+		                <label for="input" class="input-label">${formField.description}</label>
+		            </div>
+		            <div class="ui-g-8 ">
+#parse("code_template_html/searchType.vm" )	            
+		            </div>
+		         </div>
+#else
+				<div class="ui-g-6 ui-g-nopad">
+		        	<div class="ui-g-4 ">
+		                <label for="input" class="input-label">${formField.description}</label>
+		            </div>
+		            <div class="ui-g-8 ">
+#parse("code_template_html/searchType.vm" )
+		            </div>
+		        </div>
+	        </div>
+#end
+#end  
+#if(($!{formFieldList.size()} %2)==1) ##如果为基数,需要补</div>
+			</div>
+#end
+			<!-- 实体id名 -->
+			<input type="hidden" value="" formControlName="${primaryKey}" />
+		</div>
+	</form>
+	<p-footer>
+		<button type="button" pButton icon="fa-remove" label="删除" (click)="onDeleteSubmit()"></button>
+		<button type="button" pButton icon="fa-edit" label="修改" (click)="onUpdateSubmit()"></button>
+		<button type="button" pButton icon="fa-toggle-on" (click)="togglePanel=false" label="关闭"></button>
+	</p-footer> 
+</p-dialog>

+ 0 - 0
src/main/resources/code_template_html/edit.component.scss.vm


+ 63 - 0
src/main/resources/code_template_html/edit.component.ts.vm

@@ -0,0 +1,63 @@
+import { ${m1}Service } from '${ngPath}service/${m2}-service';
+import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+  selector: 'app-${m2}-edit',
+  templateUrl: './${m2}-edit.component.html',
+  styleUrls: ['./${m2}-edit.component.scss']
+})
+export class ${m1}EditComponent implements OnInit {
+  editForm: FormGroup;
+  togglePanel = false;
+  @Output() refreshGrid = new EventEmitter<boolean>(); // 新增成功刷新列表
+  
+  constructor(private fb: FormBuilder,private ${m2}Service:${m1}Service) { }
+
+  ngOnInit() {
+    this.editForm = this.fb.group({
+        ${primaryKey}:['',Validators.required], // 主键
+#foreach(${formField} in ${formFieldList})
+#if($formField.searchType =='multiSelect' or $formField.searchType =='dropdown')
+		${formField.fieldName}:[[], Validators.required], // ${formField.description}
+#else
+		${formField.fieldName}:['', Validators.required], // ${formField.description}
+#end
+#end
+    });
+  }
+  
+#foreach(${formField} in ${formFieldList})
+#if($formField.searchType == 'multiSelect')
+  ${formField.fieldName}List = []; // ${formField.description}的数据集合
+#end
+#end
+  
+  
+  toggle(data: any) {
+    this.editForm.reset();
+    this.editForm.patchValue(data);
+    this.togglePanel = data.show;
+  }
+  onDeleteSubmit() {
+    this.${m2}Service.alertService.deleteConfirm(event => {
+      this.${m2}Service.deleteEntity(this.editForm.get('${primaryKey}').value).then(
+        rsp => rsp.code ? [
+        this.refreshGrid.emit(true),
+        this.togglePanel = false,
+        this.${m2}Service.alertService.success('删除成功!')] :
+          this.${m2}Service.alertService.error('删除失败:' + rsp.message))
+    });
+  }
+  onUpdateSubmit() {
+      if (!this.editForm.valid) {
+        this.${m2}Service.alertService.error('请检查输入项!');
+        return;
+      }
+      this.${m2}Service.updateEntity(this.editForm.value).then(
+        rsp => rsp.code ? [this.refreshGrid.emit(true),
+        this.togglePanel = false,
+        this.${m2}Service.alertService.success('更新成功!')] :
+          this.${m2}Service.alertService.error('更新失败:' + rsp.message));
+    }
+}

+ 54 - 0
src/main/resources/code_template_html/grid.component.html.vm

@@ -0,0 +1,54 @@
+<div class="ui-g-12">
+	<form [formGroup]="searchForm" (ngSubmit)="onSubmit_search()" autocomplete="off" style="width:100%">
+	<p-panel header="查询条件" [toggleable]="true">
+	    <div class="ui-g form-group ui-fluid">
+#set($row = 1) 
+#foreach(${formField} in ${searchFieldList})
+#if(($!{velocityCount} %2)==1)
+			<!-- row${row} -->
+#set($row = $row+1)	    
+          	<div class="ui-g-12 ui-g-nopad">
+	         <div class="ui-g-6 ui-g-nopad">
+	         	<div class="ui-g-2 ">
+	                 <label for="input" class="input-label">${formField.description}</label>
+	             </div>
+	             <div class="ui-g-10 ">
+#parse("code_template_html/searchType.vm" )	
+	             </div>
+	         </div>
+#else	         
+	         <div class="ui-g-6 ui-g-nopad">
+	         	<div class="ui-g-2 ">
+	                 <label for="input" class="input-label">${formField.description}</label>
+	             </div>
+	             <div class="ui-g-10 ">
+#parse("code_template_html/searchType.vm" )
+	             </div>
+	         </div>
+	      	</div>
+#end
+#end  
+#if(($!{searchFieldList.size()} %2)==1) ##如果为基数,需要补</div>
+			</div>
+#end	      	
+       	   <div class="ui-g-12 form-center">
+           		<button pButton type="submit" label="查询" icon="fa-search" style="width:auto"></button>
+           </div>
+        </div>
+	</p-panel>
+	</form>
+</div>
+<div class="ui-g-12">
+	<p-dataTable #dataTable [value]="dataList" selectionMode="single" (onPage)="onPage(${var})" [lazy]="true"
+	                [paginator]="true" (onRowSelect)="onRowSelect(${var})" [rows]="tableRows" [responsive]="true" scrollable="true">
+	    <p-header>
+	    	<div class="toolbar-header">
+	    		<button pButton type="button" label="新增${head}" icon="fa-plus" class="purple-btn toolbar-btn" (click)="add()"></button>
+	    		${head}列表
+    		</div>
+   		</p-header>
+#foreach(${tableField} in ${tableFieldList})
+	    <p-column field="${tableField.fieldName}" header="${tableField.description}"></p-column>
+#end   		
+	</p-dataTable>
+</div>

+ 0 - 0
src/main/resources/code_template_html/grid.component.scss.vm


+ 98 - 0
src/main/resources/code_template_html/grid.component.ts.vm

@@ -0,0 +1,98 @@
+import { ${m1}Service } from '${ngPath}service/${m2}-service';
+import { DatePipe } from '@angular/common';
+import { Component, OnInit, Output, EventEmitter, ViewChild, Input } from '@angular/core';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { DataTable } from 'primeng/primeng';
+import { AppUtil } from '../../../../util/app.util';
+
+@Component({
+  selector: 'app-${m2}-grid',
+  templateUrl: './${m2}-grid.component.html',
+  styleUrls: ['./${m2}-grid.component.scss']
+})
+export class ${m1}GridComponent implements OnInit {
+
+  @Output() toggleEdit = new EventEmitter<any>();
+  @Output() toggleAdd = new EventEmitter<any>();
+  @ViewChild( 'dataTable' ) dataTable: DataTable;
+  searchData: any = {};
+  searchForm: FormGroup;
+  dataList = [];
+  tableRows = 10;
+
+  #foreach(${searchField} in ${searchFieldList})
+#if($searchField.searchType =="multiSelect" or $formField.searchType == 'dropdown')
+  ${searchField.fieldName}List = [];//${searchField.description}的数据集合
+#end
+#end
+
+  constructor(private fb: FormBuilder,
+   private ${m2}Service: ${m1}Service,
+   private datePipe:DatePipe) { }
+
+  ngOnInit() {
+    this.searchForm = this.fb.group({
+#foreach(${searchField} in ${searchFieldList})
+#if($searchField.searchType == 'multiSelect')
+		${searchField.fieldName}:[[]], // ${searchField.description}
+#else
+		${searchField.fieldName}:[''], // ${searchField.description}
+#end
+#end
+    });
+    
+    this.onSubmit_search();
+  }
+
+  
+  edit(rowData: any) {
+    rowData['show'] = true;
+    this.toggleEdit.emit(rowData);
+  }
+
+  add() {
+    this.toggleAdd.emit({ show: true });
+  }
+
+  public refresh() {
+      this.searchData['offset'] = 0;
+      this.queryDataList();
+  }
+
+  onRowSelect(event) {
+    event.data['show'] = true;
+    this.edit(event.data);
+  }
+
+  onSubmit_search() {
+      const searchData: any = AppUtil.deleteNullAttr(this.searchForm.value);
+      #foreach(${searchField} in ${searchFieldList})
+          #if($searchField.searchType == 'dateRange')
+              if (searchData.${searchField.fieldName}) {
+                  searchData.${searchField.fieldName}_start = searchData.${searchField.fieldName}.length > 0&&searchData.${searchField.fieldName}[0] ?
+                      this.datePipe.transform(searchData.${searchField.fieldName}[0],DATE_yyyy_MM_dd) + ' 00:00:00' : '';
+                  searchData.${searchField.fieldName}_end = searchData.${searchField.fieldName}.length > 1&&searchData.${searchField.fieldName}[1] ?
+                      this.datePipe.transform(searchData.${searchField.fieldName}[1],DATE_yyyy_MM_dd)+ ' 23:59:59' : '';
+              }
+              delete searchData.${searchField.fieldName};
+          #end
+      #end
+      this.searchData = searchData;
+      this.searchData['offset'] = 0;
+      this.searchData['limit'] = this.tableRows;
+      this.queryDataList();
+  }
+
+  onPage(page) {
+      this.searchData.limit = page.rows;
+      this.searchData.offset = page.first;
+      this.queryDataList();
+  }
+  
+  queryDataList() {
+    this.${m2}Service.queryDataList(this.searchData).then(
+      rsp => rsp.code ? [this.dataTable.totalRecords=rsp.total,this.dataList = rsp.data] : 
+      this.${m2}Service.alertService.error('查询失败:' + rsp.message)
+    );
+  }
+}

+ 5 - 0
src/main/resources/code_template_html/manager.component.html.vm

@@ -0,0 +1,5 @@
+<app-${m2}-grid (toggleEdit)="toggleEdit(${var})" (toggleAdd)="toggleAdd(${var})"></app-${m2}-grid>
+
+<app-${m2}-edit (refreshGrid)="refreshGrid(${var})"></app-${m2}-edit>
+
+<app-${m2}-add (refreshGrid)="refreshGrid(${var})"></app-${m2}-add>

+ 0 - 0
src/main/resources/code_template_html/manager.component.scss.vm


+ 44 - 0
src/main/resources/code_template_html/manager.component.ts.vm

@@ -0,0 +1,44 @@
+import { ${m1}Service } from '../service/${m2}-service';
+import { ${m1}AddComponent } from './${m2}-add/${m2}-add.component';
+import { ${m1}EditComponent } from './${m2}-edit/${m2}-edit.component';
+import { ${m1}GridComponent } from './${m2}-grid/${m2}-grid.component';
+import { Component, OnInit, ViewChild } from '@angular/core';
+
+@Component({
+  selector: 'app-${m2}-manager',
+  templateUrl: './${m2}-manager.component.html',
+  styleUrls: ['./${m2}-manager.component.scss']
+})
+export class ${m1}ManagerComponent implements OnInit {
+  selectSysList = [];
+
+  @ViewChild(${m1}GridComponent) ${m2}Grid: ${m1}GridComponent; // 列表组件
+
+  @ViewChild(${m1}AddComponent) ${m2}Add: ${m1}AddComponent; // 新增dialog
+
+  @ViewChild(${m1}EditComponent) ${m2}Edit: ${m1}EditComponent; // 更新dialog
+  
+  constructor(private ${m2}Service: ${m1}Service) { }
+
+  ngOnInit() {
+  }
+
+ 
+  /**
+     * 打开更新面板
+     * **/
+  toggleEdit(event) {
+    this.${m2}Edit.toggle(event);
+  }
+  /**
+   * 打开新增面板 
+   */
+  toggleAdd(event) {
+    this.${m2}Add.toggle(event);
+  }
+
+  refreshGrid(event) {
+    this.${m2}Grid.refresh();
+  }
+
+}

+ 28 - 0
src/main/resources/code_template_html/searchType.vm

@@ -0,0 +1,28 @@
+#if( $formField.searchType =="input" ) 
+					<input formControlName="${formField.fieldName}" pInputText type="text" />
+#elseif($formField.searchType =="textarea")
+					<textarea formControlName="${formField.fieldName}" [rows]="3" [cols]="30" pInputTextarea placeholder="Your Message" autoResize="autoResize"></textarea>
+#elseif($formField.searchType =="multiSelect")
+					<p-multiSelect formControlName="${formField.fieldName}" [options]="${formField.fieldName}List" ></p-multiSelect>
+#elseif($formField.searchType =="dropdown")
+					<p-dropdown  formControlName="${formField.fieldName}" [options]="${formField.fieldName}List" ></p-dropdown>
+#elseif($formField.searchType =="checkbox")
+#foreach(${data} in ${formField.dataList})
+					<p-checkbox formControlName="${formField.fieldName}" name="${formField.fieldName}" value="${data.value}" label="${data.label}"></p-checkbox>
+#end
+#elseif($formField.searchType =="radioButton")
+#foreach(${data} in ${formField.dataList})
+					<p-radioButton formControlName="${formField.fieldName}" name="${formField.fieldName}" value="${data.value}" label="${data.label}" ></p-radioButton>
+#end
+#elseif($formField.searchType =="inputSwitch")
+					<p-inputSwitch formControlName="${formField.fieldName}"></p-inputSwitch>
+#elseif($formField.searchType =="date")
+					<p-calendar formControlName="${formField.fieldName}" dateFormat="yy/mm/dd" [showIcon]="true"></p-calendar>
+#elseif($formField.searchType =="time")
+					<p-calendar formControlName="${formField.fieldName}" [timeOnly]="true" [showIcon]="true"></p-calendar>
+#elseif($formField.searchType =="dateTime")
+					<p-calendar formControlName="${formField.fieldName}" [showTime]="true" [showIcon]="true"></p-calendar>
+#elseif($formField.searchType =="dateRange")
+					<p-calendar formControlName="${formField.fieldName}" dateFormat="yy/mm/dd" selectionMode="range" readonlyInput="true" [showIcon]="true" placeholder="请选择..."></p-calendar>
+#else
+#end

+ 53 - 0
src/main/resources/code_template_html/service.ts.vm

@@ -0,0 +1,53 @@
+import {BaseService} from '../../commonService/base.service';
+import {AppUtil} from '../../../util/app.util';
+import {Injectable} from '@angular/core';
+import {Constant} from '../../../config/constant/constant';
+import {UrlConstant} from '../../../config/constant/url.constant';
+import { Headers } from '@angular/http';
+
+@Injectable()
+export class ${m1}Service extends BaseService {
+//查询列表
+  queryDataList(queryData) {
+    return this.httpInterceptor
+      .get(UrlConstant.${m3}_LIST + ('?' + AppUtil.stringToUrl(queryData)),
+      { headers: new Headers({ 'type': 'QUERY', 'Content-Type': Constant.CONTENT_TYPE_GET }) })
+      .toPromise()
+      .then(response => response.json())
+      .catch(this.handleError);
+  }
+ // 新增
+  addEntity(add${m1}) {
+    return this.httpInterceptor
+      .post(UrlConstant.${m3}_ADD,
+      add${m1},
+      { headers: new Headers({ 'type': 'INSERT', 'Content-Type': Constant.CONTENT_TYPE_JSON }) })
+      .toPromise()
+      .then(response => (console.log(response.json()), response.json()))
+      .catch(this.handleError);
+  }
+ // 删除
+  deleteEntity(${m2}Id) {
+    return this.httpInterceptor
+      .delete(UrlConstant.${m3}_DELETE +'/'+ ${m2}Id)
+      .toPromise()
+      .then(response => (console.log(response.json()), response.json()))
+      .catch(this.handleError);
+  }
+  // 修改
+  updateEntity(updateData: any): Promise<any> {
+  	  if(!updateData.${primaryKey}){
+  	  	this.alertService.error('primaryKey 为空');
+  	  	return;
+  	  }
+  	  const primaryKey :any = updateData.${primaryKey};
+      const paramsData = Object.assign({},updateData);
+      return this.httpInterceptor
+          .put(UrlConstant.${m3}_UPDATE+'/'+primaryKey,
+          paramsData,
+          { headers: new Headers({ 'type': 'UPDATE', 'Content-Type': Constant.CONTENT_TYPE_JSON }) })
+          .toPromise()
+          .then(response => (console.log(response.json()),response.json()))
+          .catch(this.handleError);
+  }
+}

+ 26 - 0
src/main/resources/code_template_new/Dict.java.vm

@@ -0,0 +1,26 @@
+package ${packageName};
+
+import java.util.Date;
+import org.springframework.format.annotation.DateTimeFormat;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+import com.shawn.web.exception.MyException;
+
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class ${m1} {
+    
+#foreach(${else} in ${elseList})
+	${else}
+#end
+
+}

+ 42 - 0
src/main/resources/code_template_new/DictController.java.vm

@@ -0,0 +1,42 @@
+/**
+ * Date:${today}
+ * author:${author}
+*/
+
+package ${packageName};
+
+import java.util.Date;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.shawn.web.controller.base.BaseController;
+import com.shawn.model.entity.${m1};
+import com.shawn.model.entity.${m1}Example;
+import com.shawn.model.param.${m1}Param;
+import com.shawn.service.interfac.${m1}ServiceInterface;
+
+import lombok.extern.apachecommons.CommonsLog;
+@CommonsLog
+@RestController
+@RequestMapping("${m1}")
+public class ${m1}Controller extends BaseController<${m1},${m1}Example,${m1}Param,${primaryKeyType}>{
+	@Autowired
+	private ${m1}ServiceInterface ${m2}Service;
+	@Autowired
+	public ${m1}Controller(${m1}ServiceInterface service) {
+		super(service);
+	}
+
+	@Override
+	protected ${m1}Example createNewExample() {
+		return new ${m1}Example();
+	}
+	
+    
+}

+ 14 - 0
src/main/resources/code_template_new/DictMapper.java.vm

@@ -0,0 +1,14 @@
+/**
+ * Date:${today}
+ * author:${author}
+*/
+
+package ${packageName};
+
+import com.shawn.model.entity.${m1};
+import com.shawn.model.entity.${m1}Example;
+import com.shawn.model.param.${m1}Param;
+import com.shawn.repository.base.BaseDaoInterface;
+
+public interface ${m1}Mapper extends BaseDaoInterface<${m1},${m1}Example,${m1}Param, ${primaryKeyType}>{
+}

+ 43 - 0
src/main/resources/code_template_new/DictParam.java.vm

@@ -0,0 +1,43 @@
+/**
+ * Date:${today}
+ * author:${author}
+*/
+
+package ${packageName};
+
+import com.shawn.model.entity.${m1};
+import java.util.List;
+import java.util.Date;
+import org.springframework.format.annotation.DateTimeFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+@SuppressWarnings("serial")
+@Accessors(chain = true)
+@NoArgsConstructor
+@Getter
+@Setter
+@ToString
+public class ${m1}Param extends ${m1} {
+    @ApiModelProperty(value = "排序,如:id desc")
+    private String orderByClause;
+    @ApiModelProperty(value = "是否distinct")
+    private boolean distinct;
+    @ApiModelProperty(value = "分页,展示多少条记录")
+    private Integer limit;
+    @ApiModelProperty(value = "分页,从第几条开始,默认从0开始")
+    private Integer offset;
+    @ApiModelProperty(value = "主键id 集合,用于批量删除和批量修改")
+    private List primaryKeyList;
+    private List<${m1}> entityList;//实体集合,用于批量新增
+    
+#foreach(${else} in ${elseList})
+	${else}
+#end
+
+/*==================================以上是自动生成部分字段======================================*/
+	
+}

+ 31 - 0
src/main/resources/code_template_new/DictServiceImpl.java.vm

@@ -0,0 +1,31 @@
+/**
+ * Date:${today}
+ * author:${author}
+*/
+
+package ${packageName};
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.shawn.model.entity.${m1};
+import com.shawn.model.entity.${m1}Example;
+import com.shawn.model.param.${m1}Param;
+import com.shawn.repository.${m1}Mapper;
+import com.shawn.service.base.BaseService;
+import com.shawn.service.interfac.${m1}ServiceInterface;
+@Service
+public class ${m1}ServiceImpl extends BaseService<${m1},${m1}Example,${m1}Param,${primaryKeyType}> implements ${m1}ServiceInterface{
+	@Autowired
+	private ${m1}Mapper ${m2}Mapper;
+	@Autowired
+	public ${m1}ServiceImpl(${m1}Mapper dao) {
+		super(dao);
+	}
+
+	@Override
+	public String getResourceName() {
+		return "${m1}";
+	}
+
+}

+ 14 - 0
src/main/resources/code_template_new/DictServiceInterface.java.vm

@@ -0,0 +1,14 @@
+/**
+ * Date:${today}
+ * author:${author}
+*/
+
+package ${packageName};
+
+import com.shawn.model.entity.${m1};
+import com.shawn.model.entity.${m1}Example;
+import com.shawn.model.param.${m1}Param;
+import com.shawn.service.base.BaseServiceInterface;
+
+public interface ${m1}ServiceInterface extends BaseServiceInterface<${m1},${m1}Example,${m1}Param,${primaryKeyType}>{
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 868 - 0
src/main/resources/code_template_new/api.vm


+ 18 - 0
src/main/resources/db/hsqldb/GET_SN_SEQUENCE.sql

@@ -0,0 +1,18 @@
+CREATE OR REPLACE PROCEDURE GET_SN_SEQUENCE (
+    TABLE_NAME_P IN VARCHAR2,
+    DATE_P IN VARCHAR2,
+    VALUE_P OUT INTEGER )
+IS
+    VALUE_TEMP INTEGER := 0;
+BEGIN
+    LOCK TABLE F_SEQ_INFO IN EXCLUSIVE MODE;
+    SELECT SEQ INTO VALUE_TEMP FROM F_SEQ_INFO WHERE TABLE_NAME = TABLE_NAME_P AND SEQ_DATE = DATE_P;
+    VALUE_P :=  VALUE_TEMP + 1;
+    UPDATE F_SEQ_INFO SET SEQ = VALUE_P  WHERE TABLE_NAME = TABLE_NAME_P AND SEQ_DATE = DATE_P;
+    COMMIT;
+    EXCEPTION
+    WHEN NO_DATA_FOUND THEN
+        VALUE_P := VALUE_TEMP;
+        INSERT INTO F_SEQ_INFO VALUES(TABLE_NAME_P,DATE_P, VALUE_TEMP);
+        COMMIT;
+END GET_SN_SEQUENCE;

+ 84 - 0
src/main/resources/logConfig.xml

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration scan="true">
+    <property name="USER_HOME" value="${LOG_PATH}"/>
+    <property name="DEFAULT_FILE_NAME" value="PortalServer"/>
+    <property name="MaxSize" value="100mb"/> <!-- support kb、mb、gb  -->
+    <property name="QueueSize" value="8196"/>
+    <property name="MaxFlushTime" value="3000"/> <!-- ms -->
+    <property name="print_charset" value="utf-8"/>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{yyyyMMdd HH:mm:ss SSS}[%thread][%level][%c:%L]-%msg%n</pattern>
+            <charset>${print_charset}</charset>
+        </encoder>
+    </appender>
+
+
+    <!--  debug 开发使用   -->
+    <appender name="Channels-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>${USER_HOME}/${DEFAULT_FILE_NAME}-DEBUG.log</File>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${USER_HOME}/logs/Channels-DEBUG-%d{yyyyMMdd}-%i.log</FileNamePattern>
+            <MaxHistory>8</MaxHistory>
+            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <MaxFileSize>${MaxSize}</MaxFileSize>
+            </TimeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <layout>
+            <Pattern>%d{yyyyMMdd HH:mm:ss SSS}[%thread][%level][%X{LINE}]-%msg%n</Pattern>
+        </layout>
+    </appender>
+
+    <!-- =========================================公用配置Start=============================== -->
+    <appender name="DEFAULT-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>${USER_HOME}/${DEFAULT_FILE_NAME}-INFO.log</File>
+       
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${USER_HOME}/logs/${DEFAULT_FILE_NAME}-INFO-%d{yyyyMMdd}-%i.log</FileNamePattern>
+            <MaxHistory>8</MaxHistory>
+            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>${MaxSize}</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <layout>
+            <Pattern>%d{yyyyMMdd HH:mm:ss SSS}[%thread][%level][%X{LINE}]-%msg%n</Pattern>
+        </layout>
+    </appender>
+
+
+    <appender name="DEFAULT-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>${USER_HOME}/${DEFAULT_FILE_NAME}-ERROR.log</File>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${USER_HOME}/logs/${DEFAULT_FILE_NAME}-ERROR-%d{yyyyMMdd}-%i.log</FileNamePattern>
+            <MaxHistory>8</MaxHistory>
+             <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>${MaxSize}</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <layout>
+            <Pattern>%d{yyyyMMdd HH:mm:ss SSS} [%thread][%level][%c:%L]-%msg%n</Pattern>
+        </layout>
+    </appender>
+    <!-- =========================================公用配置End=============================== -->
+
+    <appender name="ASYNC_Channels_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
+        <queueSize>${QueueSize}</queueSize>
+        <!-- 缓冲时间 -->
+        <maxFlushTime>${MaxFlushTime}</maxFlushTime>
+        <appender-ref ref="Channels-DEBUG"/>
+    </appender>
+
+
+    <root level="DEBUG">
+        <appender-ref ref="DEFAULT-INFO"/>
+        <appender-ref ref="DEFAULT-ERROR"/>
+
+        <!--  开发-->
+        <appender-ref ref="STDOUT"/> 
+        <appender-ref ref="ASYNC_Channels_DEBUG"/>
+    </root>
+</configuration>
+