文章转载自:https://www.jiweichengzhu.com/article/d063714d7af04f699cd6779b498ae96d
如果还有问题,加群交流:686430774
案例代码下载,请移步原文链接!
SSH框架(struts + spring + hibernate),在spring没有出现之前用的非常多,最近整理以前的笔记,看到很早之前写的三大框架案例,重新整理了一下,来写一篇SSH框架的基础搭建教程,方便自己回忆,也帮助刚入行的新人们学习,由于是很早的笔记,框架的版本也稍微落后了一些,但是一些核心的理念还是没怎么变化,这里就懒得升级版本了。
数据库表见resources目录下的wolff.sql文件,项目结构也很简单,传统的MVC模式,struts充当控制器,spring负责容器的管理和事务托管,主要利用了它的ioc来解耦,hibernate提供orm映射机制,方便数据库操作,简化sql操作。
版本信息如下:
Struts版本:2.3.20
Spring版本:4.1.5.RELEASE
Hibernate版本:4.3.8.Final
工程目录如下:
结构没什么多说的,配置文件中一些难理解的地方,当时我都加上了注释,这次也没什么过多改动,力求言简意赅!
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <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"> <!-- spring配置 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <!-- 可以自己指定配置文件位置 --> <param-value>classpath:applicationContext.xml</param-value> <!-- <param-value>/WEB-INF/applicationContext.xml</param-value> --> </context-param> <!-- struts配置 --> <filter> <filter-name>struts</filter-name> <!--不同版本中配置的不一样,低版本中,filter-class配置就不是这个class类--> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>*.action</url-pattern> <!-- <url-pattern>/*</url-pattern> --> </filter-mapping> <!-- 默认页面 --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
这里需要注意一下filter的配置中的注释,filter-class需要注意版本信息,不同版本配置的是不一样的。
struts.xml:
截止到我当时做笔记的时候,struts总共有三种映射方式:
一对一映射:比较常见,每一个请求都需要在struts.xml中配置一个action,是早期的方式,非常麻烦;
DMI动态映射:利用感叹号动态映射,如:test!a.action就代表TestController中的a请求,官方不推荐使用;
通配符映射:利用花括号{}的方式进行匹配,不太好描述,大家看我上面配置文件中的注释;
applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <!--配置数据源,可以选择c3p0、druid等,这里直接使用spring的DataSource数据源--> <!--也可以选择在hibernate.cfg.xml中配置数据源,在这里为了事务的方便管理,将数据源交给spring管理--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true"/> <property name="username" value="test"/> <property name="password" value="111111"/> </bean> <!--hibernate的session工厂相关配置--> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!--指定数据源--> <property name="dataSource" ref="dataSource"/> <!--配置jdbc属性--> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.autoReconnect">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <!-- 引入映射文件,有两种方式:--> <!-- 1、直接将配置文件写在spring配置中 --> <!-- <property name="mappingResources"> <list> <value>sqlmap/Book.hbm.xml</value> <value>sqlmap/School.hbm.xml</value> <value>sqlmap/Student.hbm.xml</value> </list> </property> --> <!-- 2、引用外部配置文件,在hibernate配置文件中统一配置 --> <property name="configLocations"> <list> <value>classpath:hibernate.cfg.xml</value> </list> </property> </bean> <!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 模板,作为公用,调用是只需要加上parent属性指向这里,不然每个bean中都需要加上这些配置 --> <bean id="transactionalTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 引入事务管理器 --> <property name="transactionManager" ref="transactionManager"/> <!-- 配置事务的传播属性 --> <property name="transactionAttributes"> <props> <!-- 事务管理的方法、方式 --> <!-- 例如:add开头的方法 --> <!-- <prop key="add*">PROPAGATION_REQUIRED</prop> --> <!-- PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启。 --> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <!-- dao中注意,需要使用parent将相应的事务管理引入进来,因为每个dao都写一遍是不现实的,所以抽出公用 --> <!-- 使用xml方式注入时,这里的dao不是用接口方式不行? --> <bean id="schoolDao" parent="transactionalTemplate"> <property name="target"> <bean class="com.ssh.dao.impl.SchoolDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean> </property> </bean> <bean id="studentDao" parent="transactionalTemplate"> <property name="target"> <bean class="com.ssh.dao.impl.StudentDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean> </property> </bean> <bean id="bookDao" parent="transactionalTemplate"> <property name="target"> <bean class="com.ssh.dao.impl.BookDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean> </property> </bean> <!-- service中注意,需要使用property将相应的dao变量引入进来,否则注入为空 --> <bean id="schoolService" class="com.ssh.service.impl.SchoolServiceImpl"> <property name="schoolDao" ref="schoolDao"/> </bean> <bean id="studentService" class="com.ssh.service.impl.StudentServiceImpl"> <property name="studentDao" ref="studentDao"/> </bean> <bean id="bookService" class="com.ssh.service.impl.BookServiceImpl"> <property name="bookDao" ref="bookDao"/> </bean> </beans>
相对于SpringMVC来说,就是只保留了bean管理和事务两块二配置,也没什么多说的,配置方式跟现在也都一模一样。
hibernate.cfg.xml:
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- 如果没有直接在spring配置文件中集成相关映射文件,就需要在这里配置好,然后再引入到spring中 --> <hibernate-configuration> <session-factory> <!-- 如果么有使用spring托管数据源,就可以在这里进行配置--> <!-- <!– 指定连接数据库所用的驱动 –>--> <!-- <property name="connection.driver_class">com.mysql.jdbc.Driver</property>--> <!-- <!– 指定连接数据库的url,hibernate连接的数据库名 –>--> <!-- <property name="connection.url">jdbc:mysql://localhost/数据库名</property>--> <!-- <!– 指定连接数据库的用户名 –>--> <!-- <property name="connection.username">root</property>--> <!-- <!– 指定连接数据库的密码 –>--> <!-- <property name="connection.password">32147</property>--> <!-- <!– 指定数据库方言 –>--> <!-- <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>--> <!-- <!– 根据需要自动创建数据表 –>--> <!-- <property name="hbm2ddl.auto">update</property>--> <!-- <!– 显示Hibernate持久化操作所生成的SQL –>--> <!-- <property name="show_sql">true</property>--> <!-- <!– 将SQL脚本进行格式化后再输出 –>--> <!-- <property name="hibernate.format_sql">true</property>--> <!-- 下面是使用c3p0数据库进行数据源配置的样例--> <!-- <!– 指定连接池里最大连接数 –>--> <!-- <property name="hibernate.c3p0.max_size">20</property>--> <!-- <!– 指定连接池里最小连接数 –>--> <!-- <property name="hibernate.c3p0.min_size">1</property>--> <!-- <!– 指定连接池里连接的超时时长 –>--> <!-- <property name="hibernate.c3p0.timeout">5000</property>--> <!-- <!– 指定连接池里最大缓存多少个Statement对象 –>--> <!-- <property name="hibernate.c3p0.max_statements">100</property>--> <!-- <property name="hibernate.c3p0.idle_test_period">3000</property>--> <!-- <property name="hibernate.c3p0.acquire_increment">2</property>--> <!-- <property name="hibernate.c3p0.validate">true</property>--> <!-- 配置映射文件 --> <mapping resource="sqlmap/School.hbm.xml"/> <mapping resource="sqlmap/Student.hbm.xml"/> <mapping resource="sqlmap/Book.hbm.xml"/> </session-factory> </hibernate-configuration>
再看一个hibernate的映射文件:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.ssh.entity.Student" table="students"> <id name="id" type="java.lang.Integer"> <!-- scale表示小数位 --> <column name="id" precision="10" scale="0"/> <!-- 如果是oracle,则需要指定自增序列 --> <!-- class表示ID的属性,自增、关联另外表的主键等,在有对应关系时使用 --> <!-- <generator class="sequence">--> <!-- <param name="sequence">ZZ_STUDENTS</param>--> <!-- </generator>--> <!-- 主键生成策略: 1. identity : 主键自增.由数据库来维护主键值,录入时不需要指定主键值 2. sequence : Oracle中的主键生成策略 3. increment : 主键自增,由hibernate来维护,每次查询时会先查询数据库中的最大值,然后在最大值的基础上+1 4. hilo : 高低位算法,主键自增,由hibernate维护,开发时不使用 5. native : hilo+sequence+identity自动三选一 6. uuid : 产生随机字符串作为主键,主键类型必须为string类型 7. assigned : 自然主键生成策略 --> </id> <property name="name" type="java.lang.String"> <column name="student_name" length="50"/> </property> <property name="sex" type="java.lang.String"> <column name="student_sex" length="5"/> </property> <property name="age" type="java.lang.Integer"> <column name="student_age" precision="5" scale="0"/> </property> <property name="birthday" type="java.util.Date"> <column name="student_birthday"/> </property> <property name="hobby" type="java.lang.String"> <column name="student_hobby" length="100"/> </property> <!-- 与学校对应的关系 --> <!-- property-ref属性指定关联类的属性名,若不指定,默认关联主键 --> <!-- 外键一对一,相当于多对一的一种(注意加上unique='true'的限制保证唯一),严格意义上的一对一,是要求两个表主键都相同 --> <!-- 注意lazy表示延迟加载,false表示立即加载,但是这里不加会报错 --> <many-to-one name="school" column="school_id" unique="true" lazy="false"/> </class> </hibernate-mapping>
注意:表之间的对应关系是重点,一对多、多对一这种,一定要先将关系捋清楚,哪个是主哪个是从,找好关联的点在哪里。
由于代码中的注释写的比较齐全,这里不再过多赘述了,案例比较简单,就是CRUD,运行效果图: