Spring学习笔记(马士兵spring视频笔记)
课程内容
1. 面向接口(抽象)编程的概念与好处
2. IOC/DI的概念与好处
a) inversion of control
b) dependency injection
3. AOP的概念与好处
4. Spring简介
5. Spring应用IOC/DI(重要)
a) xml
b) annotation
6. Spring应用AOP(重要)
a) xml
b) annotation
7. Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2整合(重要)
a) opensessionInviewfilter(记住,解决什么问题,怎么解决)
8. Spring JDBC
面向接口编程(面向抽象编程)
1. 场景:用户添加
2. Spring_0100_AbstractOrientedProgramming
a) 不是AOP:Aspect Oriented Programming
3. 好处:灵活
什么是IOC(DI),有什么好处
1. 把自己new的东西改为由容器提供
a) 初始化具体值
b) 装配
2. 好处:灵活装配
Spring简介
1. 项目名称:Spring_0200_IOC_Introduction
2. 环境搭建
a) 只用IOC
i. spring.jar , jarkata-commons/commons-loggin.jar
3. IOC容器
a) 实例化具体bean
b) 动态装配
4. AOP支持
a) 安全检查
b) 管理transaction
Spring IOC配置与应用
1. FAQ:不给提示:
a) window – preferences – myeclipse – xml – xml catalog
b) User Specified Entries – add
i. Location: D:\share\0900_Spring\soft\spring-framework-2.5.6\dist\resources\spring-beans-2.5.xsd
ii. URI: file:///D:/share/0900_Spring/soft/spring-framework-2.5.6/dist/resources/spring-beans-2.5.xsd
iii. Key Type: Schema Location
iv. Key: http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
2. 注入类型
a) Spring_0300_IOC_Injection_Type
b) setter(重要)
c) 构造方法(可以忘记)
d) 接口注入(可以忘记)
3. id vs. name
a) Spring_0400_IOC_Id_Name
b) name可以用特殊字符 <bean id/name="u" class="com.bjsxt.dao.impl.UserDAOImpl">
4. 简单属性的注入
a) Spring_0500_IOC_SimpleProperty
b) <property name=… value=….>
(因为是基础数据类型,其实我们自己写很少遇到这样的, 但Spring整合自己时,可以用到)
5. <bean 中的scope属性
a) Spring_0600_IOC_Bean_Scope
b) singleton 单例
c) proptotype 每次创建新的对象
6. 集合注入
a) Spring_0700_IOC_Collections
b) 很少用,不重要!参考程序
7. 自动装配
a) Spring_0800_IOC_AutoWire
b) byName
c) byType
d) 如果所有的bean都用同一种,可以使用beans的属性:default-autowire
8. 生命周期
a) Spring_0900_IOC_Life_Cycle
b) lazy-init (不重要)
c) init-method destroy-methd 不要和prototype一起用(了解)
9. Annotation第一步:
a) 修改xml文件,参考文档<context:annotation-config />
10. @Autowired
a) 默认按类型by type
b) 如果想用byName,使用@Qulifier
c) 写在private field(第三种注入形式)(不建议,破坏封装)
d) 如果写在set上,@qualifier需要写在参数上
11. @Resource(重要)
a) 加入:j2ee/common-annotations.jar
b) 默认按名称,名称找不到,按类型
c) 可以指定特定名称
d) 推荐使用
e) 不足:如果没有源码,就无法运用annotation,只能使用xml
12. @Component @Service @Controller @Repository
a) 初始化的名字默认为类名首字母小写
b) 可以指定初始化bean的名字
13. @Scope
14. @PostConstruct = init-method; @PreDestroy = destroy-method;
什么是AOP
1. 面向切面编程Aspect-Oriented-Programming
a) 是对面向对象的思维方式的有力补充
2. Spring_1400_AOP_Introduction
3. 好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码
a) Filter
b) Struts2的interceptor
4. 概念:
a) JoinPoint 释意:切面与原方法交接点 即 切入点
b) PointCut 释意:切入点集合
c) Aspect(切面)释意:可理解为代理类前说明
d) Advice 释意:可理解为代理方法前说明 例如@Before
e) Target 释意:被代理对象 被织入对象
f) Weave 释意:织入
Spring AOP配置与应用
1. 两种方式:
a) 使用Annotation
b) 使用xml
2. Annotation
a) 加上对应的xsd文件spring-aop.xsd
b) beans.xml <aop:aspectj-autoproxy />
c) 此时就可以解析对应的Annotation了
d) 建立我们的拦截类
e) 用@Aspect注解这个类
f) 建立处理方法
g) 用@Before来注解方法
h) 写明白切入点(execution …….)
i) 让spring对我们的拦截器类进行管理@Component
3. 常见的Annotation:
a) @Pointcut 切入点声明 以供其他方法使用 , 例子如下:
@Aspect
@Component
public class LogInterceptor {
@Pointcut("execution(public * com.bjsxt.dao..*.*(..))")
public void myMethod(){}
@Around("myMethod()")
public void before(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("method before");
pjp.proceed();
}
@AfterReturning("myMethod()")
public void afterReturning() throws Throwable{
System.out.println("method afterReturning");
}
@After("myMethod()")
public void afterFinily() throws Throwable{
System.out.println("method end");
}
}
b) @Before 发放执行之前织入
c) @AfterReturning 方法正常执行完返回之后织入(无异常)
d) @AfterThrowing 方法抛出异常后织入
e) @After 类似异常的finally
f) @Around 环绕 类似filter , 如需继续往下执行则需要像filter中执行FilterChain.doFilter(..)对象一样 执行 ProceedingJoinPoint.proceed()方可,例子如下:
@Around("execution(* com.bjsxt.dao..*.*(..))")
public void before(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("method start");
pjp.proceed();//类似FilterChain.doFilter(..)告诉jvm继续向下执行
}
4. 织入点语法
a) void !void
b) 参考文档(* ..)
如果 execution(* com.bjsxt.dao..*.*(..))中声明的方法不是接口实现 则无法使用AOP实现动态代理,此时可引入包” cglib-nodep-2.1_3.jar” 后有spring自动将普通类在jvm中编译为接口实现类,从而打到可正常使用AOP的目的.
5. xml配置AOP
a) 把interceptor对象初始化
b) <aop:config
i. <aop:aspect …..
1. <aop:pointcut
2. <aop:before
例子:
<bean id="logInterceptor" class="com.bjsxt.aop.LogInterceptor"></bean>
<aop:config>
<!-- 配置一个切面 -->
<aop:aspect id="point" ref="logInterceptor">
<!-- 配置切入点,指定切入点表达式 -->
<!-- 此句也可放到 aop:aspect标签外 依然有效-->
<aop:pointcut
expression=
"execution(public * com.bjsxt.service..*.*(..))"
id="myMethod" />
<!-- 应用前置通知 -->
<aop:before method="before" pointcut-ref="myMethod" />
<!-- 应用环绕通知 需指定向下进行 -->
<aop:around method="around" pointcut-ref="myMethod" />
<!-- 应用后通知 -->
<aop:after-returning method="afterReturning"
pointcut-ref="myMethod" />
<!-- 应用抛出异常后通知 -->
<aop:after-throwing method="afterThrowing"
pointcut-ref="myMethod" />
<!-- 应用最终通知 -->
<aop:after method="afterFinily"
pointcut="execution(public * om.bjsxt.service..*.*(..))" />
</aop:aspect>
</aop:config>
Spring整合Hibernate
1. Spring 指定datasource
a) 参考文档,找dbcp.BasicDataSource
i. c3p0
ii. dbcp
iii. proxool
b) 在DAO或者Service中注入dataSource
c) 在Spring中可以使用PropertyPlaceHolderConfigure来读取Properties文件的内容
2. Spring整合Hibernate
a) <bean .. AnnotationSessionFactoryBean>
i. <property dataSource
ii. <annotatedClasses
b) 引入hibernate 系列jar包
c) User上加Annotation
d) UserDAO或者UserServie 注入SessionFactory
e) jar包问题一个一个解决
3. 声明式的事务管理
a) 事务加在DAO层还是Service层?
b) annotation
i. 加入annotation.xsd
ii. 加入txManager bean
iii. <tx:annotation-driven
例如: <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
iv. 在需要事务的方法上加:@Transactional
v. 需要注意,Hibernate获得session时要使用SessionFactory.getCurrentSession 不能使用OpenSession
c) @Transactional详解
i. 什么时候rollback
1. 运行期异常,非运行期异常不会触发rollback
2. 必须uncheck (没有catch)
3. 不管什么异常,只要你catch了,spring就会放弃管理
4. 事务传播特性:propagation_required
例如: @Transactional(propagation=Propagation.REQUIRED)等同于(@Transactional)
作用,一个方法声明了@Transactional事务后,其内再调用的方法不需要再声明@Transactional.
5. read_only
例如: @Transactional(propagation=Propagation.REQUIRED,readOnly=true)
当方法声明readOnly=true时,该方法及其调用的方法内都不执行insert update等
d) xml(推荐,可以同时配置好多方法)
i. <bean txmanager
ii. <aop:config
1. <aop:pointcut
2. <aop:advisor pointcut-ref advice-ref
iii. <tx:advice: id transaction-manager =
iv. <property name="packagesToScan"> 可定义扫描目标包下所有实体类
例如: <bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<!--
<property name="annotatedClasses">
<list>
<value>com.bjsxt.model.TestUser</value>
<value>com.bjsxt.model.Log</value>
</list>
</property>
-->
<!-- 将参数名称设为packagesToScan 可定义扫描目标包下所有实体类 -->
<property name="packagesToScan">
<list>
<value>com.bjsxt.model</value>
</list>
</property>
</bean>
//事务管理@transactional的注入
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
//定义字符串“execution()”为一个变量名,简化
<aop:config>
<aop:pointcut
expression="execution(public * com.bjsxt.service..*.*(..))"
id="myServiceMethod" />
<aop:advisor pointcut-ref="myServiceMethod" advice-ref="txAdvice"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="cancel*" propagation="REQUIRED" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
e) HibernateTemplate、HibernateCallback、HibernateDaoSupport(不重要)介绍
i. 设计模式:Template Method(模板方法)
ii. Callback:回调/钩子函数
iii. 第一种:(建议)
1. 在spring中初始化HibernateTemplate,注入sessionFactory
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
2. DAO里注入HibernateTemplate
private HibernateTemplate hibernateTemplate;
@Resource
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
3. save写getHibernateTemplate.save();
public void save(TestUser testUser) {
hibernateTemplate.save(testUser);
}
iv. 第二种:
1. 从HibernateDaoSupport继承(此方法不好用 可忽略)
2. 必须写在xml文件中,无法使用Annotation,因为set方法在父类中,而且是final的
例如:
首先,新建SuperDAOImpl类(使用Annotation注入--@Component):
@Component
public class SuperDAOImpl {
private HibernateTemplate hibernateTemplate; //此处定义由spring注入管理
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
@Resource
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
}
此时,xml中必须要有:
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
或者,SuperDAOImpl类写成下面代码:
@Component
public class SuperDAOImpl extends HibernateDaoSupport {
@Resource(name="sessionFactory")
public void setSuperHibernateTemplate(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
}
对应的xml中则可省略
<bean id="hibernateTemplate"………部分
只要包含
<bean id="sessionFactory"……..部分即可
最后,其他类继承SuperDaoImpl类后便可直接使用HibernateTemplate
@Component("u")
public class UserDAOImpl extends SuperDAOImpl implements UserDAO {
public void save(TestUser testUser) {
this.getHibernateTemplate().save(testUser);
}
}
f) spring整合hibernate的时候使用packagesToScan属性,可以让spring自动扫描对应包下面的实体类
Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2
1. 需要的jar包列表
jar包名称 |
所在位置 |
说明 |
antlr-2.7.6.jar |
hibernate/lib/required |
解析HQL |
aspectjrt |
spring/lib/aspectj |
AOP |
aspectjweaver |
.. |
AOP |
cglib-nodep-2.1_3.jar |
spring/lib/cglib |
代理,二进制增强 |
common-annotations.jar |
spring/lib/j2ee |
@Resource |
commons-collections-3.1.jar |
hibernate/lib/required |
集合框架 |
commons-fileupload-1.2.1.jar |
struts/lib |
struts |
commons-io-1.3.2 |
struts/lib |
struts |
commons-logging-1.1.1 |
单独下载,删除1.0.4(struts/lib) |
struts spring |
dom4j-1.6.1.jar |
hibernate/required |
解析xml |
ejb3-persistence |
hibernate-annotation/lib |
@Entity |
freemarker-2.3.13 |
struts/lib |
struts |
hibernate3.jar |
hibernate |
|
hibernate-annotations |
hibernate-annotation/ |
|
hibernate-common-annotations |
hibernate-annotation/lib |
|
javassist-3.9.0.GA.jar |
hiberante/lib/required |
hibernate |
jta-1.1.jar |
.. |
hibernate transaction |
junit4.5 |
|
|
mysql- |
|
|
ognl-2.6.11.jar |
struts/lib |
|
slf4j-api-1.5.8.jar |
hibernate/lib/required |
hibernate-log |
slf4j-nop-1.5.8.jar |
hibernate/lib/required |
|
spring.jar |
spring/dist |
|
struts2-core-2.1.6.jar |
struts/lib |
|
xwork-2.1.2.jar |
struts/lib |
struts2 |
commons-dbcp |
spring/lib/jarkata-commons |
|
commons-pool.jar |
.. |
|
struts2-spring-plugin-2.1.6.jar |
struts/lib |
|
2. BestPractice:
a) 将这些所有的jar包保存到一个位置,使用的时候直接copy
3. 步骤
a) 加入jar包
b) 首先整合Spring + Hibernate
i. 建立对应的package
1. dao / dao.impl / model / service / service.impl/ test
ii. 建立对应的接口与类框架
1. S2SH_01
iii. 建立spring的配置文件(建议自己保留一份经常使用的配置文件,以后用到的时候直接copy改)
iv. 建立数据库
v. 加入Hibernate注解
1. 在实体类上加相应注解@Entity @Id等
在字段属性的get方法上加--@Column(name = "表字段名")
2. 在beans配置文件配置对应的实体类,使之受管
vi. 写dao service的实现
vii. 加入Spring注解
1. 在对应Service及DAO实现中加入@Component,让spring对其初始化
2. 在Service上加入@Transactional或者使用xml方式(此处建议后者,因为更简单)
3. 在DAO中注入sessionFactory
4. 在Service中注入DAO
5. 写DAO与Service的实现
viii. 写测试
c) 整合Struts2
i. 结合点:Struts2的Action由Spring产生
ii. 步骤:
1. 修改web.xml加入 struts的filter
如下:
<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>
2. 再加入spring的listener,这样的话,webapp一旦启动,spring容器就初始化了
如下:
<!-- 指定由spring初始化加载xml配置文件 spring与struts结合必备 -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
<!-- 默认寻找xml路径:WEB-INF/applicationContext.xml -->
</listener-class>
</listener>
<!--整个应用的参数 服务启动时读取.
可指定spring初始化文件路径位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring/*applicationContext.xml
</param-value>
</context-param>
3. 规划struts的action和jsp展现
4. 加入struts.xml
a) 修改配置,由spring替代struts产生Action对象
5. 修改action配置
a) 把类名改为bean对象的名称,这个时候就可以使用首字母小写了
b) @Scope(“prototype”)不要忘记
iii. struts的读常量:
1. struts-default.xml
2. struts-plugin.xml
3. struts.xml
4. struts.properties
5. web.xml
iv. 中文问题:
1. Struts2.1.8已经修正,只需要改i18n.encoding = gbk
2. 使用spring的characterencoding
例:
<!-- 过滤器相关配置 ======== 字符编码过滤======== -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
3. 需要严格注意filter的顺序
4. 需要加到Struts2的filter前面
v. LazyInitializationException
1. OpenSessionInViewFilter
2. 需要严格顺序问题
3. 需要加到struts2的filter前面
附:
1.
@Autowired 与@Resource 都可以用来装配bean. 都可以写在属性定义上,或写在set方法上
@Autowired (srping提供的) 默认按类型装配
@Resource ( j2ee提供的 ) 默认按名称装配,当找不到(不写name属性)名称匹配的bean再按类型装配.
可以通过@Resource(name="beanName") 指定被注入的bean的名称, 要是指定了name属性, 就用 字段名 去做name属性值,一般不用写name属性.
@Resource(name="beanName")指定了name属性,按名称注入但没找到bean, 就不会再按类型装配了.
@Autowired 与@Resource可作用在属性定义上, 就不用写set方法了(此方法不提倡);
2.
a.
Action类前加@Component,则Action可由spring来管理,例子如下:
Action中写:
@Component("u") //spring管理注解
@Scope("prototype") //多态
public class UserAction extends ActionSupport implements ModelDriven{
//内部属性需要有get/set方法 且需要set方法前加@Resource或@Autowired
}
Struts2配置文件中写
<action name="u" class="u">
Jsp中
<form method="post" action="u.do" >
b.
Action中也可不加@Component,Action由struts2-spring-plugin管理。此时,如果Action中定义的属性有set方法 则@Autowired 与@Resource也可不写,但是如果没有set方法,则需要在属性前加上@Autowired 或@Resource才能生效。
3.
Hibernate如果使用load来查询数据,例如:
Service中:
public User loadById(int id) {
return this.userDao.loadById(id);
}
DAO中:
public User loadById(int id) {
return (User)this.hibernateTemplate.load(User.class, id);
}
此时,session(应该说的是Hibernate的session)在事物结束(通常是service调用完)后自动关闭。由于使用的是load获取数据,在jsp页面申请取得数据时才真正的执行sql,而此时session已经关闭,故报错。
Session关闭解决方法:
在web.xml中增加filter—openSessionInView,用于延长session在jsp调用完后再关闭
如下所示:
注意:filter –openSessionInView 一定要在 filter—struts2之前调用
Filter顺序—先进后出!
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sf</param-value>(此处默认指定的sessionFactory应为” sessionFactory” 默认可省略此行 如果shring配置文件中配置的sessionFactory为”sf” 则此处需要写sf 一般用不到)
</init-param>
</filter>
<filter-mapping>
<filter-name> OpenSessionInViewFilter </filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
1、导入29个JAR包
JAR包名称 |
作用 |
Struts2.1.6(7个) |
|
struts2-core-2.1.6.jar |
struts2开发的核心类库 |
freemarker-2.3.13.jar |
struts2的UI标签的模板使用freemarker编写 |
commons-logging-1.0.4.jar |
ASF出的日志包,支持Log4J和JDK的日志记录 |
ognl-2.6.11.jar |
对象图导航语言,通过它来读写对象属性 |
xwork-2.1.2.jar |
xwork类库,struts2在其上进行构建 |
commons-fileupload-1.2.1.jar |
文件上传组件,2.1.6版本后必须加入此jar包 |
commons-io-1.3.2.jar |
以后文件上传下载需要 |
|
|
Hibernate3.3.2(13个) |
|
hibernate3.jar |
hibernate3开发的核心类库 |
antlr-2.7.6.jar |
解析HQL |
commons-collections-3.1.jar |
集合框架 |
dom4j-1.6.1.jar |
解析xml |
javassist-3.9.0.GA.jar |
|
jta-1.1.jar |
|
junit-4.8.1.jar |
Junit test 包 |
ejb3-persistence.jar |
@Entity |
Hibernate-annotations.jar |
|
Hibernate-commons-annotations.jar |
|
log4j-1.2.15.jar |
是log4j实现类 |
slf4j-api-1.5.8.jar |
标准接口 |
slf4j-log4j12-1.5.8.jar |
是slf4j转换log4j的中间接口 |
|
|
Spring 2.5.6(8个) |
|
spring.jar |
Spring核心文件 |
common-annotations.jar |
IOC支持, 例如@resource |
aspectjrt.jar |
AOP支持:aspectj运行时候需要的 |
aspectjweaver.jar |
AOP支持:织入 |
cglib-nodep-2.1_3.jar |
动态生成字节码 |
Commons-dbcp.jar |
数据源 |
commons-po ol.jar |
数据源 |
struts2-spring-plugin-2.1.6.jar |
Struts2和Spring结合所需包 |
|
|
commons-logging-1.0.4.jar |
Struts2加入了就不需要导入 |
log4j-1.2.15.jar |
Hibernate加入了就不需要导入 |
|
|
数据库包(1个) |
|
mysql-connector-java-3.1.10-bin.jar |
MySql的驱动程序
|
2、导入框架的配置文件
SRC目录下的配置文件 |
|
log4j.properties |
log4j的配置文件,放到SRC根目录下 |
hibernate.cfg.xml |
Hibernate的配置文件 |
beans.xml |
Spring的配置文件 |
struts.xml |
Struts的配置文件 |
|
|
WEB-INF下配置文件 |
|
web.xml |
Struts2和Spring的结合配置 |
PS:如果需要使用JSTL标签需要导入2个包
jstl.jar
standard.jar
3、建立对应的package和对应的接口与类框架
hibernate.cfg.xml
Xml代码
<?xml version='1.0' encoding='GBK'?>
1. <!DOCTYPE hibernate-configuration PUBLIC
2. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
3. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
4. <hibernate-configuration>
5.
6. <session-factory>
7.
8. <!-- MySQL数据库连接设置.端口号不用改。只需修改XXXX-->
9. <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
10. <property name="connection.url">jdbc:mysql://localhost:3306/ssh</property>
11. <property name="connection.username">root</property>
12. <property name="connection.password">lee</property>
13.
14. <!-- 一般不用HIBERNATE的连接池
15. <property name="connection.pool_size">1</property>
16. -->
17.
18. <!-- 指定用哪种数据库语言,查文档搜索dialect -->
19. <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
20. <!--<property name="dialect">org.hibernate.dialect.SQLServerDialect</property> -->
21.
22. <!-- 当前SESSION运行环境的上下文getCurrentSession对应的配置-thread线程。JTA是分布式管理,例如多个数据库-->
23. <property name="current_session_context_class">thread</property>
24.
25. <!-- Disable the second-level cache -->
26. <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
27.
28. <!-- 打印自动生成的SQL语句-->
29. <property name="show_sql">true</property>
30.
31. <!-- 格式化SQL语句
32. <property name="format_sql">true</property>-->
33.
34. <!-- 如果不存在表,自动在数据库里生成,常用的是create,update-->
35. <property name="hbm2ddl.auto">update</property>
36.
37. <!-- 定义需要映射的路径
38. <mapping class="ssh.model.User"/>
39. -->
40.
41. </session-factory>
42. </hibernate-configuration>
beans:xml
1. <?xml version="1.0" encoding="GBK"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xmlns:context="http://www.springframework.org/schema/context"
5. xmlns:aop="http://www.springframework.org/schema/aop"
6. xmlns:tx="http://www.springframework.org/schema/tx"
7. xsi:schemaLocation="http://www.springframework.org/schema/beans
8. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
9. http://www.springframework.org/schema/context
10. http://www.springframework.org/schema/context/spring-context-2.5.xsd
11. http://www.springframework.org/schema/aop
12. http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
13. http://www.springframework.org/schema/tx
14. http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
15. <!--使用Annotation-->
16. <context:annotation-config />
17.
18. <!--自动扫描com.bjsxt包下所有写了@Component的类注入进来-->
19. <context:component-scan base-package="ssh" />
20.
21. <!--AOP:扫描上面定义自动扫描的路径com.bjsxt目录下的文件,就可以用@Aspect定义切入类-->
22. <aop:aspectj-autoproxy />
23.
24.
25. <!--==========================定义数据源==========================-->
26. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
27. <property name="driverClassName" value="com.mysql.jdbc.Driver" />
28. <property name="url" value="jdbc:mysql://localhost:3306/ssh" />
29. <property name="username" value="root" />
30. <property name="password" value="lee" />
31. </bean>
32.
33.
34. <!--=======================定义sessionFactory====================-->
35. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
36. <property name="dataSource" ref="dataSource" />
37.
38. <!-- 将参数名称设为packagesToScan 可定义扫描目标包下所有实体类,告诉sessionFactory哪些类被Entity和注解了 -->
39. <property name="packagesToScan">
40. <list>
41. <value>ssh.model</value>
42. </list>
43. </property>
44.
45. <!--直接导入Hibernate的配置文件。这样才能自动建立数据库表和显示DDL语句。如果上面的配置只能先手动建立数据表然后更新。不能自动创建表-->
46. <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
47. </bean>
48.
49. <!--====================定义Hibernate事务管理器===================-->
50. <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
51. <property name="sessionFactory" ref="sessionFactory" />
52. </bean>
53.
54. <!--<aop:advisor 是定义事务的建议,pointcut-ref是上面pointcut的ID,advice-ref是单独的advice,是下面定义的 <tx:advice id="txAdvice" -->
55. <aop:config>
56. <aop:pointcut id="myServiceMethod" expression="execution(public * ssh.service..*.*(..))" />
57. <aop:advisor pointcut-ref="myServiceMethod" advice-ref="txAdvice"/>
58. </aop:config>
59.
60. <!--定义建议(事务),供<aop:advisor的advice-ref引用,transaction-manager=" txManager "引用的是上面定义的事务管理器<bean id="txManager"。 propagation="REQUIRED"可以省略,默认是这个-->
61. <tx:advice id="txAdvice" transaction-manager="txManager">
62. <tx:attributes>
63. <tx:method name="add*" propagation="REQUIRED"/>
64. <!--
65. <tx:method name="exists" read-only="true" />
66. -->
67. </tx:attributes>
68. </tx:advice>
69.
70.
71. <!--=========================定义HibernateTemplate===================-->
72. <!--定义后在DAO里注入HibernateTemplate(private HibernateTemplate hibernateTemplate;在其Set方法上加@Resource注入),hibernateTemplate里面直接由save、update、delete、load等方法,可以直接hibernateTemplate.save(testUser);-->
73.
74. <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
75. <property name="sessionFactory" ref="sessionFactory"></property>
76. </bean>
77.
78. </beans>
struts.xml
1. <?xml version="1.0" encoding="GBK" ?>
2. <!DOCTYPE struts PUBLIC
3. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
4. "http://struts.apache.org/dtds/struts-2.0.dtd">
5.
6. <struts>
7. <constant name="struts.devMode" value="true" />
8. <package name="default" namespace="/" extends="struts-default">
9. <action name="index" class="mstx.action.UserAction">
10. <result name="success">/index.jsp</result>
11. </action>
12. <action name="user" class="mstx.action.UserAction" method="save">
13. <result name="success">/success.jsp</result>
14. </action>
15.
16. </package>
17.
18. </struts>
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="index" class="mstx.action.UserAction">
<result name="success">/index.jsp</result>
</action>
<action name="user" class="mstx.action.UserAction" method="save">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
web.xml
1. <?xml version="1.0" encoding="UTF-8"?>
2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6. <welcome-file-list>
7. <welcome-file>index.jsp</welcome-file>
8. </welcome-file-list>
9.
10. <listener>
11. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
12. <!-- default: /WEB-INF/applicationContext.xml -->
13. </listener>
14.
15. <context-param>
16. <param-name>contextConfigLocation</param-name>
17. <!-- <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value> -->
18. <param-value>classpath:beans.xml</param-value>
19. </context-param>
20.
21.
22. <!--中文问题
23. 1. Struts2.1.8已经修正,只需要改Struts.xml的i18n.encoding = gbk
24. 2. 使用spring的characterencoding
25. -->
26. <filter>
27. <filter-name>encodingFilter</filter-name>
28. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
29. <init-param>
30. <param-name>encoding</param-name>
31. <param-value>GBK</param-value>
32. </init-param>
33. </filter>
34.
35. <filter-mapping>
36. <filter-name>encodingFilter</filter-name>
37. <url-pattern>/*</url-pattern>
38. </filter-mapping>
39.
40.
41. <!--openSessionInView
42. 此时,session(应该说的是Hibernate的session)在事物结束(通常是service调用完)后自动关闭。由于使用的是load获取数据,在jsp页面申请取得数据时才真正的执行sql,而此时session已经关闭,故报错。
43. Session关闭解决方法:
44. 在web.xml中增加filter—openSessionInView,用于延长session在jsp调用完后再关闭
45.
46. -->
47. <filter>
48. <filter-name>openSessionInView</filter-name>
49. <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
50. </filter>
51.
52. <filter-mapping>
53. <filter-name>openSessionInView</filter-name>
54. <url-pattern>/*</url-pattern>
55. </filter-mapping>
56.
57. <filter>
58. <filter-name>struts2</filter-name>
59. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
60. </filter>
61.
62. <filter-mapping>
63. <filter-name>struts2</filter-name>
64. <url-pattern>/*</url-pattern>
65. </filter-mapping>
66.
67. </web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
<!-- default: /WEB-INF/applicationContext.xml -->
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value> -->
<param-value>classpath:beans.xml</param-value>
</context-param>
<!--中文问题
1. Struts2.1.8已经修正,只需要改Struts.xml的i18n.encoding = gbk
2. 使用spring的characterencoding
-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--openSessionInView
此时,session(应该说的是Hibernate的session)在事物结束(通常是service调用完)后自动关闭。由于使用的是load获取数据,在jsp页面申请取得数据时才真正的执行sql,而此时session已经关闭,故报错。
Session关闭解决方法:
在web.xml中增加filter—openSessionInView,用于延长session在jsp调用完后再关闭
-->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
</web-app>
4、建立实体类,并加入Hibernate的注解
1)在实体类上加相应注解@Entity @Id等
2)在字段属性的get方法上加--@Column(name = "表字段名")
User.java
5、定义工具类
1)定义查询返回结果
QueryResult.java
1. package ssh.utils;
2.
3. import java.util.List;
4.
5. /*
6. * 定义查询返回的结果,泛型定义在类上
7. */
8. public class QueryResult<T> {
9. private List<T> resultlist; //记录查询的结果
10. private long totalrecord; //记录查询得到的总条数
11.
12. public List<T> getResultlist() {
13. return resultlist;
14. }
15. public void setResultlist(List<T> resultlist) {
16. this.resultlist = resultlist;
17. }
18. public long getTotalrecord() {
19. return totalrecord;
20. }
21. public void setTotalrecord(long totalrecord) {
22. this.totalrecord = totalrecord;
23. }
24. }
package ssh.utils;
import java.util.List;
/*
* 定义查询返回的结果,泛型定义在类上
*/
public class QueryResult<T> {
private List<T> resultlist; //记录查询的结果
private long totalrecord; //记录查询得到的总条数
public List<T> getResultlist() {
return resultlist;
}
public void setResultlist(List<T> resultlist) {
this.resultlist = resultlist;
}
public long getTotalrecord() {
return totalrecord;
}
public void setTotalrecord(long totalrecord) {
this.totalrecord = totalrecord;
}
}
2)定义分页工具类
PageView.java
1. package ssh.utils;
2.
3. import java.util.List;
4.
5. /**
6. * 在Action里的调用方法
7. //这里必须要构造新对象,不然刚打开没有currentPage参数传递过来,如果不新建也行,第一次打开必须传递currentPage参数过来
8. private PageView<T>pageView=new PageView<T>();
9.
10. public PageView<T> getPageView() {
11. return pageView;
12. }
13.
14. public void setPageView(PageView<T> pageView) {
15. this.pageView = pageView;
16. }
17. int maxresult=1;
18. int firstindex=(pageView.getCurrentPage()-1)*maxresult;
19. QueryResult<T> Service.getScrollData(firstindex,maxresult, null, null, null);
20. pageView.setQueryResult(maxresult,qr);
21. request.put("pageView", pageView);
22. */
23.
24. public class PageView<T> {
25. /** 分页数据 **/
26. private List<T> records;
27.
28. /** 页码开始索引 ,例如显示第1 2 3 4 5 6 7 8 9 ,开始索引为1 **/
29. private long startIndex;
30.
31. /** 页码结束索引 ,例如显示第1 2 3 4 5 6 7 8 9 ,结束索引为9 **/
32. private long endIndex;
33.
34. /** 总页数 ,没有0页,所以设置默认值为1 **/
35. private long totalPage = 1;
36.
37. /** 每页显示记录数 **/
38. private int maxResult = 10;
39.
40. /** 当前页 **/
41. private int currentPage = 1;
42.
43. /** 总记录数 **/
44. private long totalRecord;
45.
46. /** 工具条上显示的页码数量 **/
47. private int pageBarSize = 8;
48.
49.
50. // 这只方法触发记录查询结果和总条数
51. public void setQueryResult(int maxResult,QueryResult<T> qr) {
52. this.maxResult = maxResult;
53. this.records = qr.getResultlist();
54. this.totalRecord = qr.getTotalrecord();
55. this.totalPage = this.totalRecord % this.maxResult == 0 ? this.totalRecord/ this.maxResult : this.totalRecord / this.maxResult + 1;
56.
57. /*****************************************************/
58. this.startIndex = currentPage - (pageBarSize % 2 == 0 ? pageBarSize / 2 - 1 : pageBarSize / 2);
59. this.endIndex = currentPage + pageBarSize / 2;
60.
61. if (startIndex < 1) {
62. startIndex = 1;
63. if (totalPage >= pageBarSize)
64. endIndex = pageBarSize;
65. else
66. endIndex = totalPage;
67. }
68. if (endIndex > totalPage) {
69. endIndex = totalPage;
70. if ((endIndex - pageBarSize) > 0)
71. startIndex = endIndex - pageBarSize +1; //最后一页显示多小条页
72. else
73. startIndex = 1;
74. }
75. }
76.
77. public List<T> getRecords() {
78. return records;
79. }
80.
81. public void setRecords(List<T> records) {
82. this.records = records;
83. }
84.
85. public long getStartIndex() {
86. return startIndex;
87. }
88.
89. public void setStartIndex(long startIndex) {
90. this.startIndex = startIndex;
91. }
92.
93. public long getEndIndex() {
94. return endIndex;
95. }
96.
97. public void setEndIndex(long endIndex) {
98. this.endIndex = endIndex;
99. }
100.
101. public long getTotalPage() {
102. return totalPage;
103. }
104.
105. public void setTotalPage(long totalPage) {
106. this.totalPage = totalPage;
107. }
108.
109. public int getMaxResult() {
110. return maxResult;
111. }
112.
113. public void setMaxResult(int maxResult) {
114. this.maxResult = maxResult;
115. }
116.
117. public int getCurrentPage() {
118. return currentPage;
119. }
120.
121. public void setCurrentPage(int currentPage) {
122. this.currentPage = currentPage<1?1:currentPage; //如果当前页为0,则显示第一页
123. }
124.
125. public long getTotalRecord() {
126. return totalRecord;
127. }
128.
129. public void setTotalRecord(long totalRecord) {
130. this.totalRecord = totalRecord;
131. }
132.
133. public int getPageBarSize() {
134. return pageBarSize;
135. }
136.
137. public void setPageBarSize(int pageBarSize) {
138. this.pageBarSize = pageBarSize;
139. }
140. }