我爱编程Spring框架学习笔记

16_Spring 整合Hibernate(XML方式)

2018-01-20  本文已影响0人  小窗风雨

基本原理:由Spring来管理Hibernate的SessionFactory

方式一:零障碍整合(了解)

  1. 配置好 hibernate.cfg.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
    
        <!-- 配置数据库连接 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sshtest</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>

        <!-- Hibernate的方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 显示sql语句 -->
        <property name="hibernate.show_sql">true</property>

        <!-- 格式化sql语句 -->
        <property name="hibernate.format_sql">true</property>
        
        <!-- 自动创建表 -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 设置连接提供者 -->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        
        <!-- c3p0连接配置 -->
        <property name="hibernate.c3p0.max_size">20</property><!-- 最大连接数 -->
        <property name="hibernate.c3p0.min_size">5</property><!-- 最小连接数 -->
        <property name="hibernate.c3p0.timeout">120</property><!-- 超时 -->
        <property name="hibernate.c3p0.idle_test_period">3000</property><!-- 空闲连接 -->

        <!-- 配置映射文件 -->
        <mapping resource="com/zhangquanli/sshxml/domain/Person.hbm.xml"/>
        
    </session-factory>
</hibernate-configuration>
  1. 将 sessionFactory 交由 Spring 容器来管理
    • Spring 中提供了 LocalSessionFactory 来加载 hibernate.cfg.xml 文件
    • 注意:LocalSessionFactory 类针对 Hibernate 的不同版本,有不同的实现类
    <!-- spring整合hibernate方式一 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    </bean>
    
  2. 在 web.xml 中配置监听器,在服务器启动的时候加载 Spring 的配置文件
<!-- 配置 ContextLoaderListener 监听器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置 applicationContext.xml 路径 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
  1. 当工程加载到服务器后,如果可以自动创建表,就代表Spring整合Hibernate成功。因为在 hibernate.cfg.xml 配置文件中设置了自动创建表。

方式二:由 Spring 管理 Hibernate 的配置文件(重点)

  1. 在 applicationContext.xml 引入 db.properties 文件
<!-- 引入properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sshtest
jdbc.username=root
jdbc.password=root
  1. 配置C3P0连接池
 <!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driverClass}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
  1. 创建 LocalSessionFactoryBean
    • 由 Spring 管理 Hibernate 中的 SessionFactory
<!-- 创建sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
    <!-- 注入连接池 -->
    <property name="dataSource" ref="dataSource"/>
    
    <!-- 配置Hibernate -->
    <property name="hibernateProperties">
        <!-- 以下属性在书写时不能省略hibernate -->
        <!-- <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props> -->
        <!-- 上述props可以简写成以下方案 -->
        <value>
            hibernate.dialect=org.hibernate.dialect.MySQLDialect
            hibernate.show_sql=true
            hibernate.format_sql=true
            hibernate.hbm2ddl.auto=update
        </value>
    </property>
    
    <!-- 加载映射文件 -->
    <property name="mappingResources">
        <list>
            <value>com/zhangquanli/sshxml/domain/Person.hbm.xml</value>
        </list>
    </property>
</bean>
  1. 映射文件加载方式
    • <font color="red">mappingResources</font> 类似于 <mappring resource=""/>
    <property name="mappingResources">
        <list>
            <value>com/zhangquanli/sshxml/domain/Person.hbm.xml</value>
        </list>
    </property>
    
    • <font color="red">mappingLocations</font> 根据类路径加载 classpath:路径
    <property name="mappingLocations">
        <list>
            <value>classpath:com/zhangquanli/sshxml/domain/Person.hbm.xml</value>
        </list>
    </property>
    
    • <font color="red">mappingDirectoryLocations</font> 加载目录下所有映射文件
    <property name="mappingDirectoryLocations">
        <list>
            <value>classpath:com/zhangquanli/sshxml/domain</value>
        </list>
    </property>
    
    • <font color="red">mappingJarLocations</font> 加载jar文件中的映射文件
  2. 由 Spring 管理 Hibernate 的配置文件时,不再需要 hibernate.cfg.xml 配置文件。因为 applicationContext.xml 文件中,就可以完成 Hibernate 的配置。

