项目下载地址:http://pan.baidu.com/s/1o6v0UyI
项目下载地址2:http://download.csdn.net/detail/afgasdg/7019001
这里就简单的粘一下部分重要代码,方便以后查看
一、框架简介
这个demo采用目前最新的技术Spring4+Mybatis3+maven +freemarker+Bootstrap3构建的系统部分底层框架。目前以初具模型,可以直接用在项目上。
系统运行环境:tomcat7+ 、JDK7+、MySql 5.5+
二、系统部分代码
这里只粘贴部分代码,不做过多的解说,如果想了解具体内容请加QQ:864060165 详谈。
1、web.xml
<web-app 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"
version="3.0">
<display-name>SSR Web Application</display-name>
<!-- Enables use of HTTP methods PUT and DELETE,默认参数名: _method -->
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
</filter-mapping>
<!-- 字符编码过滤器 -->
<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>encodingFilter</filter-name>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
</filter-mapping>
<!-- Spring 容器加载 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config.xml</param-value>
</context-param>
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all *.spring requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- 欢迎页面 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2、Spring-config.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- Activates annotation-based bean configuration -->
<context:annotation-config />
<!-- Scans for application @Components to deploy -->
<context:component-scan base-package="com.viathink" />
<!-- 数据库配置文件位置 -->
<context:property-placeholder location="classpath:/jdbc.properties" />
<!-- 配置dbcp数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="minIdle" value="${jdbc.minIdle}" /> <!-- 队列中的最小等待数 -->
<property name="maxIdle" value="${jdbc.maxIdle}" /> <!-- 队列中的最大等待数 -->
<property name="maxWait" value="${jdbc.maxWait}" /> <!-- 最长等待时间,单位毫秒 -->
<property name="maxActive" value="${jdbc.maxActive}" /> <!-- 最大活跃数 -->
<property name="initialSize" value="${jdbc.initialSize}" /><!--
初始大小 -->
</bean>
<!-- 使用JDBC事物 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- AOP配置事物 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="query*" read-only="true" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 配置AOP切面 -->
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.viathink..service.*.*(..))"/>
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice"/>
</aop:config>
<!-- 使用annotation注解方式配置事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
<property name="mapperLocations" value="classpath:mapper/mysql/**/*Mapper.xml"></property>
</bean>
<!-- 配置SQLSession模板 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
3、Spring-mvc.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- XML转码器 -->
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<!-- 配置freeMarker的模板路径 -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="configLocation" value="classpath:freemarker.properties" />
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
</map>
</property>
</bean>
<!-- 配置freeMarker视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
<property name="contentType" value="text/html; charset=utf-8" />
<property name="cache" value="true" />
<property name="suffix" value=".ftl" />
<property name="order" value="1" />
<property name="requestContextAttribute" value="request" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
</bean>
<!-- jsp视图解析器 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>
<!-- 扫描控制器类 -->
<context:component-scan base-package="com.viathink/**/web/controller/**" />
<!-- 配置静态资源 -->
<mvc:resources location="/resources/" mapping="/resources/**" />
<!-- 采用注解方式配置MVC -->
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:argument-resolvers>
<bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="favorParameter" value="true" />
<property name="defaultContentType" value="text/html"/>
<property name="mediaTypes" >
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>
</beans>
4、sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
<setting name="defaultStatementTimeout" value="25000" />
</settings>
</configuration>
5、ecache配置
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<!-- Sets the path to the directory where cache .data files are created.
If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<!--
name:Cache的唯一标识
maxElementsInMemory:内存中最大缓存对象数
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
eternal:Element是否永久有效,一但设置了,timeout将不起作用
overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)
-->
</ehcache>
6、数据库映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.viathink.sys.domain.SysDictionary">
<cache type="org.mybatis.caches.ehcache.LoggingEhcache" readOnly="true"/>
<resultMap id="BaseResultMap" type="com.viathink.sys.domain.vo.SysDictionaryVo">
<id column="dic_id" property="dicId" jdbcType="VARCHAR" />
<result column="dic_name" property="dicName" jdbcType="VARCHAR" />
<result column="dic_value" property="dicValue" jdbcType="VARCHAR" />
<result column="dic_group" property="dicGroup" jdbcType="VARCHAR" />
<result column="dic_type" property="dicType" jdbcType="VARCHAR" />
<result column="dic_order" property="dicOrder" jdbcType="INTEGER" />
<result column="dic_status" property="dicStatus" jdbcType="VARCHAR" />
<result column="dic_parent_id" property="dicParentId" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List">
dic_id as dicId,
dic_name as dicName,
dic_value as dicValue,
dic_group as dicGroup,
dic_type as dicType,
dic_order as dicOrder,
dic_status as dicStatus,
dic_parent_id as dicParentId
</sql>
<sql id="Base_Where_Clause">
<where>
<trim prefixOverrides="and">
<if test="dicId != null"> and dic_id = #{dicId}</if>
<if test="dicName != null">and dic_name = #{dicName}</if>
<if test="dicValue != null">and dic_value = #{dicValue}</if>
<if test="dicGroup != null">and dic_group = #{dicGroup}</if>
<if test="dicType != null">and dic_type = #{dicType}</if>
<if test="dicOrder != null">and dic_order = #{dicOrder}</if>
<if test="dicStatus != null">and dic_status = #{dicStatus}</if>
<if test="dicParentId != null">and dic_parent_id = #{dicParentId}</if>
<!-- 模糊查询 -->
<if test="dicNameLike != null">and dic_name like CONCAT("%",#{dicNameLike},"%")</if>
<if test="dicGroupLike != null">and dic_group like CONCAT("%",#{dicGroupLike},"%")</if>
</trim>
</where>
<if test="sorting != null">order by ${sorting}</if>
<if test="offset != null and limit != null">
limit #{offset}, #{limit}
</if>
</sql>
<!-- 查询总数 -->
<select id="selectCount" resultType="java.lang.Long" parameterType="java.util.Map">
select count(dic_id)
from sys_dictionary
<include refid="Base_Where_Clause" />
</select>
<!-- 查询 -->
<select id="select" resultMap="BaseResultMap" parameterType="java.util.Map">
select
<include refid="Base_Column_List" />
from sys_dictionary
<include refid="Base_Where_Clause" />
</select>
<!-- 根据ID查询 -->
<select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.String">
select
<include refid="Base_Column_List" />
from sys_dictionary
where dic_id = #{dicId}
</select>
<!-- 根据ID删除 -->
<delete id="deleteById" parameterType="java.lang.String">
delete from sys_dictionary
where dic_id = #{dicId}
</delete>
<!-- 删除 -->
<delete id="delete" parameterType="java.util.Map">
delete from sys_dictionary
<include refid="Base_Where_Clause" />
</delete>
<!-- 添加 -->
<insert id="insert" parameterType="com.viathink.sys.domain.SysDictionary">
insert into sys_dictionary(
dic_id,
dic_name,
dic_value,
dic_group,
dic_type,
dic_order,
dic_status,
dic_parent_id
)
values (
#{dicId},
#{dicName},
#{dicValue},
#{dicGroup},
#{dicType},
#{dicOrder},
#{dicStatus},
#{dicParentId}
)
</insert>
<!-- 通过ID更新 -->
<update id="updateByIdSelective" parameterType="com.viathink.sys.domain.SysDictionary">
update sys_dictionary
<set>
<if test="dicName != null">dic_name = #{dicName},</if>
<if test="dicValue != null">dic_value = #{dicValue},</if>
<if test="dicGroup != null">dic_group = #{dicGroup},</if>
<if test="dicType != null">dic_type = #{dicType},</if>
<if test="dicOrder != null">dic_order = #{dicOrder},</if>
<if test="dicStatus != null">dic_status = #{dicStatus},</if>
<if test="dicParentId != null">dic_parent_id = #{dicParentId},</if>
</set>
where dic_id = #{dicId}
</update>
<update id="updateById" parameterType="com.viathink.sys.domain.SysDictionary">
update sys_dictionary
set dic_name = #{dicName},
dic_value = #{dicValue},
dic_group = #{dicGroup},
dic_type = #{dicType},
dic_order = #{dicOrder},
dic_status = #{dicStatus},
dic_parent_id = #{dicParentId}
where dic_id = #{dicId}
</update>
</mapper>
7、Mybatis通用BaseDao实现
package com.viathink.frame.core.dao.impl;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import com.viathink.frame.core.dao.BaseDao;
import com.viathink.frame.core.dao.constants.SqlId;
import com.viathink.frame.core.dao.domain.Identifiable;
import com.viathink.frame.core.exception.DaoException;
import com.viathink.frame.core.utils.BeanUtils;
import com.viathink.frame.core.utils.UUIDUtils;
/**
* 基础Dao接口实现类,实现改类的子类必须设置泛型类型
* @author LiuJunGuang
* @date 2014年3月3日下午1:02:31
*/
public abstract class BaseDaoImpl<T extends Identifiable> implements BaseDao<T> {
@Autowired(required = true)
protected SqlSession sqlSessionTemplate;
public static final String SQLNAME_SEPARATOR = ".";
/**
* @fields sqlNamespace SqlMapping命名空间
*/
private String sqlNamespace = getDefaultSqlNamespace();
/**
* 获取泛型类型的实体对象类全名
* @author LiuJunGuang
* @return
* @date 2014年3月3日下午6:17:46
*/
protected String getDefaultSqlNamespace() {
Class<?> genericClass = BeanUtils.getGenericClass(this.getClass());
return genericClass == null ? null : genericClass.getName();
}
/**
* 获取SqlMapping命名空间
* @author LiuJunGuang
* @return SqlMapping命名空间
* @date 2014年3月4日上午12:33:15
*/
public String getSqlNamespace() {
return sqlNamespace;
}
/**
* 设置SqlMapping命名空间。 以改变默认的SqlMapping命名空间,
* 不能滥用此方法随意改变SqlMapping命名空间。
* @author LiuJunGuang
* @param sqlNamespace SqlMapping命名空间
* @date 2014年3月4日上午12:33:17
*/
public void setSqlNamespace(String sqlNamespace) {
this.sqlNamespace = sqlNamespace;
}
/**
* 将SqlMapping命名空间与给定的SqlMapping名组合在一起。
* @param sqlName SqlMapping名
* @return 组合了SqlMapping命名空间后的完整SqlMapping名
*/
protected String getSqlName(String sqlName) {
return sqlNamespace + SQLNAME_SEPARATOR + sqlName;
}
/**
* 生成主键值。 默认使用{@link UUIDUtils#create()}方法
* 如果需要生成主键,需要由子类重写此方法根据需要的方式生成主键值。
* @param entity 要持久化的对象
*/
protected String generateId() {
return UUIDUtils.create();
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectOne(java.io.Serializable)
*/
@Override
public <V extends T> V selectOne(T query) {
Assert.notNull(query);
try {
Map<String, Object> params = BeanUtils.toMap(query);
return sqlSessionTemplate.selectOne(getSqlName(SqlId.SQL_SELECT), params);
} catch (Exception e) {
throw new DaoException(String.format("查询一条记录出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectById(java.io.Serializable)
*/
@Override
public <V extends T> V selectById(String id) {
Assert.notNull(id);
try {
return sqlSessionTemplate.selectOne(getSqlName(SqlId.SQL_SELECT_BY_ID), id);
} catch (Exception e) {
throw new DaoException(String.format("根据ID查询对象出错!语句:%s", getSqlName(SqlId.SQL_SELECT_BY_ID)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectList(java.io.Serializable)
*/
@Override
public <V extends T> List<V> selectList(T query) {
try {
Map<String, Object> params = BeanUtils.toMap(query);
return sqlSessionTemplate.selectList(getSqlName(SqlId.SQL_SELECT), params);
} catch (Exception e) {
throw new DaoException(String.format("查询对象列表出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectAll()
*/
@Override
public <V extends T> List<V> selectAll() {
try {
return sqlSessionTemplate.selectList(getSqlName(SqlId.SQL_SELECT));
} catch (Exception e) {
throw new DaoException(String.format("查询所有对象列表出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectMap(java.io.Serializable, java.lang.String)
*/
@Override
public <K, V extends T> Map<K, V> selectMap(T query, String mapKey) {
Assert.notNull(mapKey, "[mapKey] - must not be null!");
try {
Map<String, Object> params = BeanUtils.toMap(query);
return sqlSessionTemplate.selectMap(getSqlName(SqlId.SQL_SELECT), params, mapKey);
} catch (Exception e) {
throw new DaoException(String.format("查询对象Map时出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/**
* 设置分页
* @param pageInfo 分页信息
* @return SQL分页参数对象
*/
protected RowBounds getRowBounds(Pageable pageable) {
RowBounds bounds = RowBounds.DEFAULT;
if (null != pageable) {
bounds = new RowBounds(pageable.getOffset(), pageable.getPageSize());
}
return bounds;
}
/**
* 获取分页查询参数
* @param query 查询对象
* @param pageable 分页对象
* @return Map 查询参数
*/
protected Map<String, Object> getParams(T query, Pageable pageable) {
Map<String, Object> params = BeanUtils.toMap(query, getRowBounds(pageable));
if (pageable != null && pageable.getSort() != null) {
String sorting = pageable.getSort().toString();
params.put("sorting", sorting.replace(":", ""));
}
return params;
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectList(com.viathink.core.dao.domain.Identifiable, org.springframework.data.domain.Pageable)
*/
@Override
public <V extends T> List<V> selectList(T query, Pageable pageable) {
try {
return sqlSessionTemplate.selectList(getSqlName(SqlId.SQL_SELECT), getParams(query, pageable));
} catch (Exception e) {
throw new DaoException(String.format("根据分页对象查询列表出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectPageList(com.viathink.core.dao.domain.Identifiable, org.springframework.data.domain.Pageable)
*/
@Override
public <V extends T> Page<V> selectPageList(T query, Pageable pageable) {
try {
List<V> contentList = sqlSessionTemplate.selectList(getSqlName(SqlId.SQL_SELECT),
getParams(query, pageable));
return new PageImpl<V>(contentList, pageable, this.selectCount(query));
} catch (Exception e) {
throw new DaoException(String.format("根据分页对象查询列表出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectMap(com.viathink.core.dao.domain.Identifiable, java.lang.String, org.springframework.data.domain.Pageable)
*/
@Override
public <K, V extends T> Map<K, V> selectMap(T query, String mapKey, Pageable pageable) {
try {
return sqlSessionTemplate.selectMap(getSqlName(SqlId.SQL_SELECT), getParams(query, pageable), mapKey);
} catch (Exception e) {
throw new DaoException(String.format("根据分页对象查询列表出错!语句:%s", getSqlName(SqlId.SQL_SELECT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectCount()
*/
@Override
public Long selectCount() {
try {
return sqlSessionTemplate.selectOne(getSqlName(SqlId.SQL_SELECT_COUNT));
} catch (Exception e) {
throw new DaoException(String.format("查询对象总数出错!语句:%s", getSqlName(SqlId.SQL_SELECT_COUNT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#selectCount(java.io.Serializable)
*/
@Override
public Long selectCount(T query) {
try {
Map<String, Object> params = BeanUtils.toMap(query);
return sqlSessionTemplate.selectOne(getSqlName(SqlId.SQL_SELECT_COUNT), params);
} catch (Exception e) {
throw new DaoException(String.format("查询对象总数出错!语句:%s", getSqlName(SqlId.SQL_SELECT_COUNT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#insert(java.io.Serializable)
*/
@Override
public void insert(T entity) {
Assert.notNull(entity);
try {
if (StringUtils.isBlank(entity.getId()))
entity.setId(generateId());
sqlSessionTemplate.insert(getSqlName(SqlId.SQL_INSERT), entity);
} catch (Exception e) {
throw new DaoException(String.format("添加对象出错!语句:%s", getSqlName(SqlId.SQL_INSERT)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#delete(java.io.Serializable)
*/
@Override
public int delete(T query) {
Assert.notNull(query);
try {
Map<String, Object> params = BeanUtils.toMap(query);
return sqlSessionTemplate.delete(getSqlName(SqlId.SQL_DELETE), params);
} catch (Exception e) {
throw new DaoException(String.format("删除对象出错!语句:%s", getSqlName(SqlId.SQL_DELETE)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#deleteById(java.io.Serializable)
*/
@Override
public int deleteById(String id) {
Assert.notNull(id);
try {
return sqlSessionTemplate.delete(getSqlName(SqlId.SQL_DELETE_BY_ID), id);
} catch (Exception e) {
throw new DaoException(String.format("根据ID删除对象出错!语句:%s", getSqlName(SqlId.SQL_DELETE_BY_ID)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#deleteAll()
*/
@Override
public int deleteAll() {
try {
return sqlSessionTemplate.delete(getSqlName(SqlId.SQL_DELETE));
} catch (Exception e) {
throw new DaoException(String.format("删除所有对象出错!语句:%s", getSqlName(SqlId.SQL_DELETE)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#updateById(java.io.Serializable)
*/
@Override
public int updateById(T entity) {
Assert.notNull(entity);
try {
return sqlSessionTemplate.update(getSqlName(SqlId.SQL_UPDATE_BY_ID), entity);
} catch (Exception e) {
throw new DaoException(String.format("根据ID更新对象出错!语句:%s", getSqlName(SqlId.SQL_UPDATE_BY_ID)), e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#updateByIdSelective(java.io.Serializable)
*/
@Override
@Transactional
public int updateByIdSelective(T entity) {
Assert.notNull(entity);
try {
return sqlSessionTemplate.update(getSqlName(SqlId.SQL_UPDATE_BY_ID_SELECTIVE), entity);
} catch (Exception e) {
throw new DaoException(String.format("根据ID更新对象某些属性出错!语句:%s", getSqlName(SqlId.SQL_UPDATE_BY_ID_SELECTIVE)),
e);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#deleteByIdInBatch(java.util.List)
*/
@Override
@Transactional
public void deleteByIdInBatch(List<String> idList) {
if (idList == null || idList.isEmpty())
return;
for (String id : idList) {
this.deleteById(id);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#updateInBatch(java.util.List)
*/
@Override
@Transactional
public void updateInBatch(List<T> entityList) {
if (entityList == null || entityList.isEmpty())
return;
for (T entity : entityList) {
this.updateByIdSelective(entity);
}
}
/* (non-Javadoc)
* @see com.viathink.core.dao.BaseDao#insertInBatch(java.util.List)
*/
@Override
public void insertInBatch(List<T> entityList) {
if (entityList == null || entityList.isEmpty())
return;
for (T entity : entityList) {
this.insert(entity);
}
}
}
9、通用BaseControllerImpl实现
package com.viathink.frame.core.web.controller;
import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.viathink.frame.core.dao.BaseService;
import com.viathink.frame.core.dao.domain.Identifiable;
import com.viathink.frame.core.web.domain.ControllerPath;
import com.viathink.frame.core.web.domain.Result;
import com.viathink.frame.core.web.domain.Result.Status;
/**
* 基础控制器接口实现类
* @author LiuJunGuang
* @date 2014年3月5日下午12:03:13
*/
public abstract class BaseControllerImpl<T extends Identifiable, Q extends T> implements BaseController<T, Q> {
private Logger log = LoggerFactory.getLogger(BaseControllerImpl.class);
/**
* @fields path 页面路径信息
*/
protected ControllerPath path = new ControllerPath(this.getClass());
/**
* 获取基础的服务
* @return BaseService
*/
protected abstract BaseService<T> getBaseService();
@Override
@ResponseBody
@RequestMapping(value = "/delete", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
public Result deleteList(String[] ids) {
if (ArrayUtils.isEmpty(ids)) {
log.error("未设置批量删除对象的ID号!对象:{}", path.getEntityName());
return new Result(Status.ERROR, "没有传入要删除的ID号数组!");
}
try {
getBaseService().deleteByIdInBatch(Arrays.asList(ids));
} catch (Exception e) {
log.error("批量删除对象失败!对象:" + path.getEntityName(), e);
return new Result(Status.ERROR, "批量删除失败!");
}
return new Result(Status.OK, ids.length);
}
@Override
@ResponseBody
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
public Result deleteOne(@PathVariable("id") String id) {
if (StringUtils.isBlank(id)) {
log.error("要删除的ID号为null或空字符串!对象:{}", path.getEntityName());
return new Result(Status.ERROR, "没有传入要删除的ID号!");
}
int count = getBaseService().deleteById(id);
if (count == 0)
return new Result(Status.ERROR, "要删除的记录不存在!");
log.debug("成功删除{}个对象,id:{},对象:{}", count, id, path.getEntityName());
return new Result(Status.OK, count);
}
@Override
@RequestMapping(method = RequestMethod.POST)
public ModelAndView addOne(T entity) {
getBaseService().insert(entity);
return new ModelAndView(path.getRedirectListPath());
}
@Override
@RequestMapping(value = "/add", method = RequestMethod.GET)
public ModelAndView addView() {
return new ModelAndView(path.getAddViewPath());
}
@Override
@RequestMapping(method = RequestMethod.GET)
public ModelAndView selectList(Q query, @PageableDefault Pageable pageable) {
Page<T> page = getBaseService().queryPageList(query, pageable);
ModelAndView mav = new ModelAndView(path.getListViewPath(), "page", page);
mav.addObject("query", query);
return mav;
}
@Override
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ModelAndView viewOne(@PathVariable("id") String id) {
Object obj = getBaseService().queryById(id);
return new ModelAndView(path.getOneViewPath(), path.getEntityName(), obj);
}
@Override
@ResponseBody
@RequestMapping(method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
public Result editOne(T entity) {
getBaseService().updateById(entity);
return new Result(Status.OK, entity);
}
@Override
@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
public ModelAndView editView(@PathVariable("id") String id) {
Object obj = getBaseService().queryById(id);
return new ModelAndView(path.getEditViewPath(), path.getEntityName(), obj);
}
}
10、列表结果页面:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<#include "/common/common.ftl">
<@pnotify/>
<title>字典列表</title>
</head>
<body>
<#include "/common/navbar.ftl">
<#-- 内容开始 -->
<div class="warp container">
<form action="${base}/sys/dictionary">
<#-- 查询条件 -->
<div class="panel panel-default">
<div class="panel-heading">
<span>查询条件</span>
<ul class="option-group">
<li><a href="javascript:void(0)" ssr-show-detail="detail" class="glyphicon glyphicon-chevron-down" title="高级查询"></a></li>
</ul>
</div>
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<th>名称</th>
<td><input type="text" class="form-control" name="dicNameLike" value="${(query.dicNameLike)!}"></td>
<th>组</th>
<td><input type="text" class="form-control" name="dicGroupLike" value="${(query.dicGroupLike)!}"></td>
<td rowspan="10">
<button type="submit" class="btn btn-default">
<span class="glyphicon glyphicon-search"></span> 查询
</button>
</td>
</tr>
<tr class="detail hidden">
<th>组</th>
<td><input type="text" class="form-control"></td>
<th>类型</th>
<td><input type="text" class="form-control"></td>
</tr>
<tr class="detail hidden">
<th>组</th>
<td><input type="text" class="form-control"></td>
<th>类型</th>
<td><input type="text" class="form-control"></td>
</tr>
</tbody>
</table>
</div>
<#-- 结果列表 -->
<div class="panel panel-default">
<div class="panel-heading">
<span>字典列表</span>
<ul class="option-group">
<li><a data-toggle="modal" data-backdrop="static" data-target="#myModal" href="${base}/sys/dictionary/add" class="glyphicon glyphicon-plus" title="添加"></a></li>
<li><a href="${base}/sys/dictionary/delete" ssr-delete-all="checkboxItem" class="glyphicon glyphicon-trash" title="批量删除"></a></li>
</ul>
</div>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th><input type="checkbox" ssr-select-all="checkboxItem"> 序号</th>
<th>名称</th>
<th>值</th>
<th>组</th>
<th>类型</th>
<th>排序</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<#list page.content as result>
<tr>
<td>
<input type="checkbox" class="checkboxItem" value="${result.dicId}">
<a href="${base}/sys/dictionary/${result.dicId}" data-toggle="modal" data-backdrop="static" data-target="#myModal">${result_index+1}</a>
</td>
<td>${result.dicName}</td>
<td>${result.dicValue}</td>
<td>${result.dicGroup}</td>
<td>${result.dicType.label}</td>
<td>${result.dicOrder}</td>
<td>${result.dicStatus.label}</td>
<td>
<ul class="option-group">
<li><a data-toggle="modal" data-backdrop="static" data-target="#myModal" href="${base}/sys/dictionary/edit/${result.dicId}" title="编辑"
class="glyphicon glyphicon-edit"></a></li>
<li><a href="${base}/sys/dictionary/${result.dicId}" ssr-delete-one title="删除" class="glyphicon glyphicon-trash"></a>
</li>
</ul>
</td>
</tr>
</#list>
<tr>
<td colspan="100"><@tablePage/></td>
</tr>
</table>
</div>
</form>
</div>
<#-- 内容结束 -->
<#include "/common/footer.ftl">
<@modal/>
</body>
</html>
11、编辑页面:
<#assign base=request.contextPath />
<!DOCTYPE html>
<html lang="zh-cn">
<head>
</head>
<body>
<form class="form-horizontal" role="form" method="post" action="${base}/sys/dictionary">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">编辑</h4>
</div>
<div class="modal-body">
<input type="hidden" name="_method" value="put"> <input type="hidden" name="dicId" value="${dictionary.dicId}">
<div class="form-group">
<label for="dicName" class="col-md-2 control-label">名称</label>
<div class="col-md-5">
<input type="text" name="dicName" class="form-control" value="${dictionary.dicName}" id="dicName" placeholder="名称">
</div>
</div>
<div class="form-group">
<label for="dicValue" class="col-md-2 control-label">值</label>
<div class="col-md-5">
<input type="text" name="dicValue" class="form-control" value="${dictionary.dicValue}" id="dicValue" placeholder="值">
</div>
</div>
<div class="form-group">
<label for="dicGroup" class="col-md-2 control-label">组</label>
<div class="col-md-5">
<input type="text" name="dicGroup" class="form-control" value="${dictionary.dicGroup}" id="dicGroup" placeholder="值">
</div>
</div>
<div class="form-group">
<label for="dicType" class="col-md-2 control-label">类型</label>
<div class="col-md-5">
<input type="text" name="dicType" class="form-control" value="${dictionary.dicType}" id="dicType" placeholder="值">
</div>
</div>
<div class="form-group">
<label for="dicOrder" class="col-md-2 control-label">排序</label>
<div class="col-md-5">
<input type="text" name="dicOrder" class="form-control" value="${dictionary.dicOrder}" id="dicOrder" placeholder="值">
</div>
</div>
<div class="form-group">
<label for="dicStatus" class="col-md-2 control-label">状态</label>
<div class="col-md-5">
<input type="text" name="dicStatus" class="form-control" value="${dictionary.dicStatus}" id="dicStatus" placeholder="值">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" id="saveBtn" class="btn btn-primary">保存</button>
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</form>
</body>
<script type="text/javascript">
$(function() {
$("#saveBtn").click(function() {
$.post($('form').attr('action'), $('form').serialize(), function(data) {
$('[data-dismiss]').click();
}, 'json');
});
});
</script>
</html>