S2SH框架搭建—基于注解配置

此次搭建s2sh框架为本人练手之用,如有不足请见谅,但希望能帮助到大家!

框架采用struts2.3.34、spring4.3.14、hibernate5.1.12版本搭建,jdk版本采用1.6。

框架中一些固定配置不需要长改动,此部分直接配置到xml中,其他配置则使用注解。

1、 S2SH框架介绍

Struts:控制层,用来控制的。
Spring:对Struts和Hibernate进行管理,整合的。
Hibernate:操控数据库,持久化操作。

框架优点:
1.spring管理对象的实例化,把对象的创建和获取放到外部,更加的灵活方便。
2.Hibernate避免了JDBC连接数据库的冗余繁杂。
3.各层分工明细,实现了各层之间的解耦,代码更加灵活

2、 框架依赖包下载

1) Spring

下载地址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframework/spring/4.3.14.RELEASE/spring-framework-4.3.14.RELEASE-dist.zip

S2SH框架搭建—基于注解配置_第1张图片

Spring版本所需JDK支持:

Spring Framework 3.x

JDK5+

Spring Framework 4.x

JDK6+

Spring Framework 5.x

JDK8+

2) struts2

下载地址:http://struts.apache.org/download.cgi

S2SH框架搭建—基于注解配置_第2张图片

Struts2版本所需JDK支持:

Struts2.3.x及以下

JDK5+

Struts2.5.x

JDK7+

 

3) hibernate

下载地址:http://hibernate.org/orm/releases/5.1/

S2SH框架搭建—基于注解配置_第3张图片

Hibernate版本所需JDK支持:

Hibernate 5.0

JDK 6+

Hibernate 5.1

JDK 6+

Hibernate 5.2

JDK 8+

Hibernate 5.3

JDK 8+

 4)其他所需jar可自行搜索下载

3、 项目总体结构

S2SH框架搭建—基于注解配置_第4张图片

4、 导入框架所需jar包

S2SH框架搭建—基于注解配置_第5张图片

5、 配置文件

