Struts + Spring + Hibernate三者各自的特点都是什么?
Struts 的MVC设计模式可以使我们的逻辑变得很清晰,主要负责表示层的显示。
Spring 的IOC和AOP可以使我们的项目在最大限度上解藕。
hibernate的就是实体对象的持久化了, 数据库的封装。
表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。
表现层是传统的JSP技术。
中间层采用的是流行的Spring+Hibernate,为了将控制层与业务逻辑层分离,又细分为以下几种。
Web层,就是MVC模式里面的“C”(controller),负责控制业务逻辑层与表现层的交互,调用业务逻辑层,并将业务数据返回给表现层作组织表现,该系统的MVC框架采用Struts。
Service层(就是业务逻辑层),负责实现业务逻辑。业务逻辑层以DAO层为基础,通过对DAO组件的正面模式包装,完成系统所要求的业务逻辑。
DAO层,负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。
PO,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库。
Spring的作用贯穿了整个中间层,将Web层、Service层、DAO层及PO无缝整合,其数据服务层用来存放数据。
一个良好的框架可以让开发人员减轻重新建立解决复杂问题方案的负担和精力;它可以被扩展以进行内部的定制化;并且有强大的用户社区来支持它。框架通常能很好的解决一个问题。然而,你的应用是分层的,可能每一个层都需要各自的框架。
开始搭建SSH:
第一步:
用eclipse(开发工具)里创建web项目,注意勾选生产web.xml文件。
第二步:
导入项目需要的jar包
struts2:http://struts.apache.org/
因为这是个国外网站,所以访问的时候会慢,下载的时候也慢
Spring:spring-framework-4.3.2.RELEASE 这个官网不提供下载,大家可以百度下载,有很多网上的朋友都封装好了。
hibernate:https://sourceforge.net/projects/hibernate/files/latest/download?source=files 访问就提示下载
Struts2的jar包:
从下载的解压打开,apps 目录下解压打开,
WEB-INF 目录下,lib 目录下所有 jar 包导入项目。
Spring 的jar包:
从下载的解压打开,在从解压打开,把
,以"javadoc.jar"、"sources.jar"结尾的jar包不导入,其他的全部导入项目。因为是SSH框架,所以还要从刚刚Struts2中(刚刚下载的
中的lib里面)导入 commons-logging.jar 和 struts2-spring-plugin.jar
Hibernate的jar包:
从刚刚给的网址中下载解压打开,lib 目录下中的required 目录下所有的 jar 包 和 optional 目录下 c3p0 目录下所有的 jar 包。
注意:c3p0 :本文使用的数据库连接池,根据不同的连接池需要导不同的包
如果是dbcp,那么你可以去网上下载
第三步:
在配置文件web.xml中配置一个struts2的过滤器和spring监听器。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>ssh_001</display-name> <welcome-file-list> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- struts2过滤器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- spring监听器配置开始 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
第四步:
在Java Resources下的src目录下创建一个struts.xml文件
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
上面的头,注意版本,从样例里复制过来 showcase.war\\WEB-INF\\src\\java\\struts.xml
告知Struts2运行时使用Spring来创建对象就要加入一句:<constant name="struts.objectFactory" value="spring" />
当然也可以包括多个xml文件,让项目分工明确,减少各个人的代码冲突
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <!-- 上面的头,注意版本,从样例里复制过来 showcase.war\\WEB-INF\\src\\java\\struts.xml --> <struts> <!-- 第1步:先定义一个包 --> <package name="mypck001" extends="struts-default"> <!-- 第2步:定义一个action,配置跳转信息 name 类似于Servlet @WebServlet("/IndexServlet") http://xxxx/xxx/Index.action http://xxxx/xxx/Index class 对应于自己写的Action类 当不写method属性时,默认调用的是execute class="ssh.action.IndexAction" ** new ssh.action.IndexAction() 设计思想:关心了具体的实现类 必须改为不要关注那个实现类 加入spring后,struts的action节点的class属性意义发生变化, 直接引用spring帮忙创建的实例 --> <action name="Index" class="myIndexAction" method="execute1"> <!-- 跳转是forward /WEB-INF/是防止jsp不经过action就可以访问 --> <result name="success">/WEB-INF/jsp/index2.jsp</result> <result name="error">/WEB-INF/jsp/s_tag.jsp</result> </action> </package> </struts>
如果你是只是用stutrs,没有用spring,那么在action的class里自己写的Action类路径,
而这里用了spring
,就要去到appliCation.xml配置文件
而method属性里的方法名则是Action里的方法,当不写method属性时,默认调用的是execute。
result name="success"里的name就是action里对应方法的返回值进行请求转发跳转。
第五步:
在Java Resources下的src目录下创建四个包进行分层。
在ssh.action里创建一个IndexAction 继承ActionSupport
package ssh.action; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import ssh.dao.IndexDao; import ssh.dao.IndexDaoImpl; import ssh.entity.BookCard; import ssh.service.IndexService; import ssh.service.IndexServiceImpl; import ssh.util.MyConnection; public class IndexAction extends ActionSupport { //声明service,但不给它创建具体的实现类的实例, private IndexService is = null; public void setIs(IndexService is) { this.is = is; } public String execute1() { List<BookCard> myBookCardList = is.getAllBookCard(); System.out.println("结果集:"+myBookCardList.size()); ActionContext ac = ActionContext.getContext(); ac.put("myBookCardList", myBookCardList); return "success"; } public String formatDouble(double s){ DecimalFormat fmat=new DecimalFormat("\\u00A4##.0"); return fmat.format(s); } }
这就是spring注入:
为了解藕。
return "success" ActionContext ac = ActionContext.getContext(); ac.put("myBookCardList", myBookCardList); → → (跳转)<result name="success">/WEB-INF/jsp/index2.jsp</result>
第六步:
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 数据库连接配置 -->
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://localhost:1433;DatabaseName=CardDB</property>
<property name="connection.username">sa</property>
<property name="connection.password">123456</property>
<!-- 每个数据库都有1个,针对特定的关系型数据库生成优化的SQL -->
<property name="dialect">org.hibernate.dialect.SQLServer2008Dialect</property>
<!-- 设置默认的数据库连接池 -->
<property name="connection.pool_size">5</property>
<!-- 显示SQL -->
<property name="show_sql">true</property>
<!-- 格式化SQL -->
<property name="format_sql">true</property>
<!-- 根据schema更新数据表的工具 -->
<property name="hbm2ddl.auto">update</property>
<!-- 数据表映射配置文件 -->
<mapping resource="ssh/entity/BookCard.hbm.xml"/>
</session-factory>
</hibernate-configuration>
第七步:
appliCation.xml配置文件
将 hibernate.cfg.xml 文件内的信息写入到该文件中:<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!-- 引入外部属性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 类似于财务部门一样,类就是钱,所有需要类的实例都由srping去管理 --> <bean id="myIndexAction" class="ssh.action.IndexAction" scope="prototype"> <!-- setIs(myIndexService) --> <property name="is" ref="myIndexService"/> </bean> <!-- myIndexService = new ssh.service.IndexServiceImpl() --> <bean id="myIndexService" class="ssh.service.IndexServiceImpl" scope="prototype"> <property name="id" ref="myIndexDao"/> </bean> <bean id="myIndexDao" class="ssh.dao.IndexDaoImpl" scope="prototype"> <!-- 晚点再注入能用的seesionFactory --> <property name="sessionFactory" ref="mySessionFactory"></property> </bean> <!-- 错误的做法,new org.hibernate.internal.SessionFactoryImpl() 不可以,需要configuration来创建 bean id="mySessionFactory" class="org.hibernate.internal.SessionFactoryImpl"></bean --> <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- 注入连接池,包含了数据库用户名,密码等等信息 --> <property name="dataSource" ref="myDataSource"/> <!-- 配置Hibernate的其他的属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.mysql5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.connection.autocommit">false</prop> <!-- 开机自动生成表 --> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <property name="mappingResources"> <list> <value>ssh/entity/BookCard.hbm.xml</value> </list> </property> </bean> <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> <!-- 每300秒检查所有连接池中的空闲连接 --> <property name="idleConnectionTestPeriod" value="300"></property> <!-- 最大空闲时间,900秒内未使用则连接被丢弃。若为0则永不丢弃 --> <property name="maxIdleTime" value="900"></property> <!-- 最大连接数 --> <property name="maxPoolSize" value="2"></property> </bean> </beans>
<bean id="myIndexAction" class="ssh.action.IndexAction" scope="prototype"> <!-- setIs(myIndexService) --> <property name="is" ref="myIndexService"/> </bean>
id="myIndexAction" 实例化对象的名字
class="ssh.action.IndexAction" 实例化对象的路径(包名类名)
scope="prototype" 非单例
name="is" 实例化对象里面属性的名字
ref="myIndexService" 引用
jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver 数据库驱动
jdbc.url=jdbc:mysql://localhost:3306/CardDB 连接数据库url
jdbc.user=root 用户名
jdbc.password=123456 密码
左边这些是连接数据库的信息