Spring+Hibernate整合开发配置,完整实例

来源:互联网 发布:我想学习编程 编辑:程序博客网 时间:2024/06/06 02:05

目录结构

这里写图片描述

Jar包

这里写图片描述

配置

一、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:mvc="http://www.springframework.org/schema/mvc"    xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">    <!-- 导入Src目录下的jdbc.properties文件 -->    <context:property-placeholder location="classpath:config/jdbc.properties"/>    <!-- 打开Spring的Annotation支持 -->    <context:annotation-config/>    <!-- 设定Spring去那些包中找Annotation -->    <!--    <context:component-scan base-package="com.wen"/> -->    <context:component-scan base-package="com.wen" use-default-filters="false">        <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>    <!-- 配置数据源 -->    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="${jdbc.driverClassName}"/>        <property name="jdbcUrl" value="${jdbc.url}"/>        <property name="user" value="${jdbc.username}"/>        <property name="password" value="${jdbc.password}"/>        <!-- 配置连接池的初始值 -->    </bean>    <!-- 创建Spring的SessionFactory工厂 -->    <!-- 如果使用的是Annotation的方式,不能使用LocalSessionFactory,而应该使用AnnotationSessionFactoryBean -->    <!-- 但好像无法使用了 -->    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">        <!-- 注入数据源 -->        <property name="dataSource" ref="dataSource"/>        <!-- 通过扫描包方式设置Spring取哪个包查找相应的实体类 -->        <property name="packagesToScan">            <value>com.wen.entity</value>        </property>        <!-- 或者通过注解方式        <property name="annotatedClasses">            <list>                <value>com.wen.entity.User</value>                <value>com.wen.entity.Repairs</value>            </list>        </property>           -->        <property name="hibernateProperties">            <props>                  <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>                  <prop key="hibernate.hbm2ddl.auto">update</prop>                  <prop key="hibernate.show_sql">true</prop>                  <prop key="hibernate.format_sql">true</prop>              </props>          </property>    </bean>    <!-- 开启HibernateTemplate,并且为其注入SessionFactory    使用HibernateTemplate不太方便的就是要获取session得通过getSessionFactory()方法获取    注意:这里之所以配置这个是因为我的UserDao继承了HibernateDaoSupport -->    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">        <property name="sessionFactory" ref="sessionFactory"/>    </bean>    <!-- 配置Spring的事务处理 -->    <!-- 创建事务管理器 -->    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">        <property name="sessionFactory" ref="sessionFactory"/>    </bean>    <!-- 配置AOP,Spring是通过AOP来进行事务管理的 -->    <aop:config>        <!-- 设置pointcut,表示哪些方法要加入事务处理 -->        <aop:pointcut expression="execution(* com.wen.service.*.*(..))" id="allMethod"/>        <!-- 通过advisor来确定具体要加入事务控制的方法 -->        <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethod"/>    </aop:config>       <!-- 配置哪些方法要加入事务控制 -->    <tx:advice id="txAdvice" transaction-manager="txManager">        <tx:attributes>            <!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读事务 -->            <tx:method name="*" propagation="REQUIRED" read-only="true"/>            <!-- 以下方法都是可能涉及写改的方法,就无法设置为只读 -->            <tx:method name="add*" propagation="REQUIRED"/>            <tx:method name="del*" propagation="REQUIRED"/>            <tx:method name="update*" propagation="REQUIRED"/>            <tx:method name="save*" propagation="REQUIRED"/>        </tx:attributes>    </tx:advice></beans>

二、user-servlet.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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">    <!-- 注解驱动 -->    <mvc:annotation-driven/>    <!-- 扫描包 -->    <context:component-scan base-package="com.wen"/>    <!-- 配置视图解析器 -->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/jsp/"/>        <property name="suffix" value=".jsp"/>    </bean></beans>

2016-9-22 09:41:37 补充 web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0"     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">  <display-name></display-name>   <!-- 创建Spring的监听器 -->  <listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>  <!-- Spring的监听器可以通过这个上下文参数来获取bean.xml的位置 -->  <context-param>    <param-name>contextConfigLocation</param-name>    <param-value>classpath:config/beans.xml</param-value>  </context-param>  <servlet>    <servlet-name>user</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <init-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:config/user-servlet.xml</param-value>    </init-param>    <load-on-startup>1</load-on-startup>  </servlet>  <servlet-mapping>    <servlet-name>user</servlet-name>    <url-pattern>/</url-pattern>  </servlet-mapping>  <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>  </filter>  <filter-mapping>    <filter-name>CharacterEncodingFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>  <!-- Spring中提供了这个类来实现OpenSessionInViewer的操作 -->  <filter>    <filter-name>OpenSessionInViewFilter</filter-name>    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>  </filter>  <filter-mapping>    <filter-name>OpenSessionInViewFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>  <!-- SystemContextFilter,我们自己定义的 -->  <filter>    <filter-name>SystemContextFilter</filter-name>    <filter-class>com.wen.web.SystemContextFilter</filter-class>    <!-- <init-param>        <param-name>pageSize</param-name>        <param-value>15</param-value>    </init-param> -->  </filter>  <filter-mapping>    <filter-name>SystemContextFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>  <!-- sitemesh过滤器 -->  <filter>    <filter-name>sitemesh</filter-name>    <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>  </filter>  <filter-mapping>    <filter-name>sitemesh</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>

