SSH框架从接触以来改变了我对代码的编写方式,从最初开始学习到勉强掌握可以说得到不少心得,以下内容出自java初学者对SSH的理解,如有不对的地方还请谅解,希望可以提出来与我交流,谢谢!
SSH顾名思义,struts2,spring,hibernate三大框架组成的从服务端接收请求到数据库调用并返回的一种流程(个人观点,词汇也并不准确)
那么如何去使用,又有那些有点缺点呢?
在使用这个框架之前我一直都是使用servlet ,那么servlet是什么呢?(下面是我从百度上拷贝过来的servlet生命周期解释)
-
客户端请求该 Servlet;
-
加载 Servlet 类到内存;
-
实例化并调用init()方法初始化该 Servlet;
-
service()(根据请求方法不同调用doGet() 或者 doPost(),此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions()、destroy())。
-
加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet。
Server 创建一个 Servlet的实例
第一个客户端的请求到达 Server
Server 调用 Servlet 的 init() 方法(可配置为 Server 创建 Servlet 实例时调用,在 web.xml 中 <servlet> 标签下配置 <load-on-startup> 标签,配置的值为整型,值越小 Servlet 的启动优先级越高)
一个客户端的请求到达 Server
Server 创建一个请求对象,处理客户端请求
Server 创建一个响应对象,响应客户端请求
Server 激活 Servlet 的 service() 方法,传递请求和响应对象作为参数
service() 方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息
service() 方法使用响应对象的方法,将响应传回Server,最终到达客户端。service()方法可能激活其它方法以处理请求,如 doGet() 或 doPost() 或程序员自己开发的新的方法。
对于更多的客户端请求,Server 创建新的请求和响应对象,仍然激活此 Servlet 的 service() 方法,将这两个对象作为参数传递给它。如此重复以上的循环,但无需再次调用 init() 方法。一般 Servlet 只初始化一次(只有一个对象),当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方法。
当时用servlet的时候觉得蛮好用,自从学会ssh就知道,SSH起初配置的东西偏多,比较麻烦,但是项目基础搭建好了只好就特别方便,比如hibernate链接数据库
在这里我们需要用到一个BaceDao,用来把dao层的方法统一的抽象出来方便调用,下面是我们项目小组自己编写的抽象dao层:
package com.dazhi.core; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.List; public abstract class AbstractBaseDao<T> implements BaseDao<T> { Class<T> tClass; String className; public SessionFactory sessionFactory; @Autowired public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public AbstractBaseDao(){ ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass(); tClass = (Class<T>)parameterizedType.getActualTypeArguments()[0]; this.className = tClass.getSimpleName(); } @Override public Serializable save(T model) { Session session = sessionFactory.getCurrentSession(); Serializable serializable = session.save(model); return serializable; } @Override public int save(List<T> lists) { return 0; } @Override public int saveOrUpdate(List<T> lists) { for(T l:lists){ sessionFactory.getCurrentSession().saveOrUpdate(l); } return 0; } @Override public void delete(T model) { sessionFactory.getCurrentSession().delete(model); } /** * 批量删除 * @param ids */ @Override public void deleteList(String ids) { String hql = "DELETE FROM " + className + " AS A WHERE A.id IN ("+ids+")"; Query query = sessionFactory.getCurrentSession().createQuery(hql); query.executeUpdate(); } @Override public void update(T model) { sessionFactory.getCurrentSession().update(model); } // @Transactional @Override public List<T> findList() { return sessionFactory.getCurrentSession().createQuery("FROM "+className).list(); } @Override public List<T> findList(String property, Serializable value) { List<Query> query = sessionFactory.getCurrentSession().createQuery("FROM " + className + " AS B WHERE B." + property + "=" + value).list(); return (List<T>) query; } @Override public T find(Serializable id) { return (T) sessionFactory.getCurrentSession().get(tClass,id); } @Override public T find(String property, Serializable value) { Query query = sessionFactory.getCurrentSession().createQuery("FROM " + className + " AS B WHERE B." + property + "=:v"); query.setParameter("v",value).uniqueResult(); return (T)query.uniqueResult(); } @Override public List<T> queryForPage(int offset, int length) { Query q = sessionFactory.getCurrentSession().createQuery("FROM "+className); q.setFirstResult(offset); q.setMaxResults(length); return q.list(); } @Override public List<T> queryForPage(String hql, int offset, int length) { Query q = sessionFactory.getCurrentSession().createQuery(hql); q.setFirstResult(offset); q.setMaxResults(length); return q.list(); } @Override public Integer getCount() { // sessionFactor Query q = sessionFactory.getCurrentSession().createQuery("SELECT COUNT (*) FROM "+className); return Integer.parseInt(q.list().get(0).toString()); } @Override public Integer getCount(String hql) { Query q = sessionFactory.getCurrentSession().createQuery(hql); return Integer.parseInt(q.list().get(0).toString()); } }
上面这些方法是增删改查经常会用到的方法,于是我们把他抽象的写出来,只要经过观察就不难发现这些方法的用处了,当然这个方法也不是很完善。
用这个的方法就是首先我们需要数据库有一个表,之后我们也要对应的写出bean类,每一个bean类都需要有与之对应的service和dao(service集成抽象service,dao要继承抽象dao),同时我们需要配置hbm文件,用来确定数据库与表的关系,这个详情可以参考hibernate的使用方式,关于hbm文件的配置与使用,当然链接数据库还需要配置applicationContext.xml这个文件,这个文件的作用就是链接数据库的地址,用户名,密码,从这里写完一次之后只需要从web.xml中拿来调用就可以了,包括换个数据库只需要新建一个applicationContext.xml2来代替它是不是方便的多,感觉到美滋滋呢?
对了,还是从struts开始讲起吧,其实一开始刚上手我也很懵逼,搞不懂到底怎么用,不过现在我明白了一些,struts使用方式很简单,首先我们需要先从web.xml中调用struts2来帮我们管理链接地址就好了,也就是说web.xml被struts2取代(只是某些用途上的取代,并不是完全的),下面是web.xml中的写法
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>Archetype Created Web Application</display-name> //这里的作用是配置链接数据库的文件,更改数据库只需要applicationContext.xml配置在这里就好了 <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-teacher.xml,classpath:applicationContext-common.xml</param-value> </context-param> <filter > <filter-name > HibernateOpenSession</filter-name > <filter-class > org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class > </filter > <filter-mapping > <filter-name > HibernateOpenSession</filter-name > <url-pattern > /*</url-pattern > </filter-mapping > <!--<!– 分布式Session共享Filter –>--> <filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> //在这里打上一下代码就可一让struts2来帮我们管理链接请求了,是不是很简单呢 <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> 然后我们就可以使用struts2了,当然别忘了去下载jar包,如果你使用maven来管理jar包的话 <!-- Struts--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts.version}</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>${struts.version}</version> </dependency> 就是这些打在pom文件中,不知道maven是什么的可以自己去百度,简单的来说就是个jar包管理工具用起来方便的很,再也不用自己去找jar包了 之后我们需要一个struts.xml文件 <action name="paper_*" class="com.dazhi.controller.PaperAction" method="{1}"> <result name="all">/paper/index.jsp</result> <result name="add">/paper/add.jsp</result> <result name="one">/paper/update.jsp</result> <result name="delete">/paper/update.jsp</result> </action> 就像这样,如果你可以访问paper_add.action去找到com.dazhi.controller.PaperAction这个文件,访问完会跳转到这个页面/paper/add.jsp 在PaperAction这个文件中你只需要写一个方法,方法名为add,如下 public String add(){ return "add"; }
这样就可以实现页面的跳转了,之后我们可以调用service一层层去调用BaceDao中的方法,实现增删改查,同时别忘了每个文件需要加上spring注解!
把值返回到页面上只需要ActionContext.getContext().put("对象名",对象名);之后从页面上使用s标签去获取就可以了
这样看来是不是很简单呢?