您的位置:首页 > 编程语言 > Java开发

spring4+springMVC+hibernate4 整合

2016-06-12 00:00 585 查看
摘要: spring4+springMVC+hibernate4 整合

ps: 刚刚学习完了这几个框架,整合练习练习,虽说简单,但也搞了我一整天,最后终于搞通了,这酸爽。。。小记一下,(大神不要喷哦)

首先在配置的过程中,出现了几个异常,在度娘上参考各位大神的解答后,终于得以解决,最后说。

第一步:导包:

spring 包:



hibernate 包:



oracle 数据库的包:



总体的项目结构:



第二步:配置文件

web.xml 文件

<?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"
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">

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!-- 配置 :  把 POST 请求转化为 PUT, DELETE 请求-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

hibernate 的配置文件 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">
<hibernate-configuration>
<session-factory>

<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>

</session-factory>
</hibernate-configuration>

springmvc.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 
<context:component-scan base-package="ssh.handler">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>

</beans>

beans.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 
<context:property-placeholder file-encoding="UTF-8" location="classpath:db.properties"/>

<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="scott"></property>
<property name="password" value="orcl"></property>
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>

<property name="initialPoolSize" value="5"></property>
<property name="maxPoolSize" value="10"></property>
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" autowire="byName">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" value="classpath:ssh/hbm/*.hbm.xml"></property>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<context:component-scan base-package="ssh.dao,ssh.service">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

</beans>


注意:在 springmvc.xml 和 beans.xml 中都使用了<context:component-scan/>来扫描包,如果她们两个扫描的包有重叠的部分的话,则在容器初始化的时候,会初始化两次相应的类,这对性能有一定的影响,可以通过 <context:exclude-filter/> 和 <context:include-filter/> 子节点来过滤重复的包。

第三步:相关类:

ssh.po 包的:

public class Atm {

private String username;
private String password;
private Integer money;
private Long id;

setter/getter......
}

Atm.hbm.xml 配置文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-6-12 13:47:03 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="ssh.po.Atm" table="ATM">

<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="native" />
</id>

<property name="username" type="java.lang.String">
<column name="USERNAME" />
</property>
<property name="password" type="java.lang.String">
<column name="PASSWORD" />
</property>

<property name="money" type="java.lang.Integer">
<column name="MONEY" />
</property>

</class>
</hibernate-mapping>

ssh.dao 包下的:

public interface AtmDao {
List<Atm> queryAll();
Atm queryById(String username);
boolean add(Atm atm);
boolean update(String username);
boolean delete(String username);
}

@Repository("atmDao")
public class AtmDaoImpl  implements AtmDao{

@Autowired
public @Qualifier(value="sessionFactory")SessionFactory sessionFactory;

private Session getSession(){
System.out.println(sessionFactory);
return sessionFactory.getCurrentSession();
}

@Transactional
@Override
public List<Atm> queryAll() {
String hql = "FROM ssh.po.Atm";
List<Atm> atms = null;
try{
atms = this.getSession().createQuery(hql).list();
}catch(Exception e){
System.out.println("查询所有的信息失败");
e.printStackTrace();
}
return atms;
}

@Transactional
@Override
public Atm queryById(String username) {
Atm atm = null;
String hql = "FROM ssh.po.Atm where username=:name";
try{
Query query = this.getSession().createQuery(hql);
query.setParameter("name", username);
atm = (Atm)query.uniqueResult();
}catch(Exception e){
System.out.println("查询单条信息失败");
e.printStackTrace();
}
return atm;
}

@Transactional
@Override
public boolean add(Atm atm) {
try{
this.getSession().save(atm);
}catch(Exception e){
System.out.println("添加信息失败");
e.printStackTrace();
return false;
}
return true;
}

@Transactional
@Override
public boolean update(String username) {
try{
Atm atm = this.queryById(username);
atm.setPassword("ppppp");
atm.setMoney(88888);
this.getSession().update(atm);
}catch(Exception e){
System.out.println("更新息失败");
e.printStackTrace();
return false;
}
return true;
}

@Transactional
@Override
public boolean delete(String username) {
try{
Atm atm = this.queryById(username);
this.getSession().delete(atm);
}catch(Exception e){
System.out.println("删除信息失败");
e.printStackTrace();
return false;
}
return true;
}
}

