spring4+mybaits3整合—项目Demo

项目下载地址: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>

你可能感兴趣的:(spring4)