Spring 整合 Hibernate 后的 Dao

  1. 编写持久层代码
    • Spring 整合 Hibernate 后,Dao需要继承 HibernateDaoSupport
    package com.zhangquanli.sshxml.dao;
    
    import java.util.List;
    import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
    import com.zhangquanli.sshxml.domain.User;
    
    public class UserDaoImpl extends HibernateDaoSupport implements IUserDao {
    
        @Override
        public void add(User user) {
            getHibernateTemplate().save(user);//session.save()
        }
    
        @Override
        public void update(User user) {
            getHibernateTemplate().update(user);//session.update()
        }
    
        @Override
        public void del(User user) {
            getHibernateTemplate().delete(user);//session.delete();
        }
    
        @Override
        public User findById(Integer id) {
            return getHibernateTemplate().get(User.class, 1);//session.get()
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public List<User> findAll() {
            return (List<User>) getHibernateTemplate().find("from User");//session.createQuery(hql).list()
        }
    
    }
    
  2. 声明 dao
    • 在 HibernateDaoSupport 中注入 SessionFactory 获取 HibernateTemplate
    • HibernateTemplate 是对 Hibernate 操作的简单封装
    <!-- dao -->
    <bean id="userDao" class="com.zhangquanli.sshxml.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
  3. 编写业务层代码
package com.zhangquanli.sshxml.service;

import java.util.List;
import com.zhangquanli.sshxml.dao.IUserDao;
import com.zhangquanli.sshxml.domain.User;

public class UserServiceImpl implements IUserService {
    private IUserDao userDao;

    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void add(User user) {
        userDao.add(user);
    }

    @Override
    public void update(User user) {
        userDao.update(user);
    }

    @Override
    public void del(User user) {
        userDao.del(user);
    }

    @Override
    public User findById(Integer id) {
        return userDao.findById(id);
    }

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

}
  1. 声明 service
<!-- service -->
<bean id="userService" class="com.zhangquanli.sshxml.service.UserServiceImpl">
    <property name="userDao" ref="userDao" />
</bean>
  1. 在 applicationContext.xml 中配置事务管理
<!-- 声明式事务管理 -->
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="find*" read-only="true"/>
        <tx:method name="add"/>
        <tx:method name="update"/>
        <tx:method name="del"/>
    </tx:attributes>
</tx:advice>

<!-- 切面 -->
<aop:config>
    <aop:pointcut expression="execution(* com.zhangquanli.sshxml.service.*..*(..))" id="myPointcut"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
</aop:config>
  1. 编写测试代码
package com.zhangquanli.sshxml.service;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.zhangquanli.sshxml.domain.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserServiceImplTest {
    
    @Autowired
    private IUserService userService;

    @Test
    public void testAdd() {
        User user = new User();
        user.setName("lis");
        user.setAge(29);
        user.setSex("女");
        userService.add(user);
    }

    @Test
    public void testUpdate() {
        User user = userService.findById(2);
        user.setName("黄珊珊");
        userService.update(user);
    }

    @Test
    public void testDel() {
        User user = userService.findById(2);
        userService.del(user);
    }

    @Test
    public void testFindById() {
        User user = userService.findById(2);
        System.out.println(user);
    }

    @Test
    public void testFindAll() {
        List<User> list = userService.findAll();
        System.out.println(list);
    }

}

HibernateTemplate API

  1. 增删改
    • <font color="red">Serializable save(Object entity)</font>
    • <font color="red">void update(Object entity)</font>
    • <font color="red">void saveOrUpdate(Object entity)</font>
    • <font color="red">void delete(Object entity)</font>
    • <font color="red"><T> T get(Class<T> entityClass, Serializable id)</font>
    • <font color="red"><T> T load(Class<T> entityClass, Serializable id)</font>
    • <font color="red">List<?> find(String queryString, Object... values)</font>
    • <font color="red">List<?> findByCriteria(DetachedCriteria criteria)</font>
    • <font color="red">List<?> findByNamedQuery(String queryName, Object... values)</font>
  2. 一级缓存相关
    • <font color="red">void evict(Object entity)</font>
    • <font color="red">void clear()</font>
  3. 一级缓存与数据库交互
    • <font color="red">void flush()</font>
    • <font color="red">void refresh(Object entity)</font>
  4. 演示 <font color="red">findByCriteria</font> 方法
    • 创建 DetachedCriteria 对象
    public void testFindByCriteria() {
        DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
        criteria.add(Restrictions.gt("age", 20));
        List<User> list = userService.findByCriteria(criteria);
        System.out.println(list);
    }
    
    • 在dao层调用 findByCriteria 方法
    public List<User> findByCriteria(DetachedCriteria criteria) {
        return (List<User>) getHibernateTemplate().findByCriteria(criteria);
    }
    
  5. 演示 <font color="red">findByNamedQuery</font> 方法
    • 在 User.hbm.xml 文件中定义 hql 和 sql
    <query name="findUserByHQL">
        from User where id>?
    </query>
    
    <sql-query name="findUserBySQL">
        <return class="com.zhangquanli.sshxml.domain.User"/>
        select * from t_user
    </sql-query>
    
    • 持久层代码
    public List<User> findByNamedQueryHQL(Integer id) {
        return (List<User>) getHibernateTemplate().findByNamedQuery("findUserByHQL", id);
    }
    
    public List<User> findByNamedQuerySQL() {
        return (List<User>) getHibernateTemplate().findByNamedQuery("findUserBySQL");
    }
    
    • 测试代码
    @Test
    public void testFindByNamedQueryHQL() {
        List<User> list = userService.findByNamedQueryHQL(2);
        System.out.println(list);
    }
    
    @Test
    public void testFindByNamedQuerySQL() {
        List<User> list = userService.findByNamedQuerySQL();
        System.out.println(list);
    }
    
上一篇下一篇

猜你喜欢

热点阅读