1) web.xml,其中主要配置spring的listener、struts2的filter,用于启动加载spring、struts2.



	ssh-xml
  	
	
		contextConfigLocation
		classpath:applicationContext.xml
	
	
	
	
		org.springframework.web.context.ContextLoaderListener
	
	
	
	
		org.springframework.web.context.request.RequestContextListener
	

	
	
		org.springframework.web.util.IntrospectorCleanupListener
	
	
	
	
		encodingFilter
		org.springframework.web.filter.CharacterEncodingFilter
		
			encoding
			UTF-8
		
	
	
		encodingFilter
		*.jsp
	

	
		encodingFilter
		*.do
	
	
	
	
	
		openSessionInView
		org.springframework.orm.hibernate5.support.OpenSessionInViewFilter
		
			sessionFactoryBeanName
			sessionFactory
		
		
			singleSession
			true
		
		   
           flushMode   
           AUTO     
        
	

	
		openSessionInView
		*.do
	
	
	   
      
        struts2  
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter  
      
  
      
        struts2  
        /*  
    
	
	
		index.html
		index.htm
		index.jsp
		default.html
		default.htm
		default.jsp
	

2) 属性文件jdbc.properties,配置数据源的相关信息。

### HIBERNATE CONFIG
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.format_sql=false
hibernate.show_sql=false
hibernate.fetch_size=20
hibernate.batch_size=10
hibernate.hbm2ddl=none

### C3P0 CONFIG(NOT BE USED)
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/sshdemo?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.driver=com.mysql.jdbc.Driver
checkoutTimeout=30000
idleConnectionTestPeriod=60
initialPoolSize=5
maxIdleTime=10
maxPoolSize=20
minPoolSize=2
maxStatements=0
maxStatementsPerConnection=0

3) spring配置文件applicationContext.xml



    					
	
	
	
    
    
    
	
		
			
				classpath:jdbc.properties
			
		
	

    
	
        
		
		
		
		
		
		
		
		
		
		
		
    
    
	
	
		
		
			
				${hibernate.dialect}
				${hibernate.format_sql}
				${hibernate.show_sql}
			    ${hibernate.fetch_size}
			    ${hibernate.batch_size}
                ${hibernate.hbm2ddl}
                false  
			
		
		
        
            
                com.folwind.**.entity
            
		
	
    
    
    
		
	

    
	
		
	

	
	
		
			
			
			
			
			
			
			
			
			
			
			
			
			
			
		
	

	
		
		
	

4) struts2配置文件struts.xml




	
	
	
	
	
	
	
	
	
	
	
	
    
    
	
	
    
    
    
    
	
	
	

	
	

	
	
	
	
	
	
    
    
    
    
    
     
	
	
	
	
	
	
	
	
	
	 
	
	

    

	
		
		
		
			
				
				
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                     1000
                
                
                
                    input,back,cancel,browse
                
                
                    input,back,cancel,browse
                
                
                
			
		

		

		
		
		    
				
				
		        json
		        
		        
				
				
				
				
				true
				  
                
				
				
		    
			/index.jsp
			/framework/common/exception.jsp
		

		
			
		

	

5) 日志配置log4j.properties,配置日志打印的相关信息

#日志框架
#日志等级
#TRACE:详细等级,堆栈信息
#debug:类似于System.out.print
#info:类似于Hibernate的show_sql
#warn:不影响运行, 只是提示
#error:出现异常
#全局日志等级配置,输出位置

log4j.rootLogger=info,stdout,R

#stdout控制器
#org.apache.log4j.ConsoleAppender(控制台),
#org.apache.log4j.FileAppender(文件),
#org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
#org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
#org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
#org.apache.log4j.net.SMTPAppender(邮件发送日志)
#org.apache.log4j.jdbc.JDBCAppender  输出到数据库
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.out

#org.apache.log4j.HTMLLayout(以HTML表格形式布局),
#org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
#org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
#org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

#输出格式
# %c  列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间
#                   假设当前logger名字空间是"a.b.c"
#                   %c           a.b.c
#                   %c{2} 	     b.c
#                   %20c 	      (若名字空间长度小于20,则左边用空格填充)
#                   %-20c 	      (若名字空间长度小于20,则右边用空格填充)
#                   %.30c 	      (若名字空间长度超过30,截去多余字符)
#                   %20.30c 	(若名字空间长度小于20,则左边用空格填充;若名字空间长度超过30,截去多余字符)
#                   %-20.30c 	(若名字空间长度小于20,则右边用空格填充;若名字空间长度超过30,截去多余字符)
# %C  列出调用logger的类的全名(包含包路径)
#                   假设当前类是"org.apache.xyz.SomeClass"
#                   %C           org.apache.xyz.SomeClass
#                   %C{1} 	     SomeClass
# %d  显示日志记录时间,{<日期格式>}使用ISO8601定义的日期格式 	
#                   %d{yyyy/MM/dd HH:mm:ss,SSS} 	   2005/10/12 22:23:30,117
#                   %d{ABSOLUTE} 	                   22:23:30,117
#                   %d{DATE} 	                       12 Oct 2005 22:23:30,117
#                   %d{ISO8601} 	                   2005-10-12 22:23:30,117
# %F  显示调用logger的源文件名 	
#                   %F 	         MyClass.java
# %l  输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数
#                   %l           MyClass.main(MyClass.java:129)
# %L  显示调用logger的代码行 
#                   %L           129
# %m  显示输出消息
#                   %m           This is a message for debug.
# %M  显示调用logger的方法名 
#                   %M           main
# %n  当前平台下的换行符 
#                   %n           Windows平台下表示rn,UNIX平台下表示n
# %p  显示该条日志的优先级
#                   %p           INFO
# %r  显示从程序启动时到记录该条日志时已经经过的毫秒数
#                   %r           1215
# %t  输出产生该日志事件的线程名
#                   %t           MyClass
# %x  按NDC(Nested Diagnostic Context,线程堆栈)顺序输出日志
#                   假设某程序调用顺序是MyApp调用com.foo.Bar
#                   %c %x - %m%n               MyApp - Call com.foo.Bar. 
#                                              com.foo.Bar - Log in Bar
#                                              MyApp - Return to MyApp.
# %X  按MDC(Mapped Diagnostic Context,线程映射表)输出日志。通常用于多个客户端连接同一台服务器,方便服务器区分是那个客户端访问留下来的日志。
#                   %X{5} 	(记录代号为5的客户端的日志)
# %%  显示一个百分号
#                   %%           %
log4j.appender.stdout.layout.ConversionPattern= [%p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%c.%M(%F:%L)] --> %m%n
#log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

#文件路径输出
log4j.appender.R=org.apache.log4j.RollingFileAppender
#默认输出到tomcat的根路径或者运行测试工程的根路径
log4j.appender.R.File=D\:/work/workspaces/training-workspaces/apache-tomcat-6.0.37/logs/ssh-scan.log
log4j.appender.D.Append = true
#log4j.appender.D.Threshold = error
log4j.appender.R.MaxFileSize=1024KB
# Keep three backup files.
log4j.appender.R.MaxBackupIndex=20
# Pattern to output: date priority [category] - message
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern= [%p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%c.%M(%F:%L)] --> %m%n

6、 Base组件定义,定义分页组件PageModel、BaseDAO持久化操作、BaseService基本业务逻辑操作、BaseActionSupport控制层

1) 分页组件PageModel

package com.folwind.framework.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PageModel {
	// 总记录数
	private int totalRecords = 0;
	// 结果集
	private List data = Collections.emptyList();
	// 当前页
	private int pageNo = 1;
	// 每页显示多少条
	private int pageSize = 10;
	
	private List sortField = null;
	
	private List directions = null;
	
	private boolean success = true;
	
	private String msg = "";
	
	private final String SPACE = " ";
	
	public int getTotalRecords() {
		return totalRecords;
	}

	public void setTotalRecords(int totalRecords) {
		this.totalRecords = totalRecords;
	}

	public List getData() {
		return data;
	}

	public void setData(List data) {
		this.data = data;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public boolean isNull() {
		if (data == null || data.size() <= 0) {
			return true;
		} else {
			return false;
		}
	}
	
	public void addSort(String fieldName, String direction) {
		if(this.sortField == null) {
			this.sortField = new ArrayList(1);
			this.directions = new ArrayList(1);
		}
		this.sortField.add(fieldName);
		this.directions.add(direction);
	}
	
	public String generateSortStr() {
		StringBuilder builder = new StringBuilder();
		if(this.sortField != null) {
			int length = this.sortField.size();
			for (int i = 0; i < length; i++) {
				if( i > 0) {
					builder.append(", ");
				}
				builder.append(this.sortField.get(i));
				builder.append(SPACE);
				builder.append(this.directions.get(i));
			}
		}
		return builder.toString();
	}
	
	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
}

2) BaseDAO

package com.folwind.framework.core;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.folwind.framework.util.HqlConvertUtil;
import com.folwind.framework.util.PageUtil;

@SuppressWarnings("unchecked")
@Repository
public class BaseDAO extends HibernateDaoSupport {
	
	public T load(Class clazz, Serializable id) {
		return this.getHibernateTemplate().load(clazz, id);
	}
	
	public void save(T obj) throws Exception {
		getHibernateTemplate().save(obj);
		getHibernateTemplate().flush();
	}
	
	public void update(T obj) throws Exception {
		getHibernateTemplate().update(obj);
		getHibernateTemplate().flush();
	}
	
	public void saveOrUpdate(T obj) throws Exception {
		getHibernateTemplate().saveOrUpdate(obj);
		getHibernateTemplate().flush();
	}
	
	public void merge(T obj) throws Exception {
		getHibernateTemplate().merge(obj);
		getHibernateTemplate().flush();
	}
	
	public void delete(T obj) throws Exception {
		if(obj != null) {
			getHibernateTemplate().delete(obj);
			getHibernateTemplate().flush();
		}
	}
	
	public void delete(Class clazz, Serializable id) throws Exception {
		T obj = load(clazz, id);
		if (obj != null)
			delete(obj);
	}
	
	public void delete(String hql) throws Exception {
		this.getHibernateTemplate().deleteAll(find(hql));
	}
	
	public void delete(String hql, String paramName, Object value) throws Exception {
		this.getHibernateTemplate().deleteAll(find(hql, paramName, value));
	}
	
	public void delete(String hql, List paramNames, List values) throws Exception {
		this.getHibernateTemplate().deleteAll(find(hql, paramNames, values));
	}
	
	public List findAll(Class clazz) throws Exception {
		return this.getHibernateTemplate().loadAll(clazz);
	}
	
	public List find(String hql) throws Exception {
		return (List) getHibernateTemplate().find(HqlConvertUtil.convert(hql));
	}
	
	public List find(String hql, String paramName, Object value) throws Exception {
		return (List) getHibernateTemplate().findByNamedParam(HqlConvertUtil.convert(hql), paramName, value);
	}
	
	public List find(String hql, List paramNames, List values) throws Exception {
		return (List) getHibernateTemplate().findByNamedParam(HqlConvertUtil.convert(hql), paramNames.toArray(new String[paramNames.size()]), values.toArray());
	}
	
	/**
	 * 根据属性名和属性值查询对象 ,返回唯一对象
	 */
	public T findBy(Class clazz, String paramName, Object value) throws Exception {
		Criteria criteria = currentSession().createCriteria(clazz);
		criteria.add(Restrictions.eq(paramName, value));
		return (T) criteria.uniqueResult();
	}
	
	/**
	 * 根据属性名和属性值查询对象 ,返回符合条件的对象列表
	 */
	public List findAllBy(Class clazz, String paramName, Object value) throws Exception {
		Criteria criteria = currentSession().createCriteria(clazz);
		criteria.add(Restrictions.eq(paramName, value));
		return criteria.list();
	}
	
	/**
	 * 根据属性名和属性值查询对象 ,返回符合条件的排序对象列表
	 */
	public List findAllBy(Class clazz, String paramName, Object value, String orderby) throws Exception {
		Criteria criteria = currentSession().createCriteria(clazz);
		criteria.add(Restrictions.eq(paramName, value));
		criteria.addOrder(Order.asc(orderby));
		return criteria.list();
	}
	
	public List findAllBy(Class clazz, String paramName, Object value, String orderby, boolean asc) throws Exception {
		Criteria criteria = currentSession().createCriteria(clazz);
		criteria.add(Restrictions.eq(paramName, value));
		if (asc)
			criteria.addOrder(Order.asc(orderby));
		else
			criteria.addOrder(Order.desc(orderby));
		return criteria.list();
	}
	
	/**
	 * 根据属性名和属性值查询对象 ,返回符合条件的对象列表
	 */
	public List findAllByLike(Class clazz, String name, Object value) throws Exception {
		Criteria criteria = currentSession().createCriteria(clazz);
		criteria.add(Restrictions.like(name, value));
		return criteria.list();
	}
	
	/**
	 * -----------------------------------------------------------------------
	 * 搜索统一实现
	 * -----------------------------------------------------------------------
	 */
	public PageModel findPage(String hql, PageModel pm) throws Exception {
		return findPage(hql, null, null, pm);
	}
	
	/**
	 * 根据HQL语句进行分页查询
	 * 
	 * @param hql HQL语句
	 * @param params HQL语句带的多个参数值
	 * @param offset 从第几条记录开始查询
	 * @param pageSize 每页显示多少行
	 * @return 分页模型
	 */
	public PageModel findPage(final String hql, final List paramNames, final List values, PageModel pm) throws Exception {
		// 获取总记录数total
		if(paramNames != null && values != null && paramNames.size() != values.size()) {
			throw new Exception("参数列表不一致!");
		}
		final String convertedHql = HqlConvertUtil.convert(hql);
		final String countHql = getCountHql(convertedHql);
		
	
		int total = (Integer)getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException {
				
				Query query = session.createQuery(countHql);
				setParameters(query, paramNames, values);
				return ((Long) query.uniqueResult()).intValue();
			}
	    });
		
		final int pageNo = pm.getPageNo();
		final int pageSize = pm.getPageSize();
		List datas = (List)getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException {
				
				Query query = session.createQuery(convertedHql);
				setParameters(query, paramNames, values);
				return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
			}
	    });

	    int pageCurrent = PageUtil.getCurrentPage(total, pm.getPageSize(), pm.getPageNo());
	    
	    pm.setPageNo(pageCurrent);
		// 返回数据
		pm.setTotalRecords(total);
		pm.setData(datas);
		return pm;
	}
	
	public int executeSql(String sql) throws Exception {
		Query query = currentSession().createSQLQuery(sql);
		return query.executeUpdate();
	}
	
	public List> findBySql(String sql) throws Exception {
		Query query = currentSession().createSQLQuery(sql);
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return query.list();
	}

	public List> findBySql(String sql, String paramName, Object value) throws Exception {
		Query query = currentSession().createSQLQuery(sql);
		query.setParameter(paramName, value);
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return query.list();
	}
	
	public List> findBySql(String sql, List paramNames, List values) throws Exception {
		Query query = currentSession().createSQLQuery(sql);
		setParameters(query, paramNames, values);
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return query.list();
	}
	
	public PageModel findPageBySql(String sql, String countSql, PageModel pm) throws Exception {
		Query countquery = currentSession().createSQLQuery(countSql);
		List countList = countquery.list();
		int rowCount = 0;
		if ((countList != null) && (!countList.isEmpty())) {
			rowCount = new Integer(countList.get(0).toString()).intValue();
		}
	    int pageCurrent = PageUtil.getCurrentPage(rowCount, pm.getPageSize(), pm.getPageNo());
	    
	    pm.setTotalRecords(rowCount);
	    pm.setPageNo(pageCurrent);
		
		Query query = currentSession().createSQLQuery(sql);
		query.setFirstResult((pageCurrent - 1) * pm.getPageSize());
	    query.setMaxResults(pm.getPageSize());
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		
		pm.setData(query.list());
		
		return pm;
	}
	
	public PageModel findPageBySql(String sql, String countSql, String paramName, Object value, PageModel pm) throws Exception {
		Query countquery = currentSession().createSQLQuery(countSql);
		countquery.setParameter(paramName, value);
		List countList = countquery.list();
		int rowCount = 0;
		if ((countList != null) && (!countList.isEmpty())) {
			rowCount = new Integer(countList.get(0).toString()).intValue();
		}
	    int pageCurrent = PageUtil.getCurrentPage(rowCount, pm.getPageSize(), pm.getPageNo());
	    
	    pm.setTotalRecords(rowCount);
	    pm.setPageNo(pageCurrent);
		
		Query query = currentSession().createSQLQuery(sql);
		query.setParameter(paramName, value);
		query.setFirstResult((pageCurrent - 1) * pm.getPageSize());
	    query.setMaxResults(pm.getPageSize());
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		
		pm.setData(query.list());
		
		return pm;
	}
	
	public PageModel findPageBySql(String sql, String countSql, List paramNames, List values, PageModel pm) throws Exception {
		Query countquery = currentSession().createSQLQuery(countSql);
		setParameters(countquery, paramNames, values);
		List countList = countquery.list();
		int rowCount = 0;
		if ((countList != null) && (!countList.isEmpty())) {
			rowCount = new Integer(countList.get(0).toString()).intValue();
		}
	    int pageCurrent = PageUtil.getCurrentPage(rowCount, pm.getPageSize(), pm.getPageNo());
	    
	    pm.setTotalRecords(rowCount);
	    pm.setPageNo(pageCurrent);
		
		Query query = currentSession().createSQLQuery(sql);
		setParameters(query, paramNames, values);
		query.setFirstResult((pageCurrent - 1) * pm.getPageSize());
	    query.setMaxResults(pm.getPageSize());
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		
		pm.setData(query.list());
		
		return pm;
	}
	
	/**
	 * 根据HQL语句,获得查找总记录数的HQL语句 如: select ... from Orgnization o where o.parent is
	 * null 经过转换,可以得到: select count(*) from Orgnization o where o.parent is null
	 * @param hql
	 * @return 
	 */
	private String getCountHql(String hql) throws Exception {
		int index = hql.indexOf("from");
		if (index != -1) {
			return "select count(*) " + hql.substring(index);
		}
		return null;
	}
	
	private void setParameters(Query query, List paramNames, List values) throws HibernateException {
		if (paramNames != null && paramNames.size() > 0) {
			int length = paramNames.size();
			Object obj = null;
			for (int i = 0; i < length; i++) {
				obj = values.get(i);
				if(obj == null) {
					continue;
				}
				if(Collection.class.isAssignableFrom(obj.getClass())) {
					query.setParameterList(paramNames.get(i), (Collection) obj);
				}
				else if(obj.getClass().isArray()) {
					query.setParameterList(paramNames.get(i), (Object[])obj);
				}
				else {
					query.setParameter(paramNames.get(i), values.get(i));
				}
			}
		}
	}
} 
  