三、jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/spring_userjdbc.username=rootjdbc.password=root

com.wen.entity实体类

1、Pager.java

package com.wen.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import org.hibernate.annotations.GenericGenerator;@Entity@Table(name="t_user")public class User {    @Id    @GeneratedValue    private int id;    private String username;    private String password;    private String email;    private String nickname;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    public String getNickname() {        return nickname;    }    public void setNickname(String nickname) {        this.nickname = nickname;    }}

2、Pager.java

package com.wen.entity;import java.util.List;public class Pager<T> {    private List<T> datas;    //初始页    private int offset;    //每页记录数    private int size;    private int totalSize;    private long total;    public List<T> getDatas() {        return datas;    }    public void setDatas(List<T> datas) {        this.datas = datas;    }    public int getOffset() {        return offset;    }    public void setOffset(int offset) {        this.offset = offset;    }    public int getSize() {        return size;    }    public void setSize(int size) {        this.size = size;    }    public int getTotalSize() {        return totalSize;    }    public void setTotalSize(int totalSize) {        this.totalSize = totalSize;    }    public long getTotal() {        return total;    }    public void setTotal(long total) {        this.total = total;    }}

3、SystemContext.java

package com.wen.entity;public class SystemContext {    private static ThreadLocal<Integer> offset = new ThreadLocal<Integer>();    private static ThreadLocal<Integer> size = new ThreadLocal<Integer>();    public static Integer getOffset() {        return offset.get();    }    public static void setOffset(Integer _offset) {        offset.set(_offset);    }    public static Integer getSize() {        return size.get();    }    public static void setSize(Integer _size) {        size.set(_size);    }    public static void removeSize() {        size.remove();    }    public static void removeOffset() {        offset.remove();    }}

4、UserException.java

package com.wen.entity;public class UserException extends RuntimeException {    private static final long serialVersionUID = 1L;    public UserException() {        super();        // TODO Auto-generated constructor stub    }    public UserException(String message, Throwable cause) {        super(message, cause);        // TODO Auto-generated constructor stub    }    public UserException(String message) {        super(message);        // TODO Auto-generated constructor stub    }    public UserException(Throwable cause) {        super(cause);        // TODO Auto-generated constructor stub    }}

com.wen.dao 数据库接口

1、IUserDao.java

package com.wen.dao;import java.util.List;import com.wen.entity.Pager;import com.wen.entity.User;public interface IUserDao {    public void add(User user);    public void update(User user);    public void delete(int id);    public User load(int id);    public List<User> list();    public Pager<User> find();    public User loadByUsername(String username);}

2、UserDao.java

package com.wen.dao;import java.util.List;import javax.annotation.Resource;import org.hibernate.Query;import org.hibernate.SessionFactory;import org.springframework.orm.hibernate4.support.HibernateDaoSupport;import org.springframework.stereotype.Repository;import com.wen.entity.Pager;import com.wen.entity.SystemContext;import com.wen.entity.User;@Repository("userDao")public class UserDao extends HibernateDaoSupport implements IUserDao {    //SessionFactory 在包org.hibernate内    //private SessionFactory sessionFactory;    //为SessionFactory添加set方法,Spring才能为其注入    //public void setSessionFactory(SessionFactory sessionFactory) {    //    this.sessionFactory = sessionFactory;    //}    @Resource    public void setSuperSessionFactory(SessionFactory sessionFactory) {        this.setSessionFactory(sessionFactory);    }    @Override    public void add(User user) {        this.getHibernateTemplate().save(user);    }    @Override    public void update(User user) {        this.getHibernateTemplate().update(user);    }    @Override    public void delete(int id) {        User user = this.load(id);        this.getHibernateTemplate().delete(user);    }    @Override    public User load(int id) {        return this.getHibernateTemplate().load(User.class, id);    }    @SuppressWarnings("unchecked")    @Override    public List<User> list() {        return this.getSessionFactory().getCurrentSession().createQuery("from User").list();    }    @Override    public Pager<User> find() {        int size = SystemContext.getSize();        int offset = SystemContext.getOffset();        Query query = this.getSessionFactory().getCurrentSession().createQuery("from User");        query.setFirstResult(offset).setMaxResults(size);        @SuppressWarnings("unchecked")        List<User> datas = query.list();        Pager<User> us = new Pager<User>();        us.setDatas(datas);        us.setOffset(offset);        us.setSize(size);        long total = (Long) this.getSessionFactory().getCurrentSession().createQuery("select count(*) from User").uniqueResult();        us.setTotal(total);        return us;    }    @Override    public User loadByUsername(String username) {        return (User) this.getSessionFactory().getCurrentSession()                .createQuery("from User where username=?")                .setParameter(0, username).uniqueResult();    }}

com.wen.service 业务逻辑层

1、IUserService.java

package com.wen.service;import java.util.List;import com.wen.entity.Pager;import com.wen.entity.User;public interface IUserService {public void add(User user);    public void update(User user);    public void delete(int id);    public User load(int id);    public List<User> list();    public Pager<User> find();    public User login(String username, String password);}

2、UserService.java

package com.wen.service;import java.util.List;import org.springframework.stereotype.Service;import com.wen.dao.IUserDao;import com.wen.entity.Pager;import com.wen.entity.User;import com.wen.entity.UserException;@Servicepublic class UserService implements IUserService {    private IUserDao userDao;    public IUserDao getUserDao() {        return userDao;    }    public void setUserDao(IUserDao userDao) {        this.userDao = userDao;    }    @Override    public void add(User user) {        User u = userDao.loadByUsername(user.getUsername());        if(u!=null) throw new UserException("要添加的用户已经存在");        userDao.add(user);    }    @Override    public void update(User user) {        userDao.update(user);    }    @Override    public void delete(int id) {        userDao.delete(id);    }    @Override    public User load(int id) {        return userDao.load(id);    }    @Override    public List<User> list() {        return userDao.list();    }    @Override    public Pager<User> find() {        return userDao.find();    }    @Override    public User login(String username, String password) {        User u = userDao.loadByUsername(username);        if(u==null) throw new UserException("登录用户不存在");        if(!u.getPassword().equals(password)) throw new UserException("用户密码不正确");        return u;    }}

com.wen.web 控制层

1、SystemContextFilter.java

package com.wen.web;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import com.wen.entity.SystemContext;public class SystemContextFilter implements Filter {    @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest req, ServletResponse resp,            FilterChain chain) throws IOException, ServletException {        int offset = 0;        try{            offset = Integer.parseInt(req.getParameter("pager.offset"));        } catch(NumberFormatException e) {            //e.printStackTrace();        }        try{            SystemContext.setOffset(offset);            SystemContext.setSize(15);            chain.doFilter(req, resp);        } finally {            SystemContext.removeOffset();            SystemContext.removeSize();        }    }    @Override    public void init(FilterConfig arg0) throws ServletException {        // TODO Auto-generated method stub    }}

2、UserController.java

package com.wen.web;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;@Controller@RequestMapping ("/user")public class UserController {    @RequestMapping(value="/users", method=RequestMethod.GET)    public String list(){        return "user/list";    }}

关于spring配置的SessionFactory解释及其使用方法

1、添加类BaseSessionFactoryImpl用于获取Session

类BaseSessionFactoryImpl的内容如下:

public class BaseSessionFactoryImpl {    @Resource(name="sessionFactory")    private SessionFactory sessionFactory=null;    public Session getSession(){        return sessionFactory.getCurrentSession();    }}

2、在Dao层获取Session,

public class UserDaoImplextends BaseSessionFactoryImpl{    public User queryByUsername(String userName) {            User user=null;        String sql="select user from User user where user.userName="+userName;        try {            user=(User) getSession().get(User.class, 1);        } catch (Exception e) {            e.printStackTrace();        }        return user;    }}

3、重点注意事项

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()将得到正确结果。

然而,产生以上异常的原因在于Spring提供了自己的CurrentSessionContext实现,如果我们不打算使用Spring,而是自己直接从hibernate.cfg.xml创建SessionFactory,并且为在hibernate.cfg.xml
中设置current_session_context_class为thread,也即使用了ThreadLocalSessionContext,那么我们在调用getCurrentSession()时,如果当前线程没有Session存在,则会创建一个绑定到当前线程。

Hibernate在默认情况下会使用JTASessionContext,Spring提供了自己SpringSessionContext,因此我们不用配置current_session_context_class,当Hibernate与Spring集成时,将使用该SessionContext,故此时调用getCurrentSession()的效果完全依赖于SpringSessionContext的实现。

在没有Spring的情况下使用Hibernate,如果没有在hibernate.cfg.xml中配置current_session_context_class,有没有JTA的话,那么程序将抛出”No
CurrentSessionContext
configured!”异常。此时的解决办法是在hibernate.cfg.xml中将current_session_context_class配置成thread。

在Spring中使用Hibernate,如果我们配置了TransactionManager,那么我们就不应该调用SessionFactory的openSession()来获得Sessioin,因为这样获得的Session并没有被事务管理。

至于解决的办法,可以采用如下方式:

1. 在spring 配置文件中加入

< tx:annotation-driven transaction-manager=”transactionManager”/>
并且在处理业务逻辑的类上采用注解

@Servicepublic class CustomerServiceImpl implements CustomerService {     @Transactional    public void saveCustomer(Customer customer) {        customerDaoImpl.saveCustomer(customer);    }...}

另外在 hibernate 的配置文件中,也可以增加这样的配置来避免这个错误:

< property name=”current_session_context_class”>thread< /property>

关于注解的一些疑问

1、在引用实现类的使用时为什么使用的是实现类的接口而不是实现的类

参考这里

这里写图片描述
遇到注解问题,请看这篇文章,绝对有用

0 0
原创粉丝点击