美文网首页我爱编程Spring框架学习笔记
16_Spring 整合Hibernate(XML方式)

16_Spring 整合Hibernate(XML方式)

作者: 小窗风雨 | 来源:发表于2018-01-20 12:06 被阅读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);
      }
      

    相关文章

      网友评论

        本文标题:16_Spring 整合Hibernate(XML方式)

        本文链接:https://www.haomeiwen.com/subject/fcxtaxtx.html