3) BaseService

package com.folwind.framework.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class BaseService {
	@Autowired
	protected BaseDAO dao;

	public abstract Class getEntityClass();
	public abstract String getEntityClassName();

	/**
	 * 生成hql的条件语句,开头为and条件连接符,实体别名为t
	 * @param queryEntity 存储查询条件的实体对象
	 * @param paramNames 条件语句中的插值符
	 * @param values  条件语句中插值符的值
	 * @return
	 */
	protected abstract String generateWheres(T queryEntity, List paramNames, List values) throws Exception;

	public T loadById(Serializable id) {
		return dao.load(getEntityClass(), id);
	}

	public void save(T obj) throws Exception {
		dao.save(obj);
	}

	public void update(T obj) throws Exception {
		dao.update(obj);
	}

	public void saveOrUpdate(T obj) throws Exception {
		dao.saveOrUpdate(obj);
	}

	public void merge(T obj) throws Exception {
		dao.merge(obj);
	}

	public void delete(T obj) throws Exception {
		dao.delete(obj);
	}

	public void deleteById(Serializable id) throws Exception {
		dao.delete(getEntityClass(), id);
	}

	public void deleteByIds(Serializable[] ids) throws Exception {
		for (int i = 0; i < ids.length; i++) {
			dao.delete(getEntityClass(), ids[i]);
		}
	}

	public List findAll() throws Exception {
		return dao.findAll(getEntityClass());
	}

	/**
	 * 根据属性名和属性值查询对象 ,返回唯一对象
	 */
	public T findBy(String name, Object value) throws Exception {
		return dao.findBy(getEntityClass(), name, value);
	}

	/**
	 * 根据属性名和属性值查询对象 ,返回符合条件的对象列表
	 */
	public List findAllBy(String name, Object value) throws Exception {
		return dao.findAllBy(getEntityClass(), name, value);
	}

	/**
	 * 根据属性名和属性值查询对象 ,返回符合条件的排序对象列表
	 */
	public List findAllBy(String name, Object value, String orderby) throws Exception {
		return dao.findAllBy(getEntityClass(), name, value, orderby);
	}

	public List findAllBy(String name, Object value, String orderby, boolean asc) throws Exception {
		return dao.findAllBy(getEntityClass(), name, value, orderby, asc);
	}

	/**
	 * 根据属性名和属性值查询对象 ,返回符合条件的对象列表
	 */
	public List findAllByLike(String name, Object value) throws Exception{
		return dao.findAllByLike(getEntityClass(), name, value);
	}

	/**
	 * -----------------------------------------------------------------------
	 * 搜索统一实现
	 * -----------------------------------------------------------------------
	 */
	protected PageModel findPage(String hql, PageModel pm) throws Exception{
		return dao.findPage(hql, pm);
	}

	/**
	 * 根据HQL语句进行分页查询
	 * 
	 * @param hql HQL语句
	 * @param params HQL语句带的多个参数值
	 * @param offset 从第几条记录开始查询
	 * @param pageSize 每页显示多少行
	 * @return 分页模型
	 */
	protected PageModel findPage(String hql, List paramNames, List values, PageModel pm) throws Exception {
		return dao.findPage(hql, paramNames, values, pm);
	}

	public PageModel findPage(T queryEntity, PageModel pm) throws Exception {
		List paramNames = new ArrayList();
		List values = new ArrayList();
		StringBuilder builder = generateHql(generateWheres(queryEntity, paramNames, values), pm.generateSortStr());

		return dao.findPage(builder.toString(), paramNames, values, pm);
	}

	public BaseDAO getDao() {
		return dao;
	}

	public void setDao(BaseDAO dao) {
		this.dao = dao;
	}

	/**
	 * 生成hql语句,实体别名为t
	 * @param wheres 条件语句,开头为and条件连接符
	 * @param orderBy 排序语句,可多个字段排序,例:field1 asc,field2 desc
	 * @return
	 */
	protected StringBuilder generateHql(String wheres, String orderBy) throws Exception {
		StringBuilder builder = new StringBuilder();
		builder.append("from ");
		builder.append(getEntityClassName());
		builder.append(" t ");
		builder.append(" where 1=1 ");
		if(StringUtils.isNotBlank(wheres)) {
			builder.append(wheres);
		}
		if(StringUtils.isNotBlank(orderBy)) {
			builder.append(" order by ");
			builder.append(orderBy);
		}

		return builder;
	}
} 
  

4) BaseActionSupport

package com.folwind.framework.core;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.beans.factory.annotation.Autowired;

import com.folwind.sys.menu.service.SysMenuService;
import com.folwind.sys.user.service.SysUserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

//继承ActionSupport,让本类具备强大的功能(例如:校验、国际化等)
public abstract class BaseActionSupport extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware, Preparable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected final String JSON = "json";

	protected HttpServletResponse response;
	protected HttpServletRequest request;
	protected Map session;

	private Object json;
	private Map jsonMap;

	//=================Service注入========================
	@Autowired
	protected SysUserService sysUserService;
	@Autowired
	protected SysMenuService sysMenuService;

	@Override
	public void prepare() throws Exception {
		this.jsonMap = new HashMap(5);
		setSuccessJson();
	}

	@Override
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	@Override
	public void setSession(Map session) {
		this.session = session;
	}

	public void setJson(Object json) {
		this.json = json;
	}

	public Object getJson() {
		return this.json;
	}

	protected void setSuccessJson() {
		jsonMap.put("success", Boolean.TRUE);
		jsonMap.put("msg", "操作成功");
		setJson(jsonMap);
	}

	protected void setSuccessJson(String msg) {
		jsonMap.put("success", Boolean.TRUE);
		jsonMap.put("msg", msg);
		setJson(jsonMap);
	}

	protected void addJson(String key, Object value) {
		jsonMap.put(key, value);
		setJson(jsonMap);
	}

	protected void setFailJson(String errorMsg) {
		jsonMap.put("success", Boolean.FALSE);
		jsonMap.put("msg", errorMsg);
		setJson(jsonMap);
	}

	/**
	 * 将list转换成json数据
	 * @param list
	 * @return
	 */
	public String convertListToJson(List list) {
		//将list转为json
		JSONArray jsonArray = new JSONArray();
		jsonArray = JSONArray.fromObject(list);
		return  jsonArray.toString();
	}

	/**
	 * 输出字符串 Json数据
	 * @param json
	 */
	public void outPutJson(String json) {
		try {
			// 设置文本流头信息
			response.setContentType("text/html;charset=UTF-8");
			// 获取流
			PrintWriter out = response.getWriter();
			// 将流打到客户端
			out.print(json);
			// 清空缓存
			out.flush();
			// 关闭流
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

7、 Entity,数据库表ORM映射信息

package com.folwind.sys.user.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

/**
 * SysUser entity. @author MyEclipse Persistence Tools
 */
@Entity//声明当前类为hibernate映射到数据库中的实体类
@Table(name = "T_SYS_USER")
public class SysUser implements java.io.Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// Fields

	@Id//声明此列为主键,作为映射对象的标识符
	/**
	 *  @GeneratedValue注解来定义生成策略
	 *  GenerationType.TABLES 当前主键的值单独保存到一个数据库的表中
	 *  GenerationType.SEQUENCE  利用底层数据库提供的序列生成标识符
	 *  GenerationType.IDENTITY 采取数据库的自增策略
	 *  GenerationType.AUTO 根据不同数据库自动选择合适的id生成方案,这里使用mysql,为递增型
	 */
	//@GeneratedValue(strategy = GenerationType.AUTO)
	@GenericGenerator(name = "assigned", strategy = "assigned")
	@GeneratedValue(generator="assigned")
	@Column(name = "ID", unique=true, nullable = false, length=50)
	private String id;

	@Column(name = "PASSWORD", length = 32)
	private String password;

	@Column(name = "REAL_NAME", length = 255)
	private String realName;

	@Column(name = "EMAIL", length = 255)
	private String email;

	@Column(name = "MOBILE", length = 16)
	private String mobile;

	@Column(name = "ORG_ID", length = 50)
	private String orgId;

	// Constructors

	/** default constructor */
	public SysUser() {
	}

	/** minimal constructor */
	public SysUser(String id) {
		this.id = id;
	}

	/** full constructor */
	public SysUser(String id, String password, String realName, String email,
			String mobile, String orgId) {
		this.id = id;
		this.password = password;
		this.realName = realName;
		this.email = email;
		this.mobile = mobile;
		this.orgId = orgId;
	}

	// Property accessors

	public String getId() {
		return this.id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getRealName() {
		return this.realName;
	}

	public void setRealName(String realName) {
		this.realName = realName;
	}

	public String getEmail() {
		return this.email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getMobile() {
		return this.mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getOrgId() {
		return this.orgId;
	}

	public void setOrgId(String orgId) {
		this.orgId = orgId;
	}

}

8、 Service,service层业务逻辑操作,继承BaseService

package com.folwind.sys.user.service;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.folwind.framework.core.BaseService;
import com.folwind.sys.user.entity.SysUser;

@Service
public class SysUserService extends BaseService {

	@Override
	public Class getEntityClass() {
		return SysUser.class;
	}

	@Override
	public String getEntityClassName() {
		return "SysUser";
	}

	@Override
	protected String generateWheres(SysUser queryEntity,
			List paramNames, List values) throws Exception {
		if(queryEntity == null) {
			return "";
		}
		StringBuilder sb = new StringBuilder();

		if(StringUtils.isNotBlank(queryEntity.getRealName())) {
			sb.append(" and t.realName like :realName");
			paramNames.add("realName");
			values.add("%" + queryEntity.getRealName() + "%");
		}
		if(StringUtils.isNotBlank(queryEntity.getMobile())) {
			sb.append(" and t.mobile like :mobile");
			paramNames.add("mobile");
			values.add("%" + queryEntity.getMobile() + "%");
		}
		return sb.toString();
	}
} 
  

9、 Action,action层控制逻辑操作,继承BaseActionSupport

package com.folwind.sys.user.action;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.folwind.framework.core.BaseActionSupport;
import com.folwind.framework.core.PageModel;
import com.folwind.framework.util.BeanUtil;
import com.folwind.framework.util.PageUtil;
import com.folwind.sys.user.entity.SysUser;

@Results({
	@Result(name="list",location="/sys/user/jsp/user.jsp")
})
public class SysUserAction extends BaseActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final Log LOG = LogFactory.getLog(SysUserAction.class);

	private SysUser entity;
	private String id;

	public String list() {
		return "list";
	}

	public String search() {
		PageModel pm = null;
		try {
			pm = PageUtil.createPageModel(request);

			pm = sysUserService.findPage(getEntity(), pm);

			pm.setSuccess(Boolean.TRUE);
			pm.setMsg("查询数据成功!");
		} catch (Exception e) {
			if(pm == null) {
				pm = new PageModel();
			}

			pm.setSuccess(Boolean.FALSE);
			pm.setMsg("查询数据失败!");
			LOG.error("查询数据失败!" + e.getMessage(), e);
		}
		setJson(pm);

		return JSON;
	}

	public String searchById() {
		try {
			entity = sysUserService.loadById(id);

			addJson("entity", entity);
			setSuccessJson("查询数据成功!");
		} catch (Exception e) {
			setFailJson("查询数据失败!");
			LOG.error("查询数据失败!" + e.getMessage(), e);
		}

		return JSON;
	}

	public String doCreate() {
		try {
			sysUserService.save(getEntity());

			setSuccessJson("创建数据成功!");
		} catch (Exception e) {
			setFailJson("创建数据失败!");
			LOG.error("创建数据失败!" + e.getMessage(), e);
		}

		return JSON;
	}

	public String doModify() {
		try {
			SysUser entity = getEntity();
			SysUser oldEntity = sysUserService.loadById(entity.getId());

			BeanUtil.copyPropertiesExcludeNullValue(oldEntity, entity);

			sysUserService.update(oldEntity);

			setSuccessJson("修改数据成功!");
		} catch (Exception e) {
			setFailJson("修改数据失败!");
			LOG.error("修改数据失败!" + e.getMessage(), e);
		}

		return JSON;
	}

	public String delete() {
		try {
			if(StringUtils.isNotBlank(id)) {
				sysUserService.deleteByIds(StringUtils.split(id.toString(), ","));
			}

			setSuccessJson("删除数据成功!");
		} catch (Exception e) {
			setFailJson("删除数据失败!");
			LOG.error("删除数据失败!" + e.getMessage(), e);
		}

		return JSON;
	}

	public SysUser getEntity() {
		return this.entity;
	}

	public void setEntity(SysUser entity) {
		this.entity = entity;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

}

10、 前台调用

前台调用Action方法的方式:sys-user!list.do

S2SH框架搭建—基于注解配置_第6张图片

你可能感兴趣的:(框架学习)