频道栏目
首页 > 程序开发 > 软件开发 > Java > 正文
Spring对ORM的支持之集成Hibernate3
2016-05-12 09:07:49         来源:程序猿开发日志【学习永无止境】  
收藏   我要投稿

1 集成Hibernate3

Hibernate是全自动的ORM框架,能自动为对象生成相应SQL并透明的持久化对象到数据库

Spring2.5+版本支持Hibernate 3.1+版本,不支持低版本,Spring3.0.5版本提供对Hibernate 3.6.0 Final版本支持。

1.1. 如何集成

Spring通过使用如下Bean进行集成Hibernate:

  • LocalSessionFactoryBean :用于支持XML映射定义读取:

    configLocation和configLocations:用于定义Hibernate配置文件位置,一般使用如classpath:hibernate.cfg.xml形式指定;

    mappingLocations :用于指定Hibenate映射文件位置,如chapter8/hbm/user.hbm.xml;

    hibernateProperties:用于定义Hibernate属性,即Hibernate配置文件中的属性;

    dataSource:定义数据源;

    hibernateProperties、dataSource用于消除Hibernate配置文件,因此如果使用configLocations指定配置文件,就不要设置这两个属性了,否则会产生重复配置。推荐使用dataSource来指定数据源,而使用hibernateProperties指定Hibernate属性。

    • AnnotationSessionFactoryBean:用于支持注解风格映射定义读取,该类继承LocalSessionFactoryBean并额外提供自动查找注解风格配置模型的能力:

      annotatedClasses:设置注解了模型类,通过注解指定映射元数据。

      packagesToScan:通过扫描指定的包获取注解模型类,而不是手工指定,如“cn.javass.**.model”将扫描cn.javass包及子包下的model包下的所有注解模型类。

      接下来学习一下Spring如何集成Hibernate吧:

      1.1.1、准备jar包:

      首先准备Spring对ORM框架支持的jar包:

      org.springframework.orm-3.0.5.RELEASE.jar //提供对ORM框架集成

      下载hibernate-distribution-3.6.0.Final包,获取如下Hibernate需要的jar包:

      hibernate3.jar //核心包

      lib\required\antlr-2.7.6.jar //HQL解析时使用的包

      lib\required\javassist-3.9.0.GA.jar //字节码类库,类似于cglib

      lib\required\commons-collections-3.1.jar //对集合类型支持包,前边测试时已经提供过了,无需再拷贝该包了

      lib\required\dom4j-1.6.1.jar //xml解析包,用于解析配置使用

      lib\required\jta-1.1.jar //JTA事务支持包

      lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar //用于支持JPA

      下载slf4j-1.6.1.zip(https://www.slf4j.org/download.html),slf4j是日志系统门面(Simple Logging Facade for Java),用于对各种日志框架提供给一致的日志访问接口,从而能随时替换日志框架(如log4j、java.util.logging):

      slf4j-api-1.6.1.jar //核心API

      slf4j-log4j12-1.6.1.jar //log4j实现

      将这些jar包添加到类路径中。

      1.1.2、对象模型定义,此处使用第七章中的UserModel:

      java代码:

      package cn.javass.spring.chapter7;
      public class UserModel {
          private int id;
          private String myName;
          //省略getter和setter
      }

      1.1.3、Hibernate映射定义(chapter8/hbm/user.hbm.xml),定义对象和数据库之间的映射:

      java代码:

      
      
      
          
              
              
          
      

      1.1.4、数据源定义,此处使用第7章的配置文件,即“chapter7/applicationContext-resources.xml”文件。

      1.1.5、SessionFactory配置定义(chapter8/applicationContext-hibernate.xml):

      java代码:

      
           
                 
              
                chapter8/hbm/user.hbm.xml
              
            
               
              
                
                    org.hibernate.dialect.HSQLDialect
                
              
            
      

      1.1.6、获取SessionFactory:

      java代码:

      package cn.javass.spring.chapter8;
      //省略import
      public class HibernateTest {
          private static SessionFactory sessionFactory;
          @BeforeClass
          public static void beforeClass() {
              String[] configLocations = new String[] {
                      "classpath:chapter7/applicationContext-resources.xml",
                      "classpath:chapter8/applicationContext-hibernate.xml"};
              ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
              sessionFactory = ctx.getBean("sessionFactory", SessionFactory.class);
      }
      }

      此处我们使用了chapter7/applicationContext-resources.xml定义的“dataSource”数据源,通过ctx.getBean(“sessionFactory”, SessionFactory.class)获取SessionFactory。

      1.1.7、通过SessionFactory获取Session对象进行创建和删除表:

      java代码:

      @Before
      public void setUp() {
        //id自增主键从0开始
        final String createTableSql = "create memory table test" + "(id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, " + "name varchar(100))";
        sessionFactory.openSession().
        createSQLQuery(createTableSql).executeUpdate();
      }
      @After
      public void tearDown() {
          final String dropTableSql = "drop table test";
          sessionFactory.openSession().
          createSQLQuery(dropTableSql).executeUpdate();
      }

      使用SessionFactory创建Session,然后通过Session对象的createSQLQuery创建本地SQL执行创建和删除表。

      1.1.8、使用SessionFactory获取Session对象进行持久化数据:

      java代码:

      @Test
      public void testFirst() {
          Session session = sessionFactory.openSession();
          Transaction transaction = null;
          try {
              transaction = beginTransaction(session);
              UserModel model = new UserModel();
              model.setMyName("myName");
              session.save(model);
          } catch (RuntimeException e) {
              rollbackTransaction(transaction);
              throw e;
          } finally {
              commitTransaction(session);
          }
      }

      java代码:

      private Transaction beginTransaction(Session session) {
          Transaction transaction = session.beginTransaction();
          transaction.begin();
          return transaction;
      }
      private void rollbackTransaction(Transaction transaction) {
         if(transaction != null) {
              transaction.rollback();
          }
      }
      private void commitTransaction(Session session) {
          session.close();
      }

      使用SessionFactory获取Session进行操作,必须自己控制事务,而且还要保证各个步骤不会出错,有没有更好的解决方案把我们从编程事务中解脱出来?Spring提供了HibernateTemplate模板类用来简化事务处理和常见操作。

      1.2 使用HibernateTemplate

      HibernateTimplate模板类用于简化事务管理及常见操作,类似于JdbcTemplate模板类,对于复杂操作通过提供HibernateCallback回调接口来允许更复杂的操作。

      接下来示例一下HibernateTemplate的使用:

      java代码:

      @Test
      public void testHibernateTemplate() {
      HibernateTemplate hibernateTemplate =
      new HibernateTemplate(sessionFactory);
          final UserModel model = new UserModel();
          model.setMyName("myName");
          hibernateTemplate.save(model);
          //通过回调允许更复杂操作
          hibernateTemplate.execute(new HibernateCallback() {
              @Override
              public Void doInHibernate(Session session)
                  throws HibernateException, SQLException {
                  session.save(model);
                  return null;
              }});
      }

      通过new HibernateTemplate(sessionFactory) 创建HibernateTemplate模板类对象,通过调用模板类的save方法持久化对象,并且自动享受到Spring管理事务的好处。

      而且HibernateTemplate 提供使用HibernateCallback回调接口的方法execute用来支持复杂操作,当然也自动享受到Spring管理事务的好处。

      1.3 集成Hibernate及最佳实践

      类似于JdbcDaoSupport类,Spring对Hibernate也提供了HibernateDaoSupport类来支持一致的数据库访问。HibernateDaoSupport也是DaoSupport实现:

      接下来示例一下Spring集成Hibernate的最佳实践:

      1.3.1、定义Dao接口,此处使用cn.javass.spring.chapter7.dao. IUserDao:

      1.3.2、定义Dao接口实现,此处是Hibernate实现:

      java代码:

      package cn.javass.spring.chapter8.dao.hibernate;
      import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
      import cn.javass.spring.chapter7.UserModel;
      import cn.javass.spring.chapter7.dao.IUserDao;
      public class UserHibernateDaoImpl extends HibernateDaoSupport implements IUserDao {
          private static final String COUNT_ALL_HQL = "select count(*) from UserModel";
          @Override
          public void save(UserModel model) {
              getHibernateTemplate().save(model);
          }
          @Override
          public int countAll() {
              Number count = (Number) getHibernateTemplate().find(COUNT_ALL_HQL).get(0);
              return count.intValue();
          }
      }

      此处注意首先Hibernate实现放在dao.hibernate包里,其次实现类命名如UserHibernateDaoImpl,即×××HibernateDaoImpl,当然如果自己有更好的命名规范可以遵循自己的,此处只是提个建议。

      1.3.3 、进行资源配置,使用resources/chapter7/applicationContext-resources.xml:

      1.3.4、dao定义配置,在chapter8/applicationContext-hibernate.xml中添加如下配置:

      java代码:

      
          
         
      

      首先定义抽象的abstractDao,其有一个sessionFactory属性,从而可以让继承的子类自动继承sessionFactory属性注入;然后定义userDao,且继承abstractDao,从而继承sessionFactory注入;我们在此给配置文件命名为applicationContext-hibernate.xml表示Hibernate实现。

      1.3.5、 最后测试一下吧(cn.javass.spring.chapter8. HibernateTest):

      java代码:

      @Test
      public void testBestPractice() {
          String[] configLocations = new String[] {
                  "classpath:chapter7/applicationContext-resources.xml",
                  "classpath:chapter8/applicationContext-hibernate.xml"};
          ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
          IUserDao userDao = ctx.getBean(IUserDao.class);
          UserModel model = new UserModel();
          model.setMyName("test");
          userDao.save(model);
          Assert.assertEquals(1, userDao.countAll());
      }

      和Spring JDBC框架的最佳实践完全一样,除了使用applicationContext-hibernate.xml代替了applicationContext-jdbc.xml,其他完全一样。也就是说,DAO层的实现替换可以透明化。

      1.4 Spring+Hibernate的CRUD

      Spring+Hibernate CRUD(增删改查)我们使用注解类来示例,让我们看具体示例吧:

      1.4.1、首先定义带注解的模型对象UserModel2:

      • 使用JPA注解@Table指定表名映射;
      • 使用注解@Id指定主键映射;
      • 使用注解@ Column指定数据库列映射;

        java代码:

        package cn.javass.spring.chapter8;
        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.GenerationType;
        import javax.persistence.Id;
        import javax.persistence.Table;
        @Entity
        @Table(name = "test")
        public class UserModel2 {
            @Id @GeneratedValue(strategy = GenerationType.AUTO)
            private int id;
            @Column(name = "name")
            private String myName;
            //省略getter和setter
        }

        1.4.2、 定义配置文件(chapter8/applicationContext-hibernate2.xml):

        1.4.2.1、定义SessionFactory:

        此处使用AnnotationSessionFactoryBean通过annotatedClasses属性指定注解模型来定义映射元数据;

        java代码:

        
          
                     
             cn.javass.spring.chapter8.UserModel2
        
          
            
             
                org.hibernate.dialect.HSQLDialect
             
            
          
        

        1.4.2.2、定义HibernateTemplate:

        java代码:

        
            
        

        1.4.3、最后进行CURD测试吧:

        java代码:

        @Test
        public void testCURD() {
            String[] configLocations = new String[] {
                    "classpath:chapter7/applicationContext-resources.xml",
                    "classpath:chapter8/applicationContext-hibernate2.xml"};
            ApplicationContext ctx =  new ClassPathXmlApplicationContext(configLocations);
            HibernateTemplate hibernateTemplate =  ctx.getBean(HibernateTemplate.class);
            UserModel2 model = new UserModel2();
            model.setMyName("test");
            insert(hibernateTemplate, model);
            select(hibernateTemplate, model);
            update(hibernateTemplate, model);
            delete(hibernateTemplate, model);
        }
        
        private void insert(HibernateTemplate hibernateTemplate, UserModel2 model) {
            hibernateTemplate.save(model);
        }
        private void select(HibernateTemplate hibernateTemplate, UserModel2 model) {
            UserModel2 model2 = hibernateTemplate.get(UserModel2.class, 0);
            Assert.assertEquals(model2.getMyName(), model.getMyName());
            List list = hibernateTemplate.find("from UserModel2");
            Assert.assertEquals(list.get(0).getMyName(), model.getMyName());
        }
        private void update(HibernateTemplate hibernateTemplate, UserModel2 model) {
            model.setMyName("test2");
            hibernateTemplate.update(model);
        }
        private void delete(HibernateTemplate hibernateTemplate, UserModel2 model) {
            hibernateTemplate.delete(model);
        }

        Spring集成Hibernate进行增删改查是不是比Spring JDBC方式简单许多,而且支持注解方式配置映射元数据,从而减少映射定义配置文件数量。

点击复制链接 与好友分享!回本站首页
相关TAG标签
上一篇:Java 设计模式(十三) 接口隔离原则(ISP)
下一篇:springmvc+spring3+hibernate4框架简单整合,简单实现增删改查功能
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站