Spring+Hibernate整合
结构图:
搭建步骤:
1:导包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
2:配置hibernateTemplate(applicationContext.xml中)
<!-- 配置hibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
3:配置sessionFactory(applicationContext.xml中)
<!-- 配置sessionfactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="c3p0"></property>
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
</bean>
4:开启hibernate事务
<!-- 配置事务 -->
<bean id="txManger" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
5:启用事务注解
<!-- hibernate的代理注解事务
transaction-manager:代表的是注解事务
proxy-target-class:默认属性值为false,代表不开启事务,也就是不支持事务注解,原生的jdk代理模式
如果属性值为true,则代表开启事务注解,并且此时使用的事务代理模式为cglib动态代理
如果属性值为true,annotation:默认支持的是只读状态(readonly=true),
如果是写操作,需要在action类名前面增加注解,属性设置为可读可写状态(readonly=false)
-->
<tx:annotation-driven transaction-manager="txManger" proxy-target-class="true"/>
6:将hibernate.cfg.xml中的jdbc连接信息,注释掉
重构代码,使用hibernate进行数据查询:
1:将原来的jdbc实现类中的注解注释掉
2:增加NoteDao的接口实现类(使用hibernateTemplate)
3:在写操作的action头部,增加注解,使其变为可读可写状态
代码如下:
HibernateDaoImpl.java:
@Repository
public class HibernateDaoImpl implements NoteDao{
@Resource
private HibernateTemplate hibernateTemplate;
@Override
public List<Note> queryNoteByuserId(Integer userId) {
String hql = "from Note where userId=?";
List<Note> list = (List<Note>) hibernateTemplate.find(hql, userId);
return list;
}
@Override
public int deleteNoteById(Integer id) {
Note note = hibernateTemplate.get(Note.class, id);
if (note != null) {
hibernateTemplate.delete(note); //delete里面是object类型,因此根据id查询到的note用note传值进行删除
return 1;
}
return 0;
}
}
DeleteAction.java:
增加注解:
@Transactional(readOnly=false)//默认是true,为只读状态,false是可读可写状态
重新部署启动,查看结构和控制台
OpenSessionInViewFilter
需求:
请求流程:
问题流程:
/listDetail.do-->filter-->action--->DAO(service)-->hibernate(session关闭)--->result--->listDetail.jsp(note)
解决方法:
/listDetail.do-->filter-->action--->DAO(service)-->hibernate(session不关闭)--->result--->listDetail.jsp(note)
如何让session不关闭:
将session交给spring来处理---OpenSessionInViewFilter可以集中管理sessionFactory
需要在web.xml中配置:
需要注意的是:此filter必须在struts2配置文件之前(有加载顺序的问题)
<!-- 将session交给spring来处理,集中管理session的关闭 -->
<filter>
<filter-name>nosession</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>nosession</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
开发步骤:
1:配置struts.xml中action组件
<!-- 详情功能action -->
<action name="listDetail" class="listDetailAction" method="execute">
<result name="success" type="dispatcher">/WEB-INF/jsp/listDetail.jsp</result>
</action>
2:增加listDetail.jsp文件
<h1>笔记详情</h1>
<h3>发布时间:${note.publishTime }</h3>
<h3>收藏人数:${note.likeCount }</h3>
<h3>笔记内容:${note.context }</h3>
3:增加listDetailAction.java
@Controller
@Scope("prototype")
public class ListDetailAction {
private Integer id;//接收笔记主键ID
public Note note;//前端传值 ${note.publishTime}
@Resource
private NoteDao noteDao;
public String execute(){
note = noteDao.queryNoteById(id);
return "success";
}
public Note getNote() {
return note;
}
public void setNote(Note note) {
this.note = note;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
4:在NoteDao中,增加查询方法
/**
* 根据笔记主键ID,查询笔记详情
* @param id
* @return
*/
public Note queryNoteById(Integer id);
5:实现接口方法(先使用get后使用load)
@Override
public Note queryNoteById(Integer id) {
// Note note = hibernateTemplate.get(Note.class, id);
Note note = hibernateTemplate.load(Note.class, id);
return note;
}
6:在web.xml中配置组件,解决nosession问题
<!-- 将session交给spring来处理,集中管理session的关闭 ,需要配置到struts2组件filter之前-->
<filter>
<filter-name>nosession</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>nosession</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7:部署,启动,访问
ManyToOne、OneToMany
需求:
开发步骤:
1:修改Note.java文件,增加Usernote变量,并增加getter和setter方法
@ManyToOne//多对1
@JoinColumn(name="userId")//关联字段----一般建议将外键进行注释取消
public Usernote usernote;
2:注释掉Note.java中外键字段userId
3:在Usernote.java文件中,增加note列表变量,增加getter和setter方法
@OneToMany//1对多
@JoinColumn(name="userId")
public List<Note> notes;
4:修改listDetail.jsp文件,增加C标签
<h1>笔记详情</h1>
<h3>发布时间:${note.publishTime }</h3>
<h3>发布人:${note.usernote.username }</h3>
<h3>收藏人数:${note.likeCount }</h3>
<h3>笔记内容:${note.context }</h3>
<h1>其它笔记内容:</h1>
<c:forEach items="${note.usernote.notes }" var="note1">
${note1.context }<br/>
</c:forEach>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
二级缓存、查询缓存
一级缓存:
session独享
二级缓存:
需求增加配置,并且依赖于配置内存文件echcache.xml---内存、磁盘
session共享
目的:
第一次进行数据查询的时候,此时缓存中是没有对象数据,则开启事务,进行sql查询,第二次进行相同数据查询的时候,此时缓存中是已经存在之前查询过的数据,则直接从缓存中获取,而非查询数据库执行sql
为了提高程序的性能和降低数据库访问的压力瓶颈
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_sencond_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
实体对象类中,增加缓存注解:
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
类前 和方法前 都增加
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
public class Usernote{
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
public Usernote usernote;
.....
}
查询缓存:
依赖于二级缓存,如果说想使用查询缓存,则前提条件,必须开启二级缓存
hibernate.cfg.xml中放在开启二级缓存后面
<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
HibernateDaoImpl.java中增加
hibernateTemplate.setCacheQueries(true);//开启查询缓存
使用:
1:导包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.2.21.Final</version>
</dependency>
web.xml
最前面增加 <distributable/>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>ssh_13</display-name>
<distributable/>
......
nginx+tomcat集群
注:
先启动tomcat-8081和tomcat-8082
再启动 nginx
nginx配置参考:http://www.nginx.cn/76.html
nginx+tomcat集群参考资料:
session共享问题解决
nginx设置静态文件