Service层 : 合并了Service与Dao。
当然对于简单的项目可以这样做,
用起来也方便,直接在service层写hql语句。
基本结构如下
BaseAcion.java
package edu.hainu.knowledge.base; import java.lang.reflect.ParameterizedType; import java.util.List; import javax.annotation.Resource; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import edu.hainu.knowledge.service.LogService; public abstract class BaseAcion<T> extends ActionSupport implements ModelDriven<T>{ protected T model; //子类默认调用父类的构造函数 public BaseAcion(){ //获取当前子类的父类 BaseAcion ParameterizedType pt=(ParameterizedType)this.getClass().getGenericSuperclass(); //获取该类的泛型参数的第一个参数(就是子类传入的实体类) Class<T> clazz =(Class<T>) pt.getActualTypeArguments()[0]; //通过反射创建model的实例 try { model=clazz.newInstance(); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } @Override public T getModel() { return model; } //===============需要的Service统一注入=============== //@Resource //protected BaseService<T> baseService; @Resource protected LogService logService; }
DaoSupport
package edu.hainu.knowledge.base; import java.util.List; public interface DaoSupport<T> { /** * 保存实体 * @param entity */ void save(T entity); /** * 删除实体 * @param entity */ void delete(Long id); /** * 更新实体 * @param entity */ void update(T entity); /** * 按id查询 * @param id * @return */ T getById(Long id); /** * 按id数组查询 * @param ids * @return */ List<T> getByIds(Long[] ids); /** * 查询所有 * @return */ List<T> findAll(); }
DaoSupportImpl
package edu.hainu.knowledge.base; import java.lang.reflect.ParameterizedType; import java.util.Collections; import java.util.List; import javax.annotation.Resource; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Transactional; @Transactional public class DaoSupportImpl<T> implements DaoSupport<T>{ @Resource private SessionFactory sessionFactory; private Class<T> clazz; public DaoSupportImpl() { // 使用反射技术得到T的真实类型 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型 this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型 System.out.println("clazz ---> " + clazz); } /** * 获取当前可用的Session * 共享一个sessionFactory容器,线程安全的 * @return */ protected Session getSession(){ return sessionFactory.getCurrentSession(); } @Override public void save(T entity) { getSession().save(entity); } @Override public void delete(Long id) { Object obj =getById(id); if(obj!=null){ getSession().delete(obj); } } @Override public void update(T entity) { getSession().update(entity); } @Override public T getById(Long id) { if(id==null){ return null; }else { return (T) getSession().get(clazz,id); } } @Override public List<T> getByIds(Long[] ids) { if(ids==null||ids.length==0){ //防止nullException return Collections.EMPTY_LIST; }else{ return getSession().createQuery(// "FROM " + clazz.getSimpleName() + " WHERE id IN (:ids)")// .setParameterList("ids", ids)// .list(); } } @Override public List<T> findAll() { return getSession().createQuery(// "FROM " + clazz.getSimpleName())// .list(); } }
QueryHelper
package edu.hainu.knowledge.util; import java.util.ArrayList; import java.util.List; /** * 用于辅助拼接HQL语句 * * @author Administrator * */ public class QueryHelper { private String fromClause; // From 子句 private String whereClause = ""; // Where子句 private String orderByClause = "";// OrderBy子句 private List<Object> parameters = new ArrayList<Object>(); /** * 生成From子句 * * @param clazz * @param alias */ public QueryHelper(Class clazz, String alias) { fromClause = "FROM " + clazz.getSimpleName() + " " + alias; } /** * 拼接Where子句 * * @param condition * @param params * @return */ public QueryHelper addCondition(String condition, Object... params) { // 拼接 if (whereClause.length() == 0) { whereClause = " WHERE " + condition; } else { whereClause += " AND " + condition; } // 参数 if (params != null) { for (Object p : params) { parameters.add(p); } } return this; } /** * 拼接OrderBy子句 * * @param propertyName * 需要排序的属性名 * @param asc * true Asc false desc * @return */ public QueryHelper addOrderProperty(String propertyName, boolean asc) { if (orderByClause.length() == 0) { orderByClause = " ORDER BY " + propertyName; } else { orderByClause += " AND " + propertyName; } orderByClause += (asc ? " ASC" : " DESC"); return this; } /** * 获取生成的用于查询数据列表的HQL语句 * @return */ public String getListQueryHql(){ return fromClause+whereClause+orderByClause; } /** * 获取生成的用于查询总记录数的HQL语句 * @return */ public String getCountQueryHql(){ return "SELECT COUNT(*) "+fromClause+whereClause; } /** * 获取HQL中的参数列表 * @return */ public List<Object> getParameters() { return parameters; } public void setParameters(List<Object> parameters) { this.parameters = parameters; } }
流程总结:实现增删改查一组功能的步骤
一.设计实体
增加ER图中,实体之间的关系。
检查:
属于实体的属性
关联关系的属性(一个关联关系对应两个实体,不漏不重)
减少运算而冗余的特殊属性
一、特殊属性的作用
Forum |
topicCount |
主题数量 |
articleCount |
文章数量(主题数+回复数) |
|
lastTopic |
最后发表的主题 |
|
Topic |
replyCount |
回复数量 |
lastReply |
最后发表的回复 |
|
lastUpdateTime |
最后更新时间(主题的发表时间或最后回复的时间) |
二、特殊属性的维护
|
|
发表新主题 |
发表新回复 |
Forum |
topicCount |
加1 |
|
articleCount |
加1 |
加1 |
|
lastTopic |
更新为当前的新主题 |
||
Topic |
replyCount |
0,默认值 |
加1 |
lastReply |
Null,默认值 |
更新为当前的新回复 |
|
lastUpdateTime |
主题的发表时间 |
更新为当前新回复的时间 |
domain:写javabean
hbm.xml:映射关系
模板
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<!—本类的attribute属性,本类与class类的一对多 --> <set name=" "> <key column=" "></key> <!-- key指明了多的一方中的外键名--> <one-to-many class=" "/>
<!--本类的attribute属性,本类与class类的多对一 --> <many-to-one name=" " class=" " column=" "> </many-to-one>
<!--本类的attribute属性,,本类与class类的多对多 --> <set name=" " table=" " > <key column=" "></key> <many-to-many class=" " column=" "></many-to-many> </set>
<!--本类的attribute属性,本类与class类一对一。 采用基于外键的一对一映射,本方有外键。 --> <many-to-one name=" " class=" " column=" " unique="true"></many-to-one>
2.做Action相关的准备
1,创建 MyAction extends BaseAction.
2,定义出Action中的方法,要写出方法名、参数、作用、返回值。
/** 列表 */ public String list() throws Exception { return "list"; } /** 删除 */ public String delete() throws Exception { return "toList"; } /** 添加页面 */ public String addUI() throws Exception { return "saveUI"; } /** 添加 */ public String add() throws Exception { return "toList"; } /** 修改页面 */ public String editUI() throws Exception { return "saveUI"; } /** 修改 */ public String edit() throws Exception { return "toList"; }
3,创建出所用到的JSP页面(目前还没有具体内容)。
4,配置Action:
1,在MyAction上写注解 @Controller与@Scope("prototype").
2,在strtus.xml中配置这个Action与所用到的result.
二、做Service相关的准备
1,创建接口MyService extends DaoSupport.
2,创建实现类MyServiceImpl extends DaoSupportImpl.
3,配置:在MyServiceImpl上写注解:
@Service 与 @Transactional
4,声明:在BaseAction中声明:
@Resource protected MyService myService;
三、填空:JSP页面的内容:
a,拷贝静态页面中的源代码到JSP中。
b,包含进来公共的资源:
<%@ include file=“../public/commons.jspf" %>
c,把 ../ 替换为 ${pageContext.request.contextPath}/
d,修改页面内容(使用自定义标签)
在添加struts2中,使用JDK1.8会一直提示,用回1.7又没事了
The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files
Unable to load configuration. - action - file:/D:/workspace/Struts2_0100/WebRoot/WEB-INF/classes/struts.xml:38:66
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:380)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:424)
at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4584)
at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5262)
at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5257)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
//这个地方很关键,因为我一直我修改config/struts.xml里面的action,tomcat一直未能反应过来
Caused by: Action class [testAction] not found - action - file:/D:/workspace/Struts2_0100/WebRoot/WEB-INF/classes/struts.xml:38:66
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.verifyAction(XmlConfigurationProvider.java:420)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:365)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:479)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:275)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:111)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:204)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
... 16 more
projectuildclasses 文件夹存在类编译之后的文件,
应该是Tomcat好像抽风了,一直读取classes里面的struts.xml文件,
解决方法:
把Tomcat里的项目先remove,在把tomcat也删除了,在把classes里的文件全删除了.
把tomcat的缓存也清除掉 tomcat/work
File not found: F:javaWorkSpaceedu.hainu.knowledgeuildclassesstruts.xml.