背景
编写代码生成器的目的是为了进一步减少程序员的重复性“体力劳动”,让程序员有更多的时间去做创造性的工作,提高编码的质量。我在编码和架构过程中层自己开发了一系列代码生成工具,本着开源和分享的目的,会在本期和后期博客中倾情奉献给有需要的朋友,不足指出也请多包含,因为共享源码,你也可以进行修改使用。
实现思路
预先编制模版,包括实体类、数据访问类、业务逻辑类、配置文件,基于已定义的数据库结构进行模版替换生成。
1、Maven工程管理文件模版(pomTemplate.txt)
<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>testweb2</groupId>
<artifactId>testweb2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name />
<description />
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.annotation</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.ejb</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-osgi-bundle</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-junit-plugin</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.annotation</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.ejb</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-osgi-bundle</artifactId>
<version>1.0.1-SP3</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.14</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.3.14</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.3.14</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.14</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-junit-plugin</artifactId>
<version>2.3.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.35</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2、web配置文件(WebTemplate.txt)
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<description>Archimedes</description>
<display-name>Archimedes</display-name>
<!-- 上下文参数START -->
<!-- 配置Spring、Hibernate配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>Archimedes</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.xml</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<!-- apk和ipa发布路径 -->
<context-param>
<param-name>releasePath</param-name>
<param-value>release</param-value>
</context-param>
<!-- 上下文参数END -->
<!-- 监听器START -->
<!-- Log4j监听器配置 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 处理由 JavaBean Introspector功能而引起的缓存泄露监听器,配置在Spring主监听器之前 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- Spring主监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 监听器END -->
<!-- 过滤器 START -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 跨域访问 END -->
<!-- 会话配置 -->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
<!-- 首页配置 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>/login.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index</welcome-file>
</welcome-file-list>
<!-- 错误页配置 -->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
</web-app>
3、log4j日志配置模版(log4jTemplate.txt)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- ========================== 自定义输出格式说明================================ -->
<!-- %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL -->
<!-- #%r 输出自应用启动到输出该log信息耗费的毫秒数 -->
<!-- #%c 输出所属的类目,通常就是所在类的全名 -->
<!-- #%t 输出产生该日志事件的线程名 -->
<!-- #%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” -->
<!-- #%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日
22:10:28,921 -->
<!-- #%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) -->
<!-- ========================================================================== -->
<!-- ========================== 输出方式说明================================ -->
<!-- Log4j提供的appender有以下几种: -->
<!-- org.apache.log4j.ConsoleAppender(控制台), -->
<!-- org.apache.log4j.FileAppender(文件), -->
<!-- org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件), -->
<!-- org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件), -->
<!-- org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方) -->
<!-- ========================================================================== -->
<!-- 输出到日志文件 -->
<appender name="filelog_appender" class="org.apache.log4j.RollingFileAppender">
<!-- 设置File参数:日志输出文件名 -->
<param name="File" value="${Archimedes}logs/mesnac_logs_all.log" />
<!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
<param name="Append" value="true" />
<!-- 设置文件大小 -->
<param name="MaxFileSize" value="1MB" />
<!-- 设置文件备份 -->
<param name="MaxBackupIndex" value="10000" />
<!-- 设置输出文件项目和格式 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p (%c:%L)- %m%n" />
</layout>
</appender>
<!-- 输出到日志文件 每天一个日志 -->
<appender name="filelog_daily" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${Archimedes}logs/mesnac_logs_daily.log" />
<param name="DatePattern" value="'daily.'yyyy-MM-dd'.log'" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[%d{yyyy-MM-dd HH:mm:ss\} %-5p] [%t] (%c:%L) - %m%n" />
</layout>
</appender>
<!-- 输出到控制台中 -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p: %m%n" />
<!-- "%-5p: [%t] [%c{3}.%M(%L)] | %m%n" -->
</layout>
<!-- 限制日志输出级别 -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="ERROR" />
<param name="LevelMin" value="TRACE" />
</filter>
</appender>
<!-- 发邮件(只有ERROR时才会发送) -->
<appender name="mail" class="org.apache.log4j.net.SMTPAppender">
<param name="threshold" value="ERROR" />
<!-- 缓存文件大小,日志达到512k时发送Email -->
<param name="BufferSize" value="512" />
<param name="From" value="[email protected]" />
<param name="SMTPHost" value="smtp.126.com" />
<param name="Subject" value="Archimedes-log4jMessage" />
<param name="To" value="[email protected]" />
<param name="SMTPUsername" value="zhenglibingaccp" />
<param name="SMTPPassword" value="" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p]-[%c] %m%n" />
</layout>
</appender>
<!-- 通过<category></category>的定义可以将各个包中的类日志输出到不同的日志文件中-->
<category name="com.mesnac" additivity="false">
<level value="INFO" />
<appender-ref ref="filelog_daily" />
<appender-ref ref="console" />
<!-- <appender-ref ref="mail" /> -->
</category>
<root>
<level value="INFO" />
<!-- <appender-ref ref="filelog_appender" /> -->
<appender-ref ref="filelog_daily" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
4、spring配置文件模版(springTemplate.txt)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
">
<!-- 引入属性文件 -->
<context:property-placeholder location="classpath:config.properties" />
<context:property-placeholder location="classpath:databaseType.properties" />
<!-- 导入其他spring配置文件 -->
<import resource="spring-database.xml"/>
<import resource="spring-mybatis.xml"/>
<!-- 自动扫描dao和service包(自动注入) -->
<context:component-scan base-package="com.mesnac.sys.dao.impl,com.mesnac.sys.service.impl"/>
<!--quartz任务自动扫描 -->
<!--
<task:annotation-driven/>
<context:annotation-config/>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<context:component-scan base-package="com.mesnac.quartz"/>
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
-->
</beans>
5、spring数据源配置文件模版(spring-databaseTemplate.txt)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
">
<!-- 动态切换数据源 -->
<bean id="dataSource" class="com.mesnac.datasource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="sysDs" value-ref="sysDs" />
<entry key="demoDs" value-ref="demoDs" />
<entry key="glDs" value-ref="glDs" />
</map>
</property>
<property name="defaultTargetDataSource" ref="sysDs" />
</bean>
<!-- 系统库数据源 -->
<bean name="sysDs" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${sys_url}" />
<property name="username" value="${sys_username}" />
<property name="password" value="${sys_password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="0" />
<!-- 连接池最大活跃连接数量 -->
<property name="maxActive" value="50" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="300000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 测试连接,单位为毫秒 -->
<property name="validationQueryTimeout" value="300000" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<!-- 如果用Oracle,则把poolPreparedStatements配置为true,MySQL可以配置为false -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="50" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
</bean>
<!-- 演示数据源 -->
<bean name="demoDs" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${demo_url}" />
<property name="username" value="${demo_username}" />
<property name="password" value="${demo_password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="0" />
<!-- 连接池最大活跃连接数量 -->
<property name="maxActive" value="50" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="300000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 测试连接,单位为毫秒 -->
<property name="validationQueryTimeout" value="300000" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<!-- 如果用Oracle,则把poolPreparedStatements配置为true,MySQL可以配置为false -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="50" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
</bean>
<!-- 贵轮数据源 -->
<bean name="glDs" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${gl_url}" />
<property name="username" value="${gl_username}" />
<property name="password" value="${gl_password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="0" />
<!-- 连接池最大活跃连接数量 -->
<property name="maxActive" value="50" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="300000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 测试连接,单位为毫秒 -->
<property name="validationQueryTimeout" value="300000" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<!-- 如果用Oracle,则把poolPreparedStatements配置为true,MySQL可以配置为false -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="50" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
</bean>
</beans>
6、spring整合mybatis配置文件模版(spring-mybatisTemplate.txt)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
">
<!-- session工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--
<property name="configLocation" value="classpath:mybatis-config.xml" />
-->
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/mesnac/sys/mapper/*.xml"></property>
</bean>
<!-- DAO接口所在的包名,Spring会自动查找其下的类 -->
<!--
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mesnac.sys.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
-->
<!-- 切面配置 -->
<bean id="dataSourceExchange" class="com.mesnac.datasource.DataSourceExchange"/>
</beans>
7、实体类模版(EntityClassTemplate.txt)
package ${EntityPackageName};
${import}
/**
* @author ${author}
*/
public class ${EntityClassName} implements java.io.Serializable{
${fielddefine}
${getterandsetter}
}
8、基础数据访问接口模版(BaseDaoTemplate.txt)
package ${DaoPackageName};
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import ${EntityPackageName}.PageResult;
/**
* 功能说明 :数据访问基础接口
* 修改说明
* @author 郑立兵 [email protected]
* @date ${date}
* @version V1.0
*/
public interface BaseDao<T, Serializable> {
/**
* 功能说明:按主键查询-单值主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param id 主键值
* @return 返回对应的实体对象
*/
public T getByPrimaryKey(Serializable id);
/**
* 功能说明:按主键查询-组合主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 组合主键参数,可以是实体对象,可以是map
* @return 返回对应的实体对象
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public T getByPrimaryKeys(Object param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException;
/**
* 功能说明:参数查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 查询参数,可以是实体对象,可以是map
* @return 返回符合条件的实体集合
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public List<T> getByParam(Object param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException;
/**
* 功能说明:按Mapper文件中的语句ID和参数查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param statementId Mapper文件中的语句ID
* @param param 查询参数
* @return 返回符合条件的实体集合
*/
public List<T> getByStatementParam(String statementId, Map<String, Object> param);
/**
* 功能说明:按参数分页查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param pageResult 带查询参数的分页对象,需在pageResult中传入pageIndex、pageSize、param
* @return 返回带结果数据的分页实体对象,在pageResult中返回totalSize、pageCount、data
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public PageResult<T> getPageByParam(PageResult<T> pageResult) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException;
/**
* 功能说明:条件查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param whereParam 查询条件,需要在map中增加key为where的键值对作为查询条件字符串(不带where关键词)
* @return 返回符合条件的实体集合
*/
public List<T> getByWhere(Map<String, Object> whereParam);
/**
* 功能说明:按条件分页查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param pageResult 带查询条件的分页对象,需在pageResult中传入pageIndex、pageSize、where
* @return 返回带结果数据的分页实体对象,在pageResult中返回totalSize、pageCount、data
*/
public PageResult<T> getPageByWhere(PageResult<T> pageResult);
/**
* 功能说明:查询记录数
* 修改说明:
* @author 郑立兵
* @date ${date}
* @return 返回表中记录总数
*/
public int count();
/**
* 功能说明:按参数查询记录数
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 参数,可以是实体对象,可以是map
* @return 返回符合参数值的记录数
*/
public int countByParam(Map<String, Object> param);
/**
* 功能说明:按条件查询记录数
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param where 条件,条件字符串中不包括where关键词
* @return
*/
public int countByWhere(String where);
/**
* 功能说明:追加记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param entity 实体对象
* @return 返回追加的记录数
*/
public int insert(T entity);
/**
* 功能说明:批量追加记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param list 实体对象集合
* @return 返回追加的记录数
*/
public int insertBatch(List<T> list);
/**
* 功能说明:按主键更新
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param entity 要更新的实体对象
* @return 返回更新的记录数
*/
public int updateByPrimaryKey(T entity);
/**
* 功能说明:批量更新
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param list 要更新的实体对象集合
* @return 返回更新的记录数
*/
public int updateBatch(List<T> list);
/**
* 功能说明:按主键删除-单值主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param id 主键值
* @return 返回删除的记录数
*/
public int deleteByPrimaryKey(Serializable id);
/**
* 功能说明:按主键删除-组合主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 组合主键值,可以是实体对象,也可以是map
* @return 返回删除的记录数
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public int deleteByPrimaryKeys(Object param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException;
/**
* 功能说明:按参数删除记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 参数
* @return 返回删除的记录数
*/
public int deleteByParam(Map<String, Object> param);
/**
* 功能说明:批量删除
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param ids 要删除的主键值集合
* @return 返回删除的记录数
*/
public int deleteBatch(List<Serializable> ids);
/**
* 功能说明:按条件删除记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param where 条件字符串(不包含where关键词)
* @return 返回删除的记录数
*/
public int deleteByWhere(String where);
/**
* 功能说明:清空表中记录,即截断表(truncate)
* 修改说明:
* @author 郑立兵
* @date ${date}
*/
public void clean();
}
9、基础数据访问实现类模版(BaseDaoImplTemplate.txt)
package ${DaoPackageName}.impl;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import ${DaoPackageName}.BaseDao;
import ${EntityPackageName}.PageResult;
import ${UtilPackageName}.GenericsUtils;
/**
* 类功能说明 :数据访问抽象基类,封装基本数据访问
* 修改说明
* @author 郑立兵 [email protected]
* @date ${date}
* @version V1.0
*/
public abstract class BaseDaoImpl<T, Serializable> extends SqlSessionDaoSupport implements BaseDao<T, Serializable>{
private final String _GETBYPRIMARYKEY = ".getByPrimaryKey";
private final String _GETBYPRIMARYKEYS = ".getByPrimaryKeys";
private final String _GETBYPARAM = ".getByParam";
private final String _GETBYWHERE = ".getByWhere";
private final String _COUNT = ".count";
private final String _COUNTBYPARAM = ".countByParam";
private final String _COUNTBYWHERE = ".countByWhere";
private final String _INSERT = ".insert";
private final String _INSERTBATCH = ".insertBatch";
private final String _UPDATEBYPRIMARYKEY = ".updateByPrimaryKey";
private final String _UPDATEBATCH = ".updateBatch";
private final String _DELETEBYPRIMARYKEY = ".deleteByPrimaryKey";
private final String _DELETEBYPRIMARYKEYS = ".deleteByPrimaryKeys";
private final String _DELETEBYPARAM = ".deleteByParam";
private final String _DELETEBATCH = ".deleteBatch";
private final String _DELETEBYWHERE = ".deleteByWhere";
private final String _CLEAN = ".clean";
private String nameSpace = "";
public String getNameSpace() {
return this.nameSpace;
}
/**
* 依赖注入SqlSessionFactory
*/
@Autowired
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
/**
* 构造方法,通过反射解析泛型参数类型
*/
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
Class<T> clazz = GenericsUtils.getSupperClassGenericType(this.getClass());
this.nameSpace = clazz.getName();
this.nameSpace = this.nameSpace.contains("Entity") ? this.nameSpace.replace("Entity", "") : this.nameSpace;
}
/**
* 功能说明:按主键查询-单值主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param id 主键值
* @return 返回对应的实体对象
*/
public T getByPrimaryKey(Serializable id)
{
return this.getSqlSession().selectOne(this.nameSpace + _GETBYPRIMARYKEY, id);
}
/**
* 功能说明:按主键查询-组合主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 组合主键参数,可以是实体对象,可以是map
* @return 返回对应的实体对象
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
@SuppressWarnings("unchecked")
public T getByPrimaryKeys(Object param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Map<String, Object> mapParams = new HashMap<String, Object>();
if (param != null) {
if (param instanceof Map) {
mapParams.putAll((Map<String, Object>)param);
} else {
Map<String, Object> parameterObject = PropertyUtils.describe(param);
mapParams.putAll(parameterObject);
}
}
return this.getSqlSession().selectOne(this.nameSpace + _GETBYPRIMARYKEYS, mapParams);
}
/**
* 功能说明:参数查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 查询参数,可以是实体对象,可以是map
* @return 返回符合条件的实体集合
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
@SuppressWarnings("unchecked")
public List<T> getByParam(Object param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Map<String, Object> mapParams = new HashMap<String, Object>();
if (param != null) {
if (param instanceof Map) {
mapParams.putAll((Map<String, Object>)param);
} else {
Map<String, Object> parameterObject = PropertyUtils.describe(param);
mapParams.putAll(parameterObject);
}
}
return this.getSqlSession().selectList(this.nameSpace + _GETBYPARAM, param);
}
/**
* 功能说明:按Mapper文件中的语句ID和参数查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param statementId Mapper文件中的语句ID
* @param param 查询参数
* @return 返回符合条件的实体集合
*/
public List<T> getByStatementParam(String statementId, Map<String, Object> param) {
return this.getSqlSession().selectList(this.nameSpace + "." + statementId, param);
}
/**
* 功能说明:按参数分页查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param pageResult 带查询参数的分页对象,需在pageResult中传入pageIndex、pageSize、param
* @return 返回带结果数据的分页实体对象,在pageResult中返回totalSize、pageCount、data
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public PageResult<T> getPageByParam(PageResult<T> pageResult) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
pageResult.getParam().put("offset", pageResult.getPageSize() * (pageResult.getPageCurrent() - 1));
pageResult.getParam().put("limit", pageResult.getPageSize());
if (!"".equals(pageResult.getOrderField())) { pageResult.getParam().put("orderColumn", pageResult.getOrderField()); }
pageResult.getParam().put("orderTurn", pageResult.getOrderDirection());
List<T> data = this.getByParam(pageResult.getParam());
pageResult.setList(data);
int totalSize = this.countByParam(pageResult.getParam());
pageResult.setTotal(totalSize);
return pageResult;
}
/**
* 功能说明:条件查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param whereParam 查询条件,需要在map中增加key为where的键值对作为查询条件字符串(不带where关键词)
* @return 返回符合条件的实体集合
*/
public List<T> getByWhere(Map<String, Object> whereParam) {
return this.getSqlSession().selectList(this.nameSpace + _GETBYWHERE, whereParam);
}
/**
* 功能说明:按条件分页查询
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param pageResult 带查询条件的分页对象,需在pageResult中传入pageIndex、pageSize、where
* @return 返回带结果数据的分页实体对象,在pageResult中返回totalSize、pageCount、data
*/
public PageResult<T> getPageByWhere(PageResult<T> pageResult) {
pageResult.getParam().put("where", pageResult.getWhere());
pageResult.getParam().put("offset", pageResult.getPageSize() * (pageResult.getPageCurrent() - 1));
pageResult.getParam().put("limit", pageResult.getPageSize());
if (!"".equals(pageResult.getOrderField())) { pageResult.getParam().put("orderColumn", pageResult.getOrderField()); }
pageResult.getParam().put("orderTurn", pageResult.getOrderDirection());
List<T> data = this.getByWhere(pageResult.getParam());
pageResult.setList(data);
int totalSize = this.countByWhere(pageResult.getWhere());
pageResult.setTotal(totalSize);
return pageResult;
}
/**
* 功能说明:查询记录数
* 修改说明:
* @author 郑立兵
* @date ${date}
* @return 返回表中记录总数
*/
public int count() {
return this.getSqlSession().selectOne(this.nameSpace + _COUNT);
}
/**
* 功能说明:按参数查询记录数
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 参数,可以是实体对象,可以是map
* @return 返回符合参数值的记录数
*/
public int countByParam(Map<String, Object> param) {
return this.getSqlSession().selectOne(this.nameSpace + _COUNTBYPARAM, param);
}
/**
* 功能说明:按条件查询记录数
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param where 条件,条件字符串中不包括where关键词
* @return
*/
public int countByWhere(String where) {
Map<String, Object> param = new HashMap<String, Object>();
if (!"".equals(where)) { param.put("where", where); }
return this.getSqlSession().selectOne(this.nameSpace + _COUNTBYWHERE, param);
}
/**
* 功能说明:追加记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param entity 实体对象
* @return 返回追加的记录数
*/
public int insert(T entity) {
return this.getSqlSession().insert(this.nameSpace + _INSERT, entity);
}
/**
* 功能说明:批量追加记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param list 实体对象集合
* @return 返回追加的记录数
*/
public int insertBatch(List<T> list) {
return this.getSqlSession().insert(this.nameSpace + _INSERTBATCH, list);
}
/**
* 功能说明:按主键更新
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param entity 要更新的实体对象
* @return 返回更新的记录数
*/
public int updateByPrimaryKey(T entity) {
return this.getSqlSession().update(this.nameSpace + _UPDATEBYPRIMARYKEY, entity);
}
/**
* 功能说明:批量更新
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param list 要更新的实体对象集合
* @return 返回更新的记录数
*/
public int updateBatch(List<T> list) {
return this.getSqlSession().update(this.nameSpace + _UPDATEBATCH, list);
}
/**
* 功能说明:按主键删除-单值主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param id 主键值
* @return 返回删除的记录数
*/
public int deleteByPrimaryKey(Serializable id) {
return this.getSqlSession().delete(this.nameSpace + _DELETEBYPRIMARYKEY, id);
}
/**
* 功能说明:按主键删除-组合主键
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 组合主键值,可以是实体对象,也可以是map
* @return 返回删除的记录数
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
@SuppressWarnings("unchecked")
public int deleteByPrimaryKeys(Object param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Map<String, Object> mapParams = new HashMap<String, Object>();
if (param != null) {
if (param instanceof Map) {
mapParams.putAll((Map<String, Object>)param);
} else {
Map<String, Object> parameterObject = PropertyUtils.describe(param);
mapParams.putAll(parameterObject);
}
}
return this.getSqlSession().delete(this.nameSpace + _DELETEBYPRIMARYKEYS, mapParams);
}
/**
* 功能说明:按参数删除记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param param 参数
* @return 返回删除的记录数
*/
public int deleteByParam(Map<String, Object> param) {
return this.getSqlSession().delete(this.nameSpace + _DELETEBYPARAM, param);
}
/**
* 功能说明:批量删除
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param ids 要删除的主键值集合
* @return 返回删除的记录数
*/
public int deleteBatch(List<Serializable> ids) {
return this.getSqlSession().delete(this.nameSpace + _DELETEBATCH, ids);
}
/**
* 功能说明:按条件删除记录
* 修改说明:
* @author 郑立兵
* @date ${date}
* @param where 条件字符串(不包含where关键词)
* @return 返回删除的记录数
*/
public int deleteByWhere(String where) {
Map<String, Object> param = new HashMap<String, Object>();
if (!"".equals(where)) { param.put("where", where); }
return this.getSqlSession().delete(this.nameSpace + _DELETEBYWHERE, param);
}
/**
* 功能说明:清空表中记录,即截断表(truncate)
* 修改说明:
* @author 郑立兵
* @date ${date}
*/
public void clean() {
this.getSqlSession().update(this.nameSpace + _CLEAN);
}
}