ssh.service 包下的

@Service("atmService")
public class AtmService {

public AtmService() {
System.out.println("AtmService");
}

@Autowired @Qualifier(value="atmDao")
private AtmDao atmDao;

public List<Atm> queryAll(){
List<Atm> atms = atmDao.queryAll();
return atms;
}

public Atm queryById(String username) {
return atmDao.queryById(username);
}

public boolean add(Atm atm) {
return atmDao.add(atm);
}

public boolean update(String username) {
return atmDao.update(username);
}

public boolean delete(String username) {
return atmDao.delete(username);
}
}

ssh.handler 包下的

@Controller("handler")
public class Handler {

@Autowired
public AtmService atmService;

@RequestMapping("/queryAll")
public String queryAll(){
List<Atm> atms = atmService.queryAll();
for(Atm atm :atms){
System.out.println(atm.getUsername()+"--->"+atm.getPassword());
}
return "list";
}

@RequestMapping("/queryById")
public String queryById(){
Atm atm = atmService.queryById("mengyuankan1");
System.out.println(atm.getUsername()+"--->"+atm.getPassword());
return "list";
}

@RequestMapping("/add")
public String add(){
Atm atm = new Atm("ppppp", "ppp", 88888);
atmService.add(atm);
return "list";
}

@RequestMapping("/update")
public String update(){
atmService.update("menghang");
return "list";
}

@RequestMapping("/delete")
public String delete(){
atmService.delete("menghang");
return "list";
}
}

页面:index.jsp

<body>

<a href="queryAll">Query All</a>
<br><br>

<a href="queryById">QueryById</a>
<br><br>

<a href="add">Add</a>

<br><br>
<a href="update">Update</a>

<br><br>
<a href="delete">Delete</a>

</body>

完活。。。。。。

这里要说一下出现的异常:

1,No Session found for current thread 异常:

原因是在取得session 的地方使用了getCurrentSession,

即在dao下:

@Autowired
public @Qualifier(value="sessionFactory")SessionFactory sessionFactory;

private Session getSession(){
System.out.println(sessionFactory);
return sessionFactory.getCurrentSession();
}

百度有说在hibernate配置文件加上

<property name="hibernate.current_session_context_class">thread</property>

加上之后,启动没毛病,运行的时候出现了下述异常:

createQuery is not valid without active transaction

我们还是去掉吧,解决上述那个异常,我们得必须配置事务,然后在dao的方法上加上

@Transactional注解才能运行。

<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

上述粘贴的ssh.dao包下的代码中的每个方法都标注了@Transactional注解。

原因如下:SessionFactory 的 getCurrentSession 并不能保证在没有当前Session的情况下会自动创建一个新的,这取决于CurrentSessionContext的实现,SessionFactory将调用CurrentSessionContext的currentSession()方法来获得Session。在Spring中,如果我们在没有配置TransactionManager并且没有事先调用SessionFactory.openSession()的情况直接调用getCurrentSession(),那么程序将抛出“No Session found for current thread”异常。如果配置了TranactionManager并且通过@Transactional或者声明的方式配置的事务边界,那么Spring会在开始事务之前通过AOP的方式为当前线程创建Session,此时调用getCurrentSession()将得到正确结果。

2. 我在 service 通过 @Autowired 来自动注入 dao 的类,在 handler 里面自动注入 service 里面的类,有个奇怪的问题:只能自动注入 接口,而注入接口的实现类的话,则出异常,这个没搞懂是什么意思,请教各位大神们。。。是为什么啊。。

大神博客地址:

http://www.yihaomen.com/article/java/466.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息