1、spring配置相关
初始化配置文件
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/appContextService.xml,
classpath:spring/applicationContext-operation.xml
</param-value>
</context-param>
appContextService.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-lazy-init="true">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<import resource="classpath:conf/appContextDao.xml" />//①
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<tx:advice transaction-manager="transactionManager" id="txAdvice" >
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- 管理事务操作 -->
<aop:config>
<aop:pointcut id="myPoint"
expression="execution(* com.comName.dhm.nspAdapter.base.AbstractService.execute(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint" />
</aop:config>
<bean id="baseTransactionProxy" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="modify*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="shift*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="upload*">PROPAGATION_REQUIRED</prop>
<prop key="purchase*">PROPAGATION_REQUIRED</prop>
<prop key="cancel*">PROPAGATION_REQUIRED</prop>
<prop key="do*">PROPAGATION_REQUIRED</prop>
<prop key="*Delete">PROPAGATION_REQUIRED</prop>
<prop key="active*">PROPAGATION_REQUIRED</prop>
<prop key="preActive*">PROPAGATION_REQUIRED</prop>
<prop key="sync*">PROPAGATION_REQUIRED</prop>
<prop key="sendMessage*">PROPAGATION_REQUIRED</prop>
<prop key="doExcute">PROPAGATION_REQUIRED</prop>
<prop key="execute">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<import resource="appContextServiceSynchronize.xml" />//②
<!--<import resource="appContextServiceCatalog.xml" />
<import resource="appContextServiceLog.xml" />
<import resource="appContextServicePolicy.xml" />
<import resource="appContextServicePoster.xml" />
<import resource="appContextServiceProductAndGoods.xml" />
<import resource="appContextServiceResourceSpec.xml" />
<import resource="appContextServiceSpec.xml" />
<import resource="appContextServiceSystem.xml" />
<import resource="appContextServiceProvider.xml" />
<import resource="appContextServiceCustomer.xml" />
<import resource="appContextServiceGroup.xml" />
--><!--
<import resource="appContextServiceBms.xml" />
-->
<!-- 参数校验AOP -->
<bean id="serviceParaCheckInterceptor"
class="com.comName.miss.util.intercaptor.ServiceParaCheckInterceptor">
</bean>
<bean id="RegexAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="serviceParaCheckInterceptor" />
</property>
<property name="patterns">
<list>
<value>com.comName.dhm.nspAdapter.*\.execute</value>
</list>
</property>
</bean>
<!--
<bean id="paraCheckAop" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>SyncGoodsServiceImpl</value>
<value>SyncGoodsStatusServiceImpl</value>
<value>SyncAddCloumnImageServiceImpl</value>
<value>SyncDelCloumnImageServiceImpl</value>
<value>SyncColumnRecommendServiceImpl</value>
<value>SyncProgramServiceImpl</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>serviceParaCheckInterceptor</value>
</list>
</property>
</bean>
-->
</beans>
①appContextDao.xml
<?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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below)
<context:property-placeholder location="classpath:jdbc.properties"/> -->
<!-- jdbc 数据源配置 测试用 -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@172.20.100.25:1521:dbcms</value>
</property>
<property name="username">
<value>ipgB050</value>
</property>
<property name="password">
<value>comName</value>
</property>
</bean>
-->
<!-- Main JNDI DataSource for J2EE environments java:itv -->
<jee:jndi-lookup id="dataSource" jndi-name="java:itv" />⑴
<!-- SqlMap setup for iBATIS Database Layer -->
<import resource="appContextDaoLog.xml" />
<import resource="appContextDaoCatalog.xml" />
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:conf/sql-map-config.xml" />⑵
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dialect" class="com.comName.dhm.iepgm.base.dialect.OracleDialect">
<property name="limit" value="true" />
</bean>
<bean id="sqlExecutor" class="com.comName.dhm.iepgm.base.executor.LimitSqlExecutor"
scope="prototype">
<property name="enableLimit" value="true"></property>
</bean>
<bean id="baseDao" abstract="true"
class="com.comName.dhm.iepgm.base.dao.ibatis.IbatisDAO" init-method="initialize">
<property name="sqlMapClient">
<ref bean="sqlMapClient" />
</property>
<property name="sqlExecutor">
<ref bean="sqlExecutor" />
</property>
</bean>
</beans>
⑴oracle-ds.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- JBoss Server Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- $Id: oracle-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ -->
<!-- ==================================================================== -->
<!-- Datasource config for Oracle originally from Steven Coy -->
<!-- ==================================================================== -->
<datasources>
<local-tx-datasource>
<jndi-name>itv</jndi-name>
<connection-url>jdbc:oracle:thin:@172.20.100.25:1521:orcl</connection-url>
<!--
Here are a couple of the possible OCI configurations.
For more information, see http://otn.oracle.com/docs/products/oracle9i/doc_library/release2/java.920/a96654/toc.htm
<connection-url>jdbc:oracle:oci:@youroracle-tns-name</connection-url>
or
<connection-url>jdbc:oracle:oci:@(description=(address=(host=youroraclehost)(protocol=tcp)(port=1521))(connect_data=(SERVICE_NAME=yourservicename)))</connection-url>
Clearly, its better to have TNS set up properly.
-->
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>ipgB050</user-name>
<password>comName</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>40</idle-timeout-minutes>
<prepared-statement-cache-size>200</prepared-statement-cache-size>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>
<!-- Checks the Oracle error codes and messages for fatal errors -->
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
<!-- sql to call on an existing pooled connection when it is obtained from pool - the OracleValidConnectionChecker is prefered
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
-->
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml -->
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
mysql-ds.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: mysql-ds.xml 71535 2008-04-01 07:05:03Z adrian@jboss.org $ -->
<!-- Datasource config for MySQL using 3.0.9 available from:
http://www.mysql.com/downloads/api-jdbc-stable.html
-->
<datasources>
<local-tx-datasource>
<jndi-name>itv</jndi-name>
<connection-url>jdbc:mysql://172.30.60.183:3306/mscp_ipg</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>comName</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>40</idle-timeout-minutes>
<prepared-statement-cache-size>200</prepared-statement-cache-size>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
⑵sql-map-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="com/comName/dhm/core/dao/log/impl/oracle/maps/Log.xml"/>
<sqlMap resource="com/comName/dhm/core/dao/catalog/impl/oracle/maps/Catalog.xml"/>
<sqlMap resource="com/comName/dhm/core/dao/resource/impl/oracle/maps/Category.xml"/>
<sqlMap resource="com/comName/dhm/core/dao/catalog/impl/oracle/maps/CatalogResource.xml"/>
</sqlMapConfig>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="MediaCategory">
<typeAlias alias="PCategory" type="com.comName.dhm.core.dao.resource.po.PCategory"/>
<typeAlias alias="PCategoryMedia" type="com.comName.dhm.core.dao.resource.po.PCategoryMedia"/>
<resultMap id="result" class="PCategory">
<result property="id" column="ID" />
<result property="parentId" column="PARENT_ID" />
<result property="name" column="NAME" />
<result property="ordinal" column="ORDINAL" />
<result property="code" column="CODE" />
<result property="description" column="DESCRIPTION" />
</resultMap>
<resultMap id="categoryMediaResult" class="PCategoryMedia">
<result property="categoryId" column="CATEGORY_ID" />
<result property="resourceId" column="RESOURCE_ID" />
</resultMap>
<!-- Oracle Version~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<insert id="insertCategory_oracle" parameterClass="PCategory">
<selectKey resultClass="Integer" keyProperty="id">
SELECT SEQ_RESOURCE.NEXTVAL AS ID FROM DUAL
</selectKey>
INSERT INTO T_CATEGORY(ID ,PARENT_ID ,NAME ,ORDINAL,CODE,DESCRIPTION)
VALUES(
#id:NUMERIC#,
#parentId:NUMERIC#,
#name:VARCHAR#,
#ordinal:NUMERIC#,
#code:VARCHAR#,
#description:VARCHAR#)
</insert>
<!-- MySql Version~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<insert id="insertCategory_mysql" parameterClass="PCategory">
INSERT INTO T_CATEGORY(PARENT_ID ,NAME ,ORDINAL,CODE,DESCRIPTION)
VALUES(
#parentId:NUMERIC#,
#name:VARCHAR#,
#ordinal:NUMERIC#,
#code:VARCHAR#,
#description:VARCHAR#)
<selectKey resultClass="Integer" keyProperty="id">
SELECT LAST_INSERT_ID() AS ID
</selectKey>
</insert>
<select id="getCategoryById" resultMap="result" parameterClass="java.lang.Integer">
SELECT * FROM T_CATEGORY WHERE ID=#value#
</select>
<select id="getMediaCategory" resultMap="categoryMediaResult" parameterClass="java.util.Map">
SELECT * FROM T_CATEGORY_MEDIA WHERE CATEGORY_ID=#categoryId# AND RESOURCE_ID=#resourceId#
</select>
</sqlMap>
② appContextServiceSynchronize.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- 发送未成功的同步消息任务 -->
<bean id="SynFailedMessageTask" class="com.comName.dhm.core.bss.service.synchronize.job.SynFailedMessageTask">
</bean>
<bean id="SynFailedMessageJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="SynFailedMessageTask" />
</property>
<property name="targetMethod">
<value>doRun</value>
</property>
</bean>
<bean id="SynFailedMessageTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="SynFailedMessageJob"></ref>
</property>
<property name="cronExpression">
<value>10 0/5 * * * ?</value><!--每隔5分钟 -->
</property>
</bean>
<!-- ######## 总调配中心 ########## -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="SynFailedMessageTrigger" />
</list>
</property>
</bean>
</beans>
OracleDialect
package com.comName.dhm.iepgm.base.dialect;
import com.comName.dhm.iepgm.base.dao.IDialect;
/**
*
* oracle实现的方言接口
* 实现了IDialect,对oracle进行了特殊化处理
*
* @author 904008 方鸿
* @version [V200R001, 2009-11-23]
* @see IDialect
* @since [DHM.Core.IEPGM-V200R001]
*/
public class OracleDialect implements IDialect
{
/**
* SQL语句结束的符号
*/
protected static final String SQL_END_DELIMITER = ";";
/**
* 是否支持分页true-是,false-不支持
*/
private boolean limit;
/**
* 返回是否支持分页
* @return true-支持,false-不支持
*/
public boolean isLimit()
{
return limit;
}
/**
* 设置是否支持分页
* @param limit true-支持,false-不支持
*/
public void setLimit(boolean limit)
{
this.limit = limit;
}
/**
* 得到ORACLE的分页SQL语句
* @param sql 待分页的SQL语句
* @param hasOffset 是否有最大页
* @return [类型:String]返回带分页的SQL语句
*/
public String getLimitString(String sql, boolean hasOffset)
{
StringBuffer bufsql = new StringBuffer(
"SELECT * FROM (SELECT r.*, ROWNUM rn FROM (");
bufsql.append(sql);
bufsql.append(") r WHERE ROWNUM <= ? ");
bufsql.append(")");
if (hasOffset)
{
bufsql.append("where rn >=?");
}
return bufsql.toString();
}
/**
* 根据起始记录数和终止记录数得到分页的SQL语句
* @param sql [类型:String]待分页的SQL语句
* @param skipResults [类型:int]分页的起点记录
* @param maxResults [类型:int]分页的终止点记录
* @return [类型:String]具体的分页SQL语句
*/
public String getLimitString(String sql, int skipResults, int maxResults)
{
StringBuffer bufsql = new StringBuffer(
"select * from (select r.*, rownum rn from (");
bufsql.append(sql);
bufsql.append(") r where rownum <= ");
bufsql.append(maxResults);
bufsql.append(") where rn >= ");
bufsql.append(skipResults);
return bufsql.toString();
}
}
public interface IDialect
{
/**
* 返回数据库是否支持分页
* @return boolean [true--支持分页,false--不支持分页]
*/
public boolean isLimit();
/**
* 得到分页语句
* 根据不同数据库返回不同的分页代码
* @param sql sql标准语句
* @param hasOffset 是否有终止参数true-有,false-没有
* @return String [返回组装好的分页SQL语句]
*/
public String getLimitString(String sql, boolean hasOffset);
/**
* 得到具体的分页语句
* 根据传入的参数不同拼装不同的数据库分页语句
* @param sql [类型:String]数据库的原始SQL语句
* @param skipResults [类型:int]起始的记录数
* @param maxResults [类型:int]结束的记录数
* @return String [返回组装好的分页SQL语句]
*/
public String getLimitString(String sql, int skipResults, int maxResults);
}
LimitSqlExecutor
package com.comName.dhm.iepgm.base.executor;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.comName.dhm.iepgm.base.dao.IDialect;
import com.comName.dhm.iepgm.base.dialect.MySQLDialect;
import com.comName.dhm.iepgm.base.dialect.OracleDialect;
import com.ibatis.sqlmap.DBProvider;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
import com.ibatis.sqlmap.engine.scope.StatementScope;
/**
*
* 实现物理分页的SqlExecutor类
* 继承并重写了executeQuery方法,通过改变SQL语句来实现物理分页功能
*
*/
public class LimitSqlExecutor extends SqlExecutor
{
/**
* 类的日志对象
*/
private static final Log logger = LogFactory.getLog(LimitSqlExecutor.class);
private static final IDialect mySQLDialect = new MySQLDialect();
private static final IDialect oracleDialect = new OracleDialect();
/**
* 方言对象
*/
// private IDialect dialect;
/**
* 是否支持分页true-支持,false-不支持
*/
private boolean enableLimit = true;
/**
* 返回实现分页的数据库方言
* @return IDialect [返回数据库的方言]
*/
public IDialect getDialect()
{
if (DBProvider.isMySql())
{
return mySQLDialect;
}
else
{
return oracleDialect;
}
}
/**
* 设置实现分页的数据库方言,通过spring注入
* @param dialect 使用的数据库方言
*/
// public void setDialect(IDialect dialect)
// {
// this.dialect = dialect;
// }
/**
* 数据库是否支持分页
* @return boolean [返回数据库是否支持分页]
*/
public boolean isEnableLimit()
{
return enableLimit;
}
/**
* 设置数据库是否支持分页
* @param enableLimit true-支持分页,false-不支持分页
*/
public void setEnableLimit(boolean enableLimit)
{
this.enableLimit = enableLimit;
}
/**
* 实现物理分页,重写了ibatis父类的方法
* 通过不同的方言获得不同的SQL语言,实现物理分页功能
* @param statementScope 数据库statenent的存放范围
* @param conn 数据库连接
* @param sql 传入的SQL语句
* @param parameters SQL语句中的其他参数
* @param skipResults 起始记录数
* @param maxResults 终止点记录数
* @param callback 回调的接口
* @throws SQLException 数据库异常
* @see com.comName.dhm.iepgm.base.dao.IBaseDAO#deleteByKey(java.io.Serializable)
*/
@Override
public void executeQuery(StatementScope statementScope, Connection conn,
String sql, Object[] parameters, int skipResults, int maxResults,
RowHandlerCallback callback) throws SQLException
{
if ((skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS)
&& supportsLimit())
{
//取得具体的分页SQL
IDialect dialectTmp = getDialect();
sql = dialectTmp.getLimitString(sql, skipResults, maxResults);
if (logger.isDebugEnabled())
{
logger.debug(sql);
}
//设置为不分页
skipResults = NO_SKIPPED_RESULTS;
maxResults = NO_MAXIMUM_RESULTS;
}
//调用父类方法执行SQL语句
super.executeQuery(statementScope,
conn,
sql,
parameters,
skipResults,
maxResults,
callback);
}
/**
* 是否支持分页
* @return boolean [true-支持分页,false-不支持分页]
*/
public boolean supportsLimit()
{
IDialect dialectTmp = getDialect();
//如果分页开关开启方言不为空,则返回方言是否支持分页
if (enableLimit && dialectTmp != null)
{
return dialectTmp.isLimit();
}
return false;
}
}
MySQLDialect
public class MySQLDialect implements IDialect
{
protected static final String SQL_END_DELIMITER = ";";
private boolean limit=true;
/**
*
* @param sql 查询的SQL
* @param hasOffset 是否有分页
* @return String 分页后的SQL语句
*/
public String getLimitString(String sql, boolean hasOffset)
{
return new StringBuilder(sql.length() + 20).append(trim(sql))
.append(hasOffset ? " limit ?,?" : " limit ?")
.append(SQL_END_DELIMITER)
.toString();
}
/**
*
* @param sql 查询参数
* @param offset 分页起始点
* @param limit 分页终止点
* @return String 组装后的SQL
*/
public String getLimitString(String sql, int offset, int limit)
{
sql = trim(sql);
StringBuilder sb = new StringBuilder(sql.length() + 20);
sb.append(sql);
if (offset > 0)
{
sb.append(" limit ")
.append(offset)
.append(',')
.append(limit)
.append(SQL_END_DELIMITER);
}
else
{
sb.append(" limit ").append(limit).append(SQL_END_DELIMITER);
}
return sb.toString();
}
/**
* @return boolean 是否支持分页
*/
public boolean isLimit()
{
return limit;
}
/**
* 去掉SQL语句中的分号(;)
* @param sql SQL语句
* @return String [去掉分号后的SQL语句]
*/
private String trim(String sql)
{
sql = sql.trim();
if (sql.endsWith(SQL_END_DELIMITER))
{
sql = sql.substring(0, sql.length() - 1
- SQL_END_DELIMITER.length());
}
return sql;
}
public void setLimit(boolean limit)
{
this.limit = limit;
}
}
IbatisDAO
package com.comName.dhm.iepgm.base.dao.ibatis;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.comName.dhm.core.dao.CoshipSqlMapClientDaoSupport;
import com.comName.dhm.iepgm.base.dao.IIbatisDAO;
import com.comName.dhm.iepgm.base.executor.LimitSqlExecutor;
import com.comName.dhm.iepgm.common.Constants;
import com.comName.dhm.iepgm.common.util.PageList;
import com.comName.dhm.iepgm.common.util.ReflectUtil;
import com.comName.dhm.iepgm.exception.IEPGMException;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
/**
*
* IIbatisDAO 类的抽象实现,
* 部分实现公共的增删改查功能,子类可以继续扩展该类的方法
*
* @author 904008 方鸿
* @version [V200R001, 2009-11-23]
* @see SqlMapClientDaoSupport
* @since [DHM.Core.IEPGM-V200R001]
*/
public abstract class IbatisDAO<T extends Serializable, PK extends Serializable>
extends CoshipSqlMapClientDaoSupport implements IIbatisDAO<T, PK>
{
/**
* 序列化的ID
*/
private static final long serialVersionUID = 7489415169618169154L;
/**
* ibatis中sqlmap命名空间
*/
private String nameSpace = "";
/**
* 实体类
*/
private Class<T> entityClass;
/**
* SQL语句的操作对象
*/
protected SqlExecutor sqlExecutor;
/**
* 对命名空间进行了赋值,可以通过命名空间执行具体的sqlMap对应的语句
* <默认构造函数>
*/
@SuppressWarnings("unchecked")
public IbatisDAO()
{
this.entityClass = null;
Class c = getClass();
//得到具体的子类类型
Type t = c.getGenericSuperclass();
if (t instanceof ParameterizedType)
{
Type[] p = ((ParameterizedType) t).getActualTypeArguments();
this.entityClass = (Class<T>) p[0];
//得到命名空间,用于向sqlMap传入
nameSpace = entityClass.getSimpleName() + ".";
}
}
/**
* 对SQL语句操作对象进行赋值
* @param sqlExecutor
*/
public void setSqlExecutor(SqlExecutor sqlExecutor)
{
this.sqlExecutor = sqlExecutor;
}
/**
* 对是否支持物理分页进行赋值
* spring注入方法,注入具体的sqlExecutor是否支持物理分页
* @param enableLimit [是否支持物理分页,true-支持,false-不支持]
* @see LimitSqlExecutor#setEnableLimit(boolean)
*/
public void setEnableLimit(boolean enableLimit)
{
if (sqlExecutor instanceof LimitSqlExecutor)
{
((LimitSqlExecutor) sqlExecutor).setEnableLimit(enableLimit);
}
}
/**
* 初始化sqlExcutor类,在spring初始化时会加载该方法
* 因为ibatis本身不支持物理分页,用自己定义的sqlExecutor来替代默认的sqlExecutor
* @exception throws [Exception] [向上层直接抛出]
* @see SqlMapExecutorDelegate
*/
public void initialize() throws Exception
{
if (sqlExecutor != null)
{
SqlMapClientImpl client = (SqlMapClientImpl) getSqlMapClient();
SqlMapExecutorDelegate delgate = client.getDelegate();
//由于SqlMapExecutorDelegate没有setSqlExecutor方法,利用反射强行对sqlExecutor赋值
ReflectUtil.setFieldValue(delgate,
"sqlExecutor",
SqlExecutor.class,
sqlExecutor);
}
}
/**
* 按主键删除实体对象
* @param id 泛型主键ID
* @throws IEPGMException
*/
public void deleteByKey(PK id) throws IEPGMException
{
try
{
getSqlMapClientTemplate().delete(nameSpace + SQLID_DELETE, id);
}
catch (DataAccessException ex)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), ex);
}
}
@SuppressWarnings("unchecked")
/**
* 查找符合条件的所有对象
* @return List,List中存放泛型的实体对象
*/
public List<T> findAll()throws IEPGMException
{
return getSqlMapClientTemplate().queryForList(nameSpace + SQLID_FINDALL);
}
@SuppressWarnings("unchecked")
/**
* 按主键查找实体对象
* @param id 泛型主键
* @return 泛型实体,实现序列化接口的任何类型
* @throws IEPGMException
*/
public T findById(PK id) throws IEPGMException
{
T result = null;
try
{
result = (T) this.getSqlMapClient().queryForObject(nameSpace
+ SQLID_FINDBYID,
id);
}
catch (SQLException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_ACCESS_DATABASE.getLongValue(), e);
}
return result;
}
/**
* 保存实体对象,数据库的insert操作
* @param entity 参数类型:泛型,任何实现序列化的类
* @throws IEPGMException iepg管理系统统一抛出的异常
*/
public void saveEntity(T entity) throws IEPGMException
{
try
{
this.getSqlMapClient().insert(nameSpace + SQLID_INSERT, entity);
}
catch (SQLException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), e);
}
}
/**
* 更新实体对象,数据库的update操作
* @param entity 参数类型:泛型,任何实现序列化的类
* @throws IEPGMException iepg管理系统统一抛出的异常
*/
public void updateEntity(T entity) throws IEPGMException
{
try
{
this.getSqlMapClient().update(nameSpace + SQLID_UPDATE, entity);
}
catch (SQLException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), e);
}
}
/**
* 按实体对象的主键ID批量删除实体
* 空方法,子类需要时自己去实现
* @param list 主键的ID列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchDelete( final List<PK> list)throws IEPGMException
{
}
/**
* 按实体对象的主键ID批量删除实体
* 空方法,子类需要时自己去实现
* @param args 主键的ID列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchDelete(final PK[] args)throws IEPGMException
{
}
/**
* 批量插入实体,数据库insert操作
* 空方法,子类需要使用时自己去实现
* @param list 实体对象列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchInsert(final List<T> list) throws IEPGMException
{
}
/**
* 批量更新实体,数据库update操作
* 空方法,子类需要使用时自己去实现
* @param list 实体对象列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchUpdate(final List<T> list) throws IEPGMException
{
}
@SuppressWarnings("unchecked")
/**
* 按查询条件分页查询记录数
* @param map 查询的参数,封装为map或一个实体对象
* @param currPage 当前的页码
* @param pageSize 每页显示的记录数
* @return List 实体对象的列表
* @throws IEMPMException
*/
public List<T> findByCriteria(Object map, int currPage, int pageSize)
throws IEPGMException
{
//举例:当前页为第2页,每页显示10条,则开始记录数为11,结束记录数为20
//得到记录的开始数
int skipResults = (currPage - 1) * pageSize + 1;
//得到记录的结束数
int maxResults = currPage * pageSize;
Map<String, Object> obj = null;
int totalRows = 0;
// 判断是否map类型,还是普通的JavaBean。普通的JavaBean则转换成Map类型
if (map instanceof Map)
{
obj = (Map) map;
}
else
{
obj = ReflectUtil.getObjectAsMap(map);
}
try
{
totalRows = this.getRowCount(obj);
}
catch (DataAccessException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), e);
}
// 带分页参数的列表
PageList<T> pageList = new PageList<T>(currPage, pageSize, totalRows);
// 支持物理分页页码从1开始
try
{
List queryResult = this.getSqlMapClientTemplate()
.queryForList(nameSpace + SQLID_FINDALL,
obj,
skipResults,
maxResults);
if (queryResult != null)
{
pageList.addAll(queryResult);
}
}
catch (DataAccessException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_ACCESS_DATABASE.getLongValue(), e);
}
return pageList;
}
@SuppressWarnings("unchecked")
/**
* 按查询条件返回所有记录,不带分页
* @param map 查询的参数,封装为map或一个实体对象
* @return List 实体对象的列表
*/
public List<T> findByCriteria(Object map) throws IEPGMException
{
Map<String, Object> obj = null;
// 判断是否map类型,还是普通的JavaBean。普通的JavaBean则转换成Map类型
if (map instanceof Map)
{
obj = (Map) map;
}
else
{
obj = ReflectUtil.getObjectAsMap(map);
}
List<T> resultList = null;
try
{
resultList = getSqlMapClientTemplate().queryForList(nameSpace
+ SQLID_FINDALL,
obj);
}
catch (DataAccessException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_ACCESS_DATABASE.getLongValue(), e);
}
return resultList;
}
/**
* 按查询条件得到该SQL语句的总数量
* @param map 查询条件
* @return Integer 记录总数
* @throws DataAccessException 数据访问异常
*/
public Integer getRowCount(Object map) throws DataAccessException
{
return (Integer) this.getSqlMapClientTemplate()
.queryForObject(nameSpace + SQLID_ROWCOUNT, map);
}
/**
* 得到查询结果集的行数,此参数用于分页
* @return Integer记录集的行数
* @throws IEPGMException
*/
public Integer getRowCount() throws IEPGMException
{
return (Integer) this.getSqlMapClientTemplate()
.queryForObject(nameSpace + SQLID_ROWCOUNT);
}
}
CoshipSqlMapClientDaoSupport
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.comName.common.utils.Log;
import com.comName.dhm.core.dao.page.QueryPageDTO;
/**
* @author Zhong.Zongming
*
*/
public class CoshipSqlMapClientDaoSupport extends SqlMapClientDaoSupport {
private Log log = Log.getLog(CoshipSqlMapClientDaoSupport.class);
/**
* 分页查询,默认查询数据总条数
*
* @param statementName
* 查询语句名称
* @param obj
* 查询参数对象
* @param page
* 分页参数
* @return
*/
@SuppressWarnings("unchecked")
public List queryForList(String statementName, Object obj, QueryPageDTO page) {
return queryForList(statementName, obj, page, true);
}
/**
* 分页查询
*
* @param statementName
* 查询语句名称
* @param obj
* 查询参数对象
* @param page
* 分页参数
* @param queryAllCount
* 是否查询数据总条数,true:是,false:否(当page的allCount属性为0时才查询)
* @return
*/
@SuppressWarnings("unchecked")
public List queryForList(String statementName, Object parameterObject,
QueryPageDTO page, boolean queryAllCount) {
try {
if (page==null)
{
return queryForList(statementName, parameterObject);
}
if (queryAllCount) {
page.setAllCount(0);// 使其每次都去查询数据总条数
}
return getSqlMapClientTemplate().getSqlMapClient().queryForList(
statementName, parameterObject, page);
} catch (SQLException e) {
log.error(e);
throw new DataAccessException();
}
}
/** 以下方法 0506 新增 cxj,为了在访问数据库出现异常的情况下能够向NMS告警* */
public Object insert(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().insert(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public int update(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().update(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public Object queryForObject(String statementName) {
try {
return getSqlMapClientTemplate().queryForObject(statementName);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public Object queryForObject(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().queryForObject(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
@SuppressWarnings("unchecked")
public List queryForList(String statementName) {
try {
return getSqlMapClientTemplate().queryForList(statementName);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
@SuppressWarnings("unchecked")
public List queryForList(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().queryForList(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
@SuppressWarnings("unchecked")
public Map<Object, Object> queryForMap(String statementName,
Object parameterObject, String keyProperty, String valueProperty) {
try {
return getSqlMapClientTemplate().queryForMap(statementName,
parameterObject, keyProperty, valueProperty);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public int delete(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().delete(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
}
QueryPageDTO
import java.io.Serializable;
import com.ibatis.sqlmap.IQueryPage;
/**
* 分页查询对象
*/
public class QueryPageDTO implements IQueryPage , Serializable {
private static final long serialVersionUID = 8347220722610858942L;
// 起始位置
int beginIndex = 1;
// 终止位置
int endIndex = 10;
int allCount = 0;
public int getBeginIndex() {
return beginIndex;
}
public void setBeginIndex(int beginIndex) {
this.beginIndex = beginIndex;
}
public int getEndIndex() {
return endIndex;
}
public void setEndIndex(int endIndex) {
this.endIndex = endIndex;
}
public int getAllCount() {
return allCount;
}
public void setAllCount(int allCount) {
this.allCount = allCount;
}
}
Log
package com.comName.common.utils;
import java.util.Collection;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
/**
*
* @author Zhong.Zongming
*/
public class Log {
private static final String FQCN = Log.class.getName();
private Logger logger = null;
@SuppressWarnings("unchecked")
private Log(Class clazz) {
logger = Logger.getLogger(clazz);
// PropertyConfigurator.configure("log4j.properties");
}
@SuppressWarnings("unchecked")
public static Log getLog(Class clazz) {
return new Log(clazz);
}
public boolean isErrorEnabled() {
return logger.isEnabledFor(Level.ERROR);
}
public boolean isWarnEnabled() {
return logger.isEnabledFor(Level.WARN);
}
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
public void debug(Object message) {
logger.log(FQCN, Level.DEBUG, getMessage(message), null);
}
public void debug(Object message, Throwable th) {
logger.log(FQCN, Level.DEBUG, getMessage(message), th);
}
public void info(Object message) {
logger.log(FQCN, Level.INFO, getMessage(message), null);
}
public void info(Object message, Throwable th) {
logger.log(FQCN, Level.INFO, getMessage(message), th);
}
public void warn(Object message) {
logger.log(FQCN, Level.WARN, getMessage(message), null);
}
public void warn(Object message, Throwable th) {
logger.log(FQCN, Level.WARN, getMessage(message), th);
}
public void error(Object message) {
logger.log(FQCN, Level.ERROR, getMessage(message), null);
}
public void error(Throwable th) {
logger.log(FQCN, Level.ERROR, null, th);
}
public void error(Object message, Throwable th) {
logger.log(FQCN, Level.ERROR, getMessage(message), th);
}
public void fatal(Object message) {
logger.log(FQCN, Level.FATAL, getMessage(message), null);
}
public void fatal(Object message, Throwable th) {
logger.log(FQCN, Level.FATAL, getMessage(message), th);
}
@SuppressWarnings("unchecked")
private String getMessage(Object obj) {
if (obj == null) {
return "null";
}
if (obj instanceof String) {
return (String) obj;
} else if (obj instanceof Collection) {
Collection col = (Collection) obj;
if (!col.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (Object elem : col) {
sb.append(ReflectionToStringBuilder.toString(elem, ToStringStyle.MULTI_LINE_STYLE));
}
return sb.toString();
} else {
return "Collection is Empty";
}
} else {
return ReflectionToStringBuilder.toString(obj, ToStringStyle.MULTI_LINE_STYLE);
}
}
}
IIbatisDAO
package com.comName.dhm.iepgm.base.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.dao.DataAccessException;
import com.comName.dhm.iepgm.exception.IEPGMException;
/**
*
* ibatis的DAO方案
* 针对ibatis的特殊性定义的接口,继承自IBaseDAO
*
*/
public abstract interface IIbatisDAO<T extends Serializable, PK extends Serializable>
extends IBaseDAO<T, PK>, Serializable
{
/**
* IBATIS配置文件中定义文件中对应的sqlid,插入操作
*/
public static final String SQLID_INSERT = "insert";
/**
* IBATIS配置文件中定义文件中对应的sqlid,按主键删除实体操作
*/
public static final String SQLID_DELETE = "deleteByPrimaryKey";
/**
* IBATIS配置文件中定义文件中对应的sqlid,按主键的更新操作
*/
public static final String SQLID_UPDATE = "updateById";
/**
* IBATIS配置文件中定义文件中对应的sqlid,查找所有实体操作
*/
public static final String SQLID_FINDALL = "findAll";
/**
* IBATIS配置文件中定义文件中对应的sqlid,按主键ID查找实体对象
*/
public static final String SQLID_FINDBYID = "findById";
/**
* IBATIS配置文件中定义文件中对应的sqlid,查询记录集数
*/
public static final String SQLID_ROWCOUNT = "rowCount";
/**
* 批量插入实体
* 数据库的insert批量操作,接口方法,由具体实现类实现
* @param list 参数类型:List<T>列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量插入失败时抛出此异常]
*/
public abstract void batchInsert(final List<T> list) throws IEPGMException;
/**
* 批量修改实体
* 数据库的update批量操作,接口方法,由具体实现类实现
* @param list 参数类型:[List<T>]列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量更新失败时抛出此异常]
*/
public abstract void batchUpdate(final List<T> list) throws IEPGMException;
/**
* 批量删除实体
* 数据库的delete批量操作,接口方法,由具体实现类实现
* @param list [参数类型:List<T>]列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量删除失败时抛出此异常]
*/
public abstract void batchDelete(final List<PK> list) throws IEPGMException;
/**
* 批量删除实体
* 数据库的delete批量操作,接口方法,由具体实现类实现
* @param args [参数类型:PK[]列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量删除失败时抛出此异常]
*/
public abstract void batchDelete(final PK[] args) throws IEPGMException;
// public List<Admin> findByCriteria(Object map, PageQuery pageQuey)
// throws IEPGMException;
public List<T> findByCriteria(Object map, int currPage, int pageSize)throws IEPGMException;
/**
* 得到满足条件的记录数
* 根据查询条件得到满足条件的记录数
* @param map 查询参数
* @return Integer [整型包装类]
* @exception throws [DataAccessException] [当操作中发生数据库访问异常抛出]
*/
public Integer getRowCount(Object map) throws DataAccessException;
/**
* 根据查询条件得到数据库中所有满足条件的记录实体
* 此功能不带分页功能
* @param map 查询条件的参数
* @return List<T> [泛型的列表,列表中存放任何实现序列化的实体类]
* @exception throws [IEPGMException] [当ibatis访问数据库出现异常时抛出]
*/
public List<T> findByCriteria(Object map) throws IEPGMException;
}
PageList
package com.comName.dhm.iepgm.common.util;
import java.util.ArrayList;
import java.util.Collection;
public class PageList<E> extends ArrayList<E> {
/**
*
*/
private static final long serialVersionUID = -1232964988129963814L;
private int totalRows = 0;
private int totalPages = 0;
private int pageSize = 10;
private int currentPage = 1;
private boolean hasPrevious = false;
private boolean hasNext = false;
private boolean showPageLine = false;
public boolean isShowPageLine() {
return showPageLine;
}
public void setShowPageLine(boolean showPageLine) {
this.showPageLine = showPageLine;
}
public PageList() {
super();
}
public PageList(Collection<? extends E> c) {
super(c);
}
public PageList(int currentPage, int pageSize, int totalRows) {
super(pageSize);
this.currentPage = currentPage;
this.pageSize = pageSize;
this.totalRows = totalRows;
totalPages = totalRows / pageSize;
int mod = totalRows % pageSize;
if (mod > 0) {
totalPages++;
}
refresh();
}
public void reset() {
this.currentPage = 1;
refresh();
}
public void init(int totalRows) {
this.totalRows = totalRows;
totalPages = ((totalRows + pageSize) - 1) / pageSize;
refresh();
}
public void init(int totalRows, int pageSize) {
this.totalRows = totalRows;
this.pageSize = pageSize;
totalPages = ((totalRows + pageSize) - 1) / pageSize;
refresh();
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
refresh();
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
refresh();
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
refresh();
}
public int getTotalRows() {
return totalRows;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
refresh();
}
public void first() {
currentPage = 1;
this.setHasPrevious(false);
refresh();
}
public void previous() {
currentPage--;
refresh();
}
public void next() {
if (currentPage < totalPages) {
currentPage++;
}
refresh();
}
public void last() {
currentPage = totalPages;
this.setHasNext(false);
refresh();
}
public boolean isHasNext() {
return hasNext;
}
public void setHasNext(boolean hasNext) {
this.hasNext = hasNext;
}
public boolean isHasPrevious() {
return hasPrevious;
}
public void setHasPrevious(boolean hasPrevious) {
this.hasPrevious = hasPrevious;
}
public void refresh() {
if (totalPages <= 1) {
hasPrevious = false;
hasNext = false;
} else if (currentPage == 1) {
hasPrevious = false;
hasNext = true;
} else if (currentPage == totalPages) {
hasPrevious = true;
hasNext = false;
} else {
hasPrevious = true;
hasNext = true;
}
if (currentPage <= 0) {
currentPage = 1;
}
//有下一页,且当每页条数大于10,则显示上面的分页栏
if ( hasNext && pageSize > 10 ) {
this.showPageLine = true;
}
//没有下一页,而且当每页条数小于10,则不显示上面的分页栏
if ( !hasNext && pageSize < 10 ) {
this.showPageLine = false;
}
//没有下一页,而且每页条数大于10,则显示上面的分页栏
if ( !hasNext && pageSize > 10 ) {
this.showPageLine = true;
}
}
}
ReflectUtil
package com.comName.dhm.iepgm.common.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* 反射工具类
*
*/
public class ReflectUtil
{
private static final Log logger = LogFactory.getLog(ReflectUtil.class);
@SuppressWarnings("unchecked")
public static void setFieldValue(Object target, String fname, Class ftype,
Object fvalue)
{
if (target == null
|| fname == null
|| "".equals(fname)
|| (fvalue != null && !ftype.isAssignableFrom(fvalue.getClass())))
{
return;
}
Class clazz = target.getClass();
try
{
Field field = clazz.getDeclaredField(fname);
if (!Modifier.isPublic(field.getModifiers()))
{
field.setAccessible(true);
}
field.set(target, fvalue);
}
catch (Exception me)
{
if (logger.isDebugEnabled())
{
logger.debug(me);
}
}
}
/**
* 通过反射机制克隆一个对象
* @param obj
* @return
* @throws Exception
*/
public static Object copyObject(Object obj) throws Exception
{
Field[] fields = obj.getClass().getDeclaredFields();
Object newObj = obj.getClass().newInstance();
for (int i = 0, j = fields.length; i < j; i++)
{
String propertyName = fields[i].getName();
Object propertyValue = getProperty(obj, propertyName);
setProperty(newObj, propertyName, propertyValue);
}
return newObj;
}
// 反射调用setter方法,进行赋值
@SuppressWarnings("unchecked")
private static Object setProperty(Object bean, String propertyName,
Object value) throws Exception
{
Class clazz = bean.getClass();
try
{
Field field = clazz.getDeclaredField(propertyName);
Method method = clazz.getDeclaredMethod(getSetterName(field.getName()),
new Class[] { field.getType() });
return method.invoke(bean, new Object[] { value });
}
catch (Exception e)
{
throw e;
}
}
// 反射调用getter方法,得到field的值
@SuppressWarnings("unchecked")
private static Object getProperty(Object bean, String propertyName) throws Exception
{
Class clazz = bean.getClass();
try
{
Field field = clazz.getDeclaredField(propertyName);
Method method = clazz.getDeclaredMethod(getGetterName(field.getName()),
new Class[] {});
return method.invoke(bean, new Object[] {});
}
catch (Exception e)
{
throw e;
}
}
// 根据field名,得到getter方法名
private static String getGetterName(String propertyName)
{
String method = "get" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
return method;
}
// 根据field名,得到setter方法名
private static String getSetterName(String propertyName)
{
String method = "set" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
return method;
}
/**
* 普通的JavaBean对象转换成Map数据类型。
* 将普通的JavaBean对象转换成Map数据类型,其中JavaBean声明的变量名作为Map类型的key,
* 该变量的值,作为其Map数据类型相应key的值。
*
* @param obj
* - 普通JavaBean对象
* @return 返回Map数据类类型
*
* @return Map<String,Object> 返回Map数据类型
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> getObjectAsMap(Object obj)
{
Map<String, Object> map = new HashMap<String, Object>();
if (obj == null)
{
return map;
}
Class clazz = obj.getClass();
Method[] methods = clazz.getMethods();
String methodname = "";
for (int i = 0; i < methods.length; i++)
{
methodname = methods[i].getName();
if (methodname.startsWith("get"))
{
try
{
Object value = methods[i].invoke(obj);
if( value != null && (value instanceof String ) ) {
String str = (String) value;
value = str.trim();
}
map.put(getFieldName(methodname), value);
}
catch (IllegalArgumentException e)
{
logger.debug("Convert JavaBean to Map Error!", e);
}
catch (IllegalAccessException e)
{
logger.debug("Convert JavaBean to Map Error!", e);
}
catch (InvocationTargetException e)
{
logger.debug("Convert JavaBean to Map Error!", e);
}
}
}
return map;
}
private static String getFieldName(String str)
{
String firstChar = str.substring(3, 4);
String out = firstChar.toLowerCase() + str.substring(4);
return out;
}
public static void main(String[] args)
{
}
}
IEPGMException
package com.comName.dhm.iepgm.exception;
import org.apache.log4j.Logger;
/**
*
* iEPG管理系统自定义异常
* 当系统发生异常时统一包装抛出
*
* @author 904008 方鸿
* @version [V200R001, 2009-11-25]
* @see Exception
* @since [DHM.Core.IEPGM-V200R001]
*/
public class IEPGMException extends Exception
{
/**
* 序列化ID
*/
private static final long serialVersionUID = 1772426579115321126L;
/**
* 错误编号
*/
private long errorCode;
/**
* <默认构造函数>
*/
public IEPGMException()
{
super();
}
/**
* 传入错误信息构造异常
* @param message 异常提示信息
*/
public IEPGMException(String message)
{
super(message);
}
/**
* 传入异常构造异常
* @param cause 异常
*/
public IEPGMException(Throwable cause)
{
super(cause);
}
/**
* 传入提示信息和异常内容
* @param message 异常提示信息
* @param cause 异常
*/
public IEPGMException(String message, Throwable cause)
{
super(message, cause);
}
/**
* 获得错误编号
* @return long [错误码]
*/
public long getErrorCode()
{
return errorCode;
}
/**
* 传入错误编号构造异常
* @param errorCode 异常错误代码
*/
public IEPGMException(long errorCode)
{
super();
this.errorCode = errorCode;
}
/**
* 传入错误编号和消息信息构造异常
* @param errorCode 异常代码
* @param message 异常提示信息
*/
public IEPGMException(long errorCode, String message)
{
super(message);
this.errorCode = errorCode;
}
/**
* 传入错误编号和异常内容构造异常
* @param errorCode 错误代码
* @param cause 异常
*/
public IEPGMException(long errorCode, Throwable cause)
{
super(cause);
this.errorCode = errorCode;
}
/**
* 传入错误编号,消息信息和异常内容构造异常
* @param errorCode 异常错误代码
* @param message 异常提示信息
* @param cause 异常本身
*/
public IEPGMException(long errorCode, String message, Throwable cause)
{
super(message, cause);
this.errorCode = errorCode;
}
}
初始化配置文件
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/appContextService.xml,
classpath:spring/applicationContext-operation.xml
</param-value>
</context-param>
appContextService.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-lazy-init="true">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<import resource="classpath:conf/appContextDao.xml" />//①
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<tx:advice transaction-manager="transactionManager" id="txAdvice" >
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- 管理事务操作 -->
<aop:config>
<aop:pointcut id="myPoint"
expression="execution(* com.comName.dhm.nspAdapter.base.AbstractService.execute(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint" />
</aop:config>
<bean id="baseTransactionProxy" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="modify*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="shift*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="upload*">PROPAGATION_REQUIRED</prop>
<prop key="purchase*">PROPAGATION_REQUIRED</prop>
<prop key="cancel*">PROPAGATION_REQUIRED</prop>
<prop key="do*">PROPAGATION_REQUIRED</prop>
<prop key="*Delete">PROPAGATION_REQUIRED</prop>
<prop key="active*">PROPAGATION_REQUIRED</prop>
<prop key="preActive*">PROPAGATION_REQUIRED</prop>
<prop key="sync*">PROPAGATION_REQUIRED</prop>
<prop key="sendMessage*">PROPAGATION_REQUIRED</prop>
<prop key="doExcute">PROPAGATION_REQUIRED</prop>
<prop key="execute">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<import resource="appContextServiceSynchronize.xml" />//②
<!--<import resource="appContextServiceCatalog.xml" />
<import resource="appContextServiceLog.xml" />
<import resource="appContextServicePolicy.xml" />
<import resource="appContextServicePoster.xml" />
<import resource="appContextServiceProductAndGoods.xml" />
<import resource="appContextServiceResourceSpec.xml" />
<import resource="appContextServiceSpec.xml" />
<import resource="appContextServiceSystem.xml" />
<import resource="appContextServiceProvider.xml" />
<import resource="appContextServiceCustomer.xml" />
<import resource="appContextServiceGroup.xml" />
--><!--
<import resource="appContextServiceBms.xml" />
-->
<!-- 参数校验AOP -->
<bean id="serviceParaCheckInterceptor"
class="com.comName.miss.util.intercaptor.ServiceParaCheckInterceptor">
</bean>
<bean id="RegexAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="serviceParaCheckInterceptor" />
</property>
<property name="patterns">
<list>
<value>com.comName.dhm.nspAdapter.*\.execute</value>
</list>
</property>
</bean>
<!--
<bean id="paraCheckAop" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>SyncGoodsServiceImpl</value>
<value>SyncGoodsStatusServiceImpl</value>
<value>SyncAddCloumnImageServiceImpl</value>
<value>SyncDelCloumnImageServiceImpl</value>
<value>SyncColumnRecommendServiceImpl</value>
<value>SyncProgramServiceImpl</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>serviceParaCheckInterceptor</value>
</list>
</property>
</bean>
-->
</beans>
①appContextDao.xml
<?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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below)
<context:property-placeholder location="classpath:jdbc.properties"/> -->
<!-- jdbc 数据源配置 测试用 -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@172.20.100.25:1521:dbcms</value>
</property>
<property name="username">
<value>ipgB050</value>
</property>
<property name="password">
<value>comName</value>
</property>
</bean>
-->
<!-- Main JNDI DataSource for J2EE environments java:itv -->
<jee:jndi-lookup id="dataSource" jndi-name="java:itv" />⑴
<!-- SqlMap setup for iBATIS Database Layer -->
<import resource="appContextDaoLog.xml" />
<import resource="appContextDaoCatalog.xml" />
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:conf/sql-map-config.xml" />⑵
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dialect" class="com.comName.dhm.iepgm.base.dialect.OracleDialect">
<property name="limit" value="true" />
</bean>
<bean id="sqlExecutor" class="com.comName.dhm.iepgm.base.executor.LimitSqlExecutor"
scope="prototype">
<property name="enableLimit" value="true"></property>
</bean>
<bean id="baseDao" abstract="true"
class="com.comName.dhm.iepgm.base.dao.ibatis.IbatisDAO" init-method="initialize">
<property name="sqlMapClient">
<ref bean="sqlMapClient" />
</property>
<property name="sqlExecutor">
<ref bean="sqlExecutor" />
</property>
</bean>
</beans>
⑴oracle-ds.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- JBoss Server Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- $Id: oracle-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ -->
<!-- ==================================================================== -->
<!-- Datasource config for Oracle originally from Steven Coy -->
<!-- ==================================================================== -->
<datasources>
<local-tx-datasource>
<jndi-name>itv</jndi-name>
<connection-url>jdbc:oracle:thin:@172.20.100.25:1521:orcl</connection-url>
<!--
Here are a couple of the possible OCI configurations.
For more information, see http://otn.oracle.com/docs/products/oracle9i/doc_library/release2/java.920/a96654/toc.htm
<connection-url>jdbc:oracle:oci:@youroracle-tns-name</connection-url>
or
<connection-url>jdbc:oracle:oci:@(description=(address=(host=youroraclehost)(protocol=tcp)(port=1521))(connect_data=(SERVICE_NAME=yourservicename)))</connection-url>
Clearly, its better to have TNS set up properly.
-->
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>ipgB050</user-name>
<password>comName</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>40</idle-timeout-minutes>
<prepared-statement-cache-size>200</prepared-statement-cache-size>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>
<!-- Checks the Oracle error codes and messages for fatal errors -->
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
<!-- sql to call on an existing pooled connection when it is obtained from pool - the OracleValidConnectionChecker is prefered
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
-->
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml -->
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
mysql-ds.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: mysql-ds.xml 71535 2008-04-01 07:05:03Z adrian@jboss.org $ -->
<!-- Datasource config for MySQL using 3.0.9 available from:
http://www.mysql.com/downloads/api-jdbc-stable.html
-->
<datasources>
<local-tx-datasource>
<jndi-name>itv</jndi-name>
<connection-url>jdbc:mysql://172.30.60.183:3306/mscp_ipg</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>comName</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>40</idle-timeout-minutes>
<prepared-statement-cache-size>200</prepared-statement-cache-size>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
⑵sql-map-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="com/comName/dhm/core/dao/log/impl/oracle/maps/Log.xml"/>
<sqlMap resource="com/comName/dhm/core/dao/catalog/impl/oracle/maps/Catalog.xml"/>
<sqlMap resource="com/comName/dhm/core/dao/resource/impl/oracle/maps/Category.xml"/>
<sqlMap resource="com/comName/dhm/core/dao/catalog/impl/oracle/maps/CatalogResource.xml"/>
</sqlMapConfig>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="MediaCategory">
<typeAlias alias="PCategory" type="com.comName.dhm.core.dao.resource.po.PCategory"/>
<typeAlias alias="PCategoryMedia" type="com.comName.dhm.core.dao.resource.po.PCategoryMedia"/>
<resultMap id="result" class="PCategory">
<result property="id" column="ID" />
<result property="parentId" column="PARENT_ID" />
<result property="name" column="NAME" />
<result property="ordinal" column="ORDINAL" />
<result property="code" column="CODE" />
<result property="description" column="DESCRIPTION" />
</resultMap>
<resultMap id="categoryMediaResult" class="PCategoryMedia">
<result property="categoryId" column="CATEGORY_ID" />
<result property="resourceId" column="RESOURCE_ID" />
</resultMap>
<!-- Oracle Version~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<insert id="insertCategory_oracle" parameterClass="PCategory">
<selectKey resultClass="Integer" keyProperty="id">
SELECT SEQ_RESOURCE.NEXTVAL AS ID FROM DUAL
</selectKey>
INSERT INTO T_CATEGORY(ID ,PARENT_ID ,NAME ,ORDINAL,CODE,DESCRIPTION)
VALUES(
#id:NUMERIC#,
#parentId:NUMERIC#,
#name:VARCHAR#,
#ordinal:NUMERIC#,
#code:VARCHAR#,
#description:VARCHAR#)
</insert>
<!-- MySql Version~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<insert id="insertCategory_mysql" parameterClass="PCategory">
INSERT INTO T_CATEGORY(PARENT_ID ,NAME ,ORDINAL,CODE,DESCRIPTION)
VALUES(
#parentId:NUMERIC#,
#name:VARCHAR#,
#ordinal:NUMERIC#,
#code:VARCHAR#,
#description:VARCHAR#)
<selectKey resultClass="Integer" keyProperty="id">
SELECT LAST_INSERT_ID() AS ID
</selectKey>
</insert>
<select id="getCategoryById" resultMap="result" parameterClass="java.lang.Integer">
SELECT * FROM T_CATEGORY WHERE ID=#value#
</select>
<select id="getMediaCategory" resultMap="categoryMediaResult" parameterClass="java.util.Map">
SELECT * FROM T_CATEGORY_MEDIA WHERE CATEGORY_ID=#categoryId# AND RESOURCE_ID=#resourceId#
</select>
</sqlMap>
② appContextServiceSynchronize.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- 发送未成功的同步消息任务 -->
<bean id="SynFailedMessageTask" class="com.comName.dhm.core.bss.service.synchronize.job.SynFailedMessageTask">
</bean>
<bean id="SynFailedMessageJob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="SynFailedMessageTask" />
</property>
<property name="targetMethod">
<value>doRun</value>
</property>
</bean>
<bean id="SynFailedMessageTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="SynFailedMessageJob"></ref>
</property>
<property name="cronExpression">
<value>10 0/5 * * * ?</value><!--每隔5分钟 -->
</property>
</bean>
<!-- ######## 总调配中心 ########## -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="SynFailedMessageTrigger" />
</list>
</property>
</bean>
</beans>
OracleDialect
package com.comName.dhm.iepgm.base.dialect;
import com.comName.dhm.iepgm.base.dao.IDialect;
/**
*
* oracle实现的方言接口
* 实现了IDialect,对oracle进行了特殊化处理
*
* @author 904008 方鸿
* @version [V200R001, 2009-11-23]
* @see IDialect
* @since [DHM.Core.IEPGM-V200R001]
*/
public class OracleDialect implements IDialect
{
/**
* SQL语句结束的符号
*/
protected static final String SQL_END_DELIMITER = ";";
/**
* 是否支持分页true-是,false-不支持
*/
private boolean limit;
/**
* 返回是否支持分页
* @return true-支持,false-不支持
*/
public boolean isLimit()
{
return limit;
}
/**
* 设置是否支持分页
* @param limit true-支持,false-不支持
*/
public void setLimit(boolean limit)
{
this.limit = limit;
}
/**
* 得到ORACLE的分页SQL语句
* @param sql 待分页的SQL语句
* @param hasOffset 是否有最大页
* @return [类型:String]返回带分页的SQL语句
*/
public String getLimitString(String sql, boolean hasOffset)
{
StringBuffer bufsql = new StringBuffer(
"SELECT * FROM (SELECT r.*, ROWNUM rn FROM (");
bufsql.append(sql);
bufsql.append(") r WHERE ROWNUM <= ? ");
bufsql.append(")");
if (hasOffset)
{
bufsql.append("where rn >=?");
}
return bufsql.toString();
}
/**
* 根据起始记录数和终止记录数得到分页的SQL语句
* @param sql [类型:String]待分页的SQL语句
* @param skipResults [类型:int]分页的起点记录
* @param maxResults [类型:int]分页的终止点记录
* @return [类型:String]具体的分页SQL语句
*/
public String getLimitString(String sql, int skipResults, int maxResults)
{
StringBuffer bufsql = new StringBuffer(
"select * from (select r.*, rownum rn from (");
bufsql.append(sql);
bufsql.append(") r where rownum <= ");
bufsql.append(maxResults);
bufsql.append(") where rn >= ");
bufsql.append(skipResults);
return bufsql.toString();
}
}
public interface IDialect
{
/**
* 返回数据库是否支持分页
* @return boolean [true--支持分页,false--不支持分页]
*/
public boolean isLimit();
/**
* 得到分页语句
* 根据不同数据库返回不同的分页代码
* @param sql sql标准语句
* @param hasOffset 是否有终止参数true-有,false-没有
* @return String [返回组装好的分页SQL语句]
*/
public String getLimitString(String sql, boolean hasOffset);
/**
* 得到具体的分页语句
* 根据传入的参数不同拼装不同的数据库分页语句
* @param sql [类型:String]数据库的原始SQL语句
* @param skipResults [类型:int]起始的记录数
* @param maxResults [类型:int]结束的记录数
* @return String [返回组装好的分页SQL语句]
*/
public String getLimitString(String sql, int skipResults, int maxResults);
}
LimitSqlExecutor
package com.comName.dhm.iepgm.base.executor;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.comName.dhm.iepgm.base.dao.IDialect;
import com.comName.dhm.iepgm.base.dialect.MySQLDialect;
import com.comName.dhm.iepgm.base.dialect.OracleDialect;
import com.ibatis.sqlmap.DBProvider;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
import com.ibatis.sqlmap.engine.scope.StatementScope;
/**
*
* 实现物理分页的SqlExecutor类
* 继承并重写了executeQuery方法,通过改变SQL语句来实现物理分页功能
*
*/
public class LimitSqlExecutor extends SqlExecutor
{
/**
* 类的日志对象
*/
private static final Log logger = LogFactory.getLog(LimitSqlExecutor.class);
private static final IDialect mySQLDialect = new MySQLDialect();
private static final IDialect oracleDialect = new OracleDialect();
/**
* 方言对象
*/
// private IDialect dialect;
/**
* 是否支持分页true-支持,false-不支持
*/
private boolean enableLimit = true;
/**
* 返回实现分页的数据库方言
* @return IDialect [返回数据库的方言]
*/
public IDialect getDialect()
{
if (DBProvider.isMySql())
{
return mySQLDialect;
}
else
{
return oracleDialect;
}
}
/**
* 设置实现分页的数据库方言,通过spring注入
* @param dialect 使用的数据库方言
*/
// public void setDialect(IDialect dialect)
// {
// this.dialect = dialect;
// }
/**
* 数据库是否支持分页
* @return boolean [返回数据库是否支持分页]
*/
public boolean isEnableLimit()
{
return enableLimit;
}
/**
* 设置数据库是否支持分页
* @param enableLimit true-支持分页,false-不支持分页
*/
public void setEnableLimit(boolean enableLimit)
{
this.enableLimit = enableLimit;
}
/**
* 实现物理分页,重写了ibatis父类的方法
* 通过不同的方言获得不同的SQL语言,实现物理分页功能
* @param statementScope 数据库statenent的存放范围
* @param conn 数据库连接
* @param sql 传入的SQL语句
* @param parameters SQL语句中的其他参数
* @param skipResults 起始记录数
* @param maxResults 终止点记录数
* @param callback 回调的接口
* @throws SQLException 数据库异常
* @see com.comName.dhm.iepgm.base.dao.IBaseDAO#deleteByKey(java.io.Serializable)
*/
@Override
public void executeQuery(StatementScope statementScope, Connection conn,
String sql, Object[] parameters, int skipResults, int maxResults,
RowHandlerCallback callback) throws SQLException
{
if ((skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS)
&& supportsLimit())
{
//取得具体的分页SQL
IDialect dialectTmp = getDialect();
sql = dialectTmp.getLimitString(sql, skipResults, maxResults);
if (logger.isDebugEnabled())
{
logger.debug(sql);
}
//设置为不分页
skipResults = NO_SKIPPED_RESULTS;
maxResults = NO_MAXIMUM_RESULTS;
}
//调用父类方法执行SQL语句
super.executeQuery(statementScope,
conn,
sql,
parameters,
skipResults,
maxResults,
callback);
}
/**
* 是否支持分页
* @return boolean [true-支持分页,false-不支持分页]
*/
public boolean supportsLimit()
{
IDialect dialectTmp = getDialect();
//如果分页开关开启方言不为空,则返回方言是否支持分页
if (enableLimit && dialectTmp != null)
{
return dialectTmp.isLimit();
}
return false;
}
}
MySQLDialect
public class MySQLDialect implements IDialect
{
protected static final String SQL_END_DELIMITER = ";";
private boolean limit=true;
/**
*
* @param sql 查询的SQL
* @param hasOffset 是否有分页
* @return String 分页后的SQL语句
*/
public String getLimitString(String sql, boolean hasOffset)
{
return new StringBuilder(sql.length() + 20).append(trim(sql))
.append(hasOffset ? " limit ?,?" : " limit ?")
.append(SQL_END_DELIMITER)
.toString();
}
/**
*
* @param sql 查询参数
* @param offset 分页起始点
* @param limit 分页终止点
* @return String 组装后的SQL
*/
public String getLimitString(String sql, int offset, int limit)
{
sql = trim(sql);
StringBuilder sb = new StringBuilder(sql.length() + 20);
sb.append(sql);
if (offset > 0)
{
sb.append(" limit ")
.append(offset)
.append(',')
.append(limit)
.append(SQL_END_DELIMITER);
}
else
{
sb.append(" limit ").append(limit).append(SQL_END_DELIMITER);
}
return sb.toString();
}
/**
* @return boolean 是否支持分页
*/
public boolean isLimit()
{
return limit;
}
/**
* 去掉SQL语句中的分号(;)
* @param sql SQL语句
* @return String [去掉分号后的SQL语句]
*/
private String trim(String sql)
{
sql = sql.trim();
if (sql.endsWith(SQL_END_DELIMITER))
{
sql = sql.substring(0, sql.length() - 1
- SQL_END_DELIMITER.length());
}
return sql;
}
public void setLimit(boolean limit)
{
this.limit = limit;
}
}
IbatisDAO
package com.comName.dhm.iepgm.base.dao.ibatis;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.comName.dhm.core.dao.CoshipSqlMapClientDaoSupport;
import com.comName.dhm.iepgm.base.dao.IIbatisDAO;
import com.comName.dhm.iepgm.base.executor.LimitSqlExecutor;
import com.comName.dhm.iepgm.common.Constants;
import com.comName.dhm.iepgm.common.util.PageList;
import com.comName.dhm.iepgm.common.util.ReflectUtil;
import com.comName.dhm.iepgm.exception.IEPGMException;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
/**
*
* IIbatisDAO 类的抽象实现,
* 部分实现公共的增删改查功能,子类可以继续扩展该类的方法
*
* @author 904008 方鸿
* @version [V200R001, 2009-11-23]
* @see SqlMapClientDaoSupport
* @since [DHM.Core.IEPGM-V200R001]
*/
public abstract class IbatisDAO<T extends Serializable, PK extends Serializable>
extends CoshipSqlMapClientDaoSupport implements IIbatisDAO<T, PK>
{
/**
* 序列化的ID
*/
private static final long serialVersionUID = 7489415169618169154L;
/**
* ibatis中sqlmap命名空间
*/
private String nameSpace = "";
/**
* 实体类
*/
private Class<T> entityClass;
/**
* SQL语句的操作对象
*/
protected SqlExecutor sqlExecutor;
/**
* 对命名空间进行了赋值,可以通过命名空间执行具体的sqlMap对应的语句
* <默认构造函数>
*/
@SuppressWarnings("unchecked")
public IbatisDAO()
{
this.entityClass = null;
Class c = getClass();
//得到具体的子类类型
Type t = c.getGenericSuperclass();
if (t instanceof ParameterizedType)
{
Type[] p = ((ParameterizedType) t).getActualTypeArguments();
this.entityClass = (Class<T>) p[0];
//得到命名空间,用于向sqlMap传入
nameSpace = entityClass.getSimpleName() + ".";
}
}
/**
* 对SQL语句操作对象进行赋值
* @param sqlExecutor
*/
public void setSqlExecutor(SqlExecutor sqlExecutor)
{
this.sqlExecutor = sqlExecutor;
}
/**
* 对是否支持物理分页进行赋值
* spring注入方法,注入具体的sqlExecutor是否支持物理分页
* @param enableLimit [是否支持物理分页,true-支持,false-不支持]
* @see LimitSqlExecutor#setEnableLimit(boolean)
*/
public void setEnableLimit(boolean enableLimit)
{
if (sqlExecutor instanceof LimitSqlExecutor)
{
((LimitSqlExecutor) sqlExecutor).setEnableLimit(enableLimit);
}
}
/**
* 初始化sqlExcutor类,在spring初始化时会加载该方法
* 因为ibatis本身不支持物理分页,用自己定义的sqlExecutor来替代默认的sqlExecutor
* @exception throws [Exception] [向上层直接抛出]
* @see SqlMapExecutorDelegate
*/
public void initialize() throws Exception
{
if (sqlExecutor != null)
{
SqlMapClientImpl client = (SqlMapClientImpl) getSqlMapClient();
SqlMapExecutorDelegate delgate = client.getDelegate();
//由于SqlMapExecutorDelegate没有setSqlExecutor方法,利用反射强行对sqlExecutor赋值
ReflectUtil.setFieldValue(delgate,
"sqlExecutor",
SqlExecutor.class,
sqlExecutor);
}
}
/**
* 按主键删除实体对象
* @param id 泛型主键ID
* @throws IEPGMException
*/
public void deleteByKey(PK id) throws IEPGMException
{
try
{
getSqlMapClientTemplate().delete(nameSpace + SQLID_DELETE, id);
}
catch (DataAccessException ex)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), ex);
}
}
@SuppressWarnings("unchecked")
/**
* 查找符合条件的所有对象
* @return List,List中存放泛型的实体对象
*/
public List<T> findAll()throws IEPGMException
{
return getSqlMapClientTemplate().queryForList(nameSpace + SQLID_FINDALL);
}
@SuppressWarnings("unchecked")
/**
* 按主键查找实体对象
* @param id 泛型主键
* @return 泛型实体,实现序列化接口的任何类型
* @throws IEPGMException
*/
public T findById(PK id) throws IEPGMException
{
T result = null;
try
{
result = (T) this.getSqlMapClient().queryForObject(nameSpace
+ SQLID_FINDBYID,
id);
}
catch (SQLException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_ACCESS_DATABASE.getLongValue(), e);
}
return result;
}
/**
* 保存实体对象,数据库的insert操作
* @param entity 参数类型:泛型,任何实现序列化的类
* @throws IEPGMException iepg管理系统统一抛出的异常
*/
public void saveEntity(T entity) throws IEPGMException
{
try
{
this.getSqlMapClient().insert(nameSpace + SQLID_INSERT, entity);
}
catch (SQLException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), e);
}
}
/**
* 更新实体对象,数据库的update操作
* @param entity 参数类型:泛型,任何实现序列化的类
* @throws IEPGMException iepg管理系统统一抛出的异常
*/
public void updateEntity(T entity) throws IEPGMException
{
try
{
this.getSqlMapClient().update(nameSpace + SQLID_UPDATE, entity);
}
catch (SQLException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), e);
}
}
/**
* 按实体对象的主键ID批量删除实体
* 空方法,子类需要时自己去实现
* @param list 主键的ID列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchDelete( final List<PK> list)throws IEPGMException
{
}
/**
* 按实体对象的主键ID批量删除实体
* 空方法,子类需要时自己去实现
* @param args 主键的ID列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchDelete(final PK[] args)throws IEPGMException
{
}
/**
* 批量插入实体,数据库insert操作
* 空方法,子类需要使用时自己去实现
* @param list 实体对象列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchInsert(final List<T> list) throws IEPGMException
{
}
/**
* 批量更新实体,数据库update操作
* 空方法,子类需要使用时自己去实现
* @param list 实体对象列表,列表内存放泛型,任何实现序列化接口的类
*/
public void batchUpdate(final List<T> list) throws IEPGMException
{
}
@SuppressWarnings("unchecked")
/**
* 按查询条件分页查询记录数
* @param map 查询的参数,封装为map或一个实体对象
* @param currPage 当前的页码
* @param pageSize 每页显示的记录数
* @return List 实体对象的列表
* @throws IEMPMException
*/
public List<T> findByCriteria(Object map, int currPage, int pageSize)
throws IEPGMException
{
//举例:当前页为第2页,每页显示10条,则开始记录数为11,结束记录数为20
//得到记录的开始数
int skipResults = (currPage - 1) * pageSize + 1;
//得到记录的结束数
int maxResults = currPage * pageSize;
Map<String, Object> obj = null;
int totalRows = 0;
// 判断是否map类型,还是普通的JavaBean。普通的JavaBean则转换成Map类型
if (map instanceof Map)
{
obj = (Map) map;
}
else
{
obj = ReflectUtil.getObjectAsMap(map);
}
try
{
totalRows = this.getRowCount(obj);
}
catch (DataAccessException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_OPERATOR_DATABASE.getLongValue(), e);
}
// 带分页参数的列表
PageList<T> pageList = new PageList<T>(currPage, pageSize, totalRows);
// 支持物理分页页码从1开始
try
{
List queryResult = this.getSqlMapClientTemplate()
.queryForList(nameSpace + SQLID_FINDALL,
obj,
skipResults,
maxResults);
if (queryResult != null)
{
pageList.addAll(queryResult);
}
}
catch (DataAccessException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_ACCESS_DATABASE.getLongValue(), e);
}
return pageList;
}
@SuppressWarnings("unchecked")
/**
* 按查询条件返回所有记录,不带分页
* @param map 查询的参数,封装为map或一个实体对象
* @return List 实体对象的列表
*/
public List<T> findByCriteria(Object map) throws IEPGMException
{
Map<String, Object> obj = null;
// 判断是否map类型,还是普通的JavaBean。普通的JavaBean则转换成Map类型
if (map instanceof Map)
{
obj = (Map) map;
}
else
{
obj = ReflectUtil.getObjectAsMap(map);
}
List<T> resultList = null;
try
{
resultList = getSqlMapClientTemplate().queryForList(nameSpace
+ SQLID_FINDALL,
obj);
}
catch (DataAccessException e)
{
throw new IEPGMException(
Constants.ERROR_CODE_ACCESS_DATABASE.getLongValue(), e);
}
return resultList;
}
/**
* 按查询条件得到该SQL语句的总数量
* @param map 查询条件
* @return Integer 记录总数
* @throws DataAccessException 数据访问异常
*/
public Integer getRowCount(Object map) throws DataAccessException
{
return (Integer) this.getSqlMapClientTemplate()
.queryForObject(nameSpace + SQLID_ROWCOUNT, map);
}
/**
* 得到查询结果集的行数,此参数用于分页
* @return Integer记录集的行数
* @throws IEPGMException
*/
public Integer getRowCount() throws IEPGMException
{
return (Integer) this.getSqlMapClientTemplate()
.queryForObject(nameSpace + SQLID_ROWCOUNT);
}
}
CoshipSqlMapClientDaoSupport
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.comName.common.utils.Log;
import com.comName.dhm.core.dao.page.QueryPageDTO;
/**
* @author Zhong.Zongming
*
*/
public class CoshipSqlMapClientDaoSupport extends SqlMapClientDaoSupport {
private Log log = Log.getLog(CoshipSqlMapClientDaoSupport.class);
/**
* 分页查询,默认查询数据总条数
*
* @param statementName
* 查询语句名称
* @param obj
* 查询参数对象
* @param page
* 分页参数
* @return
*/
@SuppressWarnings("unchecked")
public List queryForList(String statementName, Object obj, QueryPageDTO page) {
return queryForList(statementName, obj, page, true);
}
/**
* 分页查询
*
* @param statementName
* 查询语句名称
* @param obj
* 查询参数对象
* @param page
* 分页参数
* @param queryAllCount
* 是否查询数据总条数,true:是,false:否(当page的allCount属性为0时才查询)
* @return
*/
@SuppressWarnings("unchecked")
public List queryForList(String statementName, Object parameterObject,
QueryPageDTO page, boolean queryAllCount) {
try {
if (page==null)
{
return queryForList(statementName, parameterObject);
}
if (queryAllCount) {
page.setAllCount(0);// 使其每次都去查询数据总条数
}
return getSqlMapClientTemplate().getSqlMapClient().queryForList(
statementName, parameterObject, page);
} catch (SQLException e) {
log.error(e);
throw new DataAccessException();
}
}
/** 以下方法 0506 新增 cxj,为了在访问数据库出现异常的情况下能够向NMS告警* */
public Object insert(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().insert(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public int update(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().update(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public Object queryForObject(String statementName) {
try {
return getSqlMapClientTemplate().queryForObject(statementName);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public Object queryForObject(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().queryForObject(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
@SuppressWarnings("unchecked")
public List queryForList(String statementName) {
try {
return getSqlMapClientTemplate().queryForList(statementName);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
@SuppressWarnings("unchecked")
public List queryForList(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().queryForList(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
@SuppressWarnings("unchecked")
public Map<Object, Object> queryForMap(String statementName,
Object parameterObject, String keyProperty, String valueProperty) {
try {
return getSqlMapClientTemplate().queryForMap(statementName,
parameterObject, keyProperty, valueProperty);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
public int delete(String statementName, Object parameterObject) {
try {
return getSqlMapClientTemplate().delete(statementName,
parameterObject);
} catch (Exception e) {
log.error(e);
throw new DataAccessException();
}
}
}
QueryPageDTO
import java.io.Serializable;
import com.ibatis.sqlmap.IQueryPage;
/**
* 分页查询对象
*/
public class QueryPageDTO implements IQueryPage , Serializable {
private static final long serialVersionUID = 8347220722610858942L;
// 起始位置
int beginIndex = 1;
// 终止位置
int endIndex = 10;
int allCount = 0;
public int getBeginIndex() {
return beginIndex;
}
public void setBeginIndex(int beginIndex) {
this.beginIndex = beginIndex;
}
public int getEndIndex() {
return endIndex;
}
public void setEndIndex(int endIndex) {
this.endIndex = endIndex;
}
public int getAllCount() {
return allCount;
}
public void setAllCount(int allCount) {
this.allCount = allCount;
}
}
Log
package com.comName.common.utils;
import java.util.Collection;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
/**
*
* @author Zhong.Zongming
*/
public class Log {
private static final String FQCN = Log.class.getName();
private Logger logger = null;
@SuppressWarnings("unchecked")
private Log(Class clazz) {
logger = Logger.getLogger(clazz);
// PropertyConfigurator.configure("log4j.properties");
}
@SuppressWarnings("unchecked")
public static Log getLog(Class clazz) {
return new Log(clazz);
}
public boolean isErrorEnabled() {
return logger.isEnabledFor(Level.ERROR);
}
public boolean isWarnEnabled() {
return logger.isEnabledFor(Level.WARN);
}
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
public void debug(Object message) {
logger.log(FQCN, Level.DEBUG, getMessage(message), null);
}
public void debug(Object message, Throwable th) {
logger.log(FQCN, Level.DEBUG, getMessage(message), th);
}
public void info(Object message) {
logger.log(FQCN, Level.INFO, getMessage(message), null);
}
public void info(Object message, Throwable th) {
logger.log(FQCN, Level.INFO, getMessage(message), th);
}
public void warn(Object message) {
logger.log(FQCN, Level.WARN, getMessage(message), null);
}
public void warn(Object message, Throwable th) {
logger.log(FQCN, Level.WARN, getMessage(message), th);
}
public void error(Object message) {
logger.log(FQCN, Level.ERROR, getMessage(message), null);
}
public void error(Throwable th) {
logger.log(FQCN, Level.ERROR, null, th);
}
public void error(Object message, Throwable th) {
logger.log(FQCN, Level.ERROR, getMessage(message), th);
}
public void fatal(Object message) {
logger.log(FQCN, Level.FATAL, getMessage(message), null);
}
public void fatal(Object message, Throwable th) {
logger.log(FQCN, Level.FATAL, getMessage(message), th);
}
@SuppressWarnings("unchecked")
private String getMessage(Object obj) {
if (obj == null) {
return "null";
}
if (obj instanceof String) {
return (String) obj;
} else if (obj instanceof Collection) {
Collection col = (Collection) obj;
if (!col.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (Object elem : col) {
sb.append(ReflectionToStringBuilder.toString(elem, ToStringStyle.MULTI_LINE_STYLE));
}
return sb.toString();
} else {
return "Collection is Empty";
}
} else {
return ReflectionToStringBuilder.toString(obj, ToStringStyle.MULTI_LINE_STYLE);
}
}
}
IIbatisDAO
package com.comName.dhm.iepgm.base.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.dao.DataAccessException;
import com.comName.dhm.iepgm.exception.IEPGMException;
/**
*
* ibatis的DAO方案
* 针对ibatis的特殊性定义的接口,继承自IBaseDAO
*
*/
public abstract interface IIbatisDAO<T extends Serializable, PK extends Serializable>
extends IBaseDAO<T, PK>, Serializable
{
/**
* IBATIS配置文件中定义文件中对应的sqlid,插入操作
*/
public static final String SQLID_INSERT = "insert";
/**
* IBATIS配置文件中定义文件中对应的sqlid,按主键删除实体操作
*/
public static final String SQLID_DELETE = "deleteByPrimaryKey";
/**
* IBATIS配置文件中定义文件中对应的sqlid,按主键的更新操作
*/
public static final String SQLID_UPDATE = "updateById";
/**
* IBATIS配置文件中定义文件中对应的sqlid,查找所有实体操作
*/
public static final String SQLID_FINDALL = "findAll";
/**
* IBATIS配置文件中定义文件中对应的sqlid,按主键ID查找实体对象
*/
public static final String SQLID_FINDBYID = "findById";
/**
* IBATIS配置文件中定义文件中对应的sqlid,查询记录集数
*/
public static final String SQLID_ROWCOUNT = "rowCount";
/**
* 批量插入实体
* 数据库的insert批量操作,接口方法,由具体实现类实现
* @param list 参数类型:List<T>列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量插入失败时抛出此异常]
*/
public abstract void batchInsert(final List<T> list) throws IEPGMException;
/**
* 批量修改实体
* 数据库的update批量操作,接口方法,由具体实现类实现
* @param list 参数类型:[List<T>]列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量更新失败时抛出此异常]
*/
public abstract void batchUpdate(final List<T> list) throws IEPGMException;
/**
* 批量删除实体
* 数据库的delete批量操作,接口方法,由具体实现类实现
* @param list [参数类型:List<T>]列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量删除失败时抛出此异常]
*/
public abstract void batchDelete(final List<PK> list) throws IEPGMException;
/**
* 批量删除实体
* 数据库的delete批量操作,接口方法,由具体实现类实现
* @param args [参数类型:PK[]列表中存放泛型,任何实现序列化的实体类
* @exception throws [IEPGMException] [当批量删除失败时抛出此异常]
*/
public abstract void batchDelete(final PK[] args) throws IEPGMException;
// public List<Admin> findByCriteria(Object map, PageQuery pageQuey)
// throws IEPGMException;
public List<T> findByCriteria(Object map, int currPage, int pageSize)throws IEPGMException;
/**
* 得到满足条件的记录数
* 根据查询条件得到满足条件的记录数
* @param map 查询参数
* @return Integer [整型包装类]
* @exception throws [DataAccessException] [当操作中发生数据库访问异常抛出]
*/
public Integer getRowCount(Object map) throws DataAccessException;
/**
* 根据查询条件得到数据库中所有满足条件的记录实体
* 此功能不带分页功能
* @param map 查询条件的参数
* @return List<T> [泛型的列表,列表中存放任何实现序列化的实体类]
* @exception throws [IEPGMException] [当ibatis访问数据库出现异常时抛出]
*/
public List<T> findByCriteria(Object map) throws IEPGMException;
}
PageList
package com.comName.dhm.iepgm.common.util;
import java.util.ArrayList;
import java.util.Collection;
public class PageList<E> extends ArrayList<E> {
/**
*
*/
private static final long serialVersionUID = -1232964988129963814L;
private int totalRows = 0;
private int totalPages = 0;
private int pageSize = 10;
private int currentPage = 1;
private boolean hasPrevious = false;
private boolean hasNext = false;
private boolean showPageLine = false;
public boolean isShowPageLine() {
return showPageLine;
}
public void setShowPageLine(boolean showPageLine) {
this.showPageLine = showPageLine;
}
public PageList() {
super();
}
public PageList(Collection<? extends E> c) {
super(c);
}
public PageList(int currentPage, int pageSize, int totalRows) {
super(pageSize);
this.currentPage = currentPage;
this.pageSize = pageSize;
this.totalRows = totalRows;
totalPages = totalRows / pageSize;
int mod = totalRows % pageSize;
if (mod > 0) {
totalPages++;
}
refresh();
}
public void reset() {
this.currentPage = 1;
refresh();
}
public void init(int totalRows) {
this.totalRows = totalRows;
totalPages = ((totalRows + pageSize) - 1) / pageSize;
refresh();
}
public void init(int totalRows, int pageSize) {
this.totalRows = totalRows;
this.pageSize = pageSize;
totalPages = ((totalRows + pageSize) - 1) / pageSize;
refresh();
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
refresh();
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
refresh();
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
refresh();
}
public int getTotalRows() {
return totalRows;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
refresh();
}
public void first() {
currentPage = 1;
this.setHasPrevious(false);
refresh();
}
public void previous() {
currentPage--;
refresh();
}
public void next() {
if (currentPage < totalPages) {
currentPage++;
}
refresh();
}
public void last() {
currentPage = totalPages;
this.setHasNext(false);
refresh();
}
public boolean isHasNext() {
return hasNext;
}
public void setHasNext(boolean hasNext) {
this.hasNext = hasNext;
}
public boolean isHasPrevious() {
return hasPrevious;
}
public void setHasPrevious(boolean hasPrevious) {
this.hasPrevious = hasPrevious;
}
public void refresh() {
if (totalPages <= 1) {
hasPrevious = false;
hasNext = false;
} else if (currentPage == 1) {
hasPrevious = false;
hasNext = true;
} else if (currentPage == totalPages) {
hasPrevious = true;
hasNext = false;
} else {
hasPrevious = true;
hasNext = true;
}
if (currentPage <= 0) {
currentPage = 1;
}
//有下一页,且当每页条数大于10,则显示上面的分页栏
if ( hasNext && pageSize > 10 ) {
this.showPageLine = true;
}
//没有下一页,而且当每页条数小于10,则不显示上面的分页栏
if ( !hasNext && pageSize < 10 ) {
this.showPageLine = false;
}
//没有下一页,而且每页条数大于10,则显示上面的分页栏
if ( !hasNext && pageSize > 10 ) {
this.showPageLine = true;
}
}
}
ReflectUtil
package com.comName.dhm.iepgm.common.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* 反射工具类
*
*/
public class ReflectUtil
{
private static final Log logger = LogFactory.getLog(ReflectUtil.class);
@SuppressWarnings("unchecked")
public static void setFieldValue(Object target, String fname, Class ftype,
Object fvalue)
{
if (target == null
|| fname == null
|| "".equals(fname)
|| (fvalue != null && !ftype.isAssignableFrom(fvalue.getClass())))
{
return;
}
Class clazz = target.getClass();
try
{
Field field = clazz.getDeclaredField(fname);
if (!Modifier.isPublic(field.getModifiers()))
{
field.setAccessible(true);
}
field.set(target, fvalue);
}
catch (Exception me)
{
if (logger.isDebugEnabled())
{
logger.debug(me);
}
}
}
/**
* 通过反射机制克隆一个对象
* @param obj
* @return
* @throws Exception
*/
public static Object copyObject(Object obj) throws Exception
{
Field[] fields = obj.getClass().getDeclaredFields();
Object newObj = obj.getClass().newInstance();
for (int i = 0, j = fields.length; i < j; i++)
{
String propertyName = fields[i].getName();
Object propertyValue = getProperty(obj, propertyName);
setProperty(newObj, propertyName, propertyValue);
}
return newObj;
}
// 反射调用setter方法,进行赋值
@SuppressWarnings("unchecked")
private static Object setProperty(Object bean, String propertyName,
Object value) throws Exception
{
Class clazz = bean.getClass();
try
{
Field field = clazz.getDeclaredField(propertyName);
Method method = clazz.getDeclaredMethod(getSetterName(field.getName()),
new Class[] { field.getType() });
return method.invoke(bean, new Object[] { value });
}
catch (Exception e)
{
throw e;
}
}
// 反射调用getter方法,得到field的值
@SuppressWarnings("unchecked")
private static Object getProperty(Object bean, String propertyName) throws Exception
{
Class clazz = bean.getClass();
try
{
Field field = clazz.getDeclaredField(propertyName);
Method method = clazz.getDeclaredMethod(getGetterName(field.getName()),
new Class[] {});
return method.invoke(bean, new Object[] {});
}
catch (Exception e)
{
throw e;
}
}
// 根据field名,得到getter方法名
private static String getGetterName(String propertyName)
{
String method = "get" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
return method;
}
// 根据field名,得到setter方法名
private static String getSetterName(String propertyName)
{
String method = "set" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
return method;
}
/**
* 普通的JavaBean对象转换成Map数据类型。
* 将普通的JavaBean对象转换成Map数据类型,其中JavaBean声明的变量名作为Map类型的key,
* 该变量的值,作为其Map数据类型相应key的值。
*
* @param obj
* - 普通JavaBean对象
* @return 返回Map数据类类型
*
* @return Map<String,Object> 返回Map数据类型
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> getObjectAsMap(Object obj)
{
Map<String, Object> map = new HashMap<String, Object>();
if (obj == null)
{
return map;
}
Class clazz = obj.getClass();
Method[] methods = clazz.getMethods();
String methodname = "";
for (int i = 0; i < methods.length; i++)
{
methodname = methods[i].getName();
if (methodname.startsWith("get"))
{
try
{
Object value = methods[i].invoke(obj);
if( value != null && (value instanceof String ) ) {
String str = (String) value;
value = str.trim();
}
map.put(getFieldName(methodname), value);
}
catch (IllegalArgumentException e)
{
logger.debug("Convert JavaBean to Map Error!", e);
}
catch (IllegalAccessException e)
{
logger.debug("Convert JavaBean to Map Error!", e);
}
catch (InvocationTargetException e)
{
logger.debug("Convert JavaBean to Map Error!", e);
}
}
}
return map;
}
private static String getFieldName(String str)
{
String firstChar = str.substring(3, 4);
String out = firstChar.toLowerCase() + str.substring(4);
return out;
}
public static void main(String[] args)
{
}
}
IEPGMException
package com.comName.dhm.iepgm.exception;
import org.apache.log4j.Logger;
/**
*
* iEPG管理系统自定义异常
* 当系统发生异常时统一包装抛出
*
* @author 904008 方鸿
* @version [V200R001, 2009-11-25]
* @see Exception
* @since [DHM.Core.IEPGM-V200R001]
*/
public class IEPGMException extends Exception
{
/**
* 序列化ID
*/
private static final long serialVersionUID = 1772426579115321126L;
/**
* 错误编号
*/
private long errorCode;
/**
* <默认构造函数>
*/
public IEPGMException()
{
super();
}
/**
* 传入错误信息构造异常
* @param message 异常提示信息
*/
public IEPGMException(String message)
{
super(message);
}
/**
* 传入异常构造异常
* @param cause 异常
*/
public IEPGMException(Throwable cause)
{
super(cause);
}
/**
* 传入提示信息和异常内容
* @param message 异常提示信息
* @param cause 异常
*/
public IEPGMException(String message, Throwable cause)
{
super(message, cause);
}
/**
* 获得错误编号
* @return long [错误码]
*/
public long getErrorCode()
{
return errorCode;
}
/**
* 传入错误编号构造异常
* @param errorCode 异常错误代码
*/
public IEPGMException(long errorCode)
{
super();
this.errorCode = errorCode;
}
/**
* 传入错误编号和消息信息构造异常
* @param errorCode 异常代码
* @param message 异常提示信息
*/
public IEPGMException(long errorCode, String message)
{
super(message);
this.errorCode = errorCode;
}
/**
* 传入错误编号和异常内容构造异常
* @param errorCode 错误代码
* @param cause 异常
*/
public IEPGMException(long errorCode, Throwable cause)
{
super(cause);
this.errorCode = errorCode;
}
/**
* 传入错误编号,消息信息和异常内容构造异常
* @param errorCode 异常错误代码
* @param message 异常提示信息
* @param cause 异常本身
*/
public IEPGMException(long errorCode, String message, Throwable cause)
{
super(message, cause);
this.errorCode = errorCode;
}
}