zoukankan      html  css  js  c++  java
  • Blue的博客

    整合其他ORM框架

    使用Spring所提供的ORM整合方案, 可以获得许多好处:

    1. 方便基础设施的搭建

      Spring中, 对不同的ORM框架, 首先, 始终可以采用相同的方式配置数据源; 其次, Spring为不同的ORM框架提供了相应的FactoryBean, 用以初始化ORM框架基础设施

    2. 异常封装

      Spring能够转换各种ORM框架所抛出的异常, 转换为Spring DAO异常体系中的标准异常.

    3. 统一的事务管理

      只要遵循Spring所提出的很少的编程要求, 就可以使用Spring提供的事务管理功能.

    4. 允许混合使用多个ORM框架

      由于Spring在DAO异常, 事务, 资源等高级层次建立了抽象, 因而可以让业务层对DAO具体实现的技术不敏感.

    5. 方便单元测试

    在Spring中使用Hibernate

    配置SessionFactory

    使用Hibernate框架的首要工作是编写Hibernate配置文件, 其次是如何使用这些配置文件实例化SessionFactory, 创建Hibernate的基础设施

    Spring为创建SessionFactory提供类LocalSessionFactoryBean, 通过配置一些必要的属性, 就可以获取一个SessionFactoryBean

    1. 零过渡障碍的配置方式

      1
      <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" p:configLocaiton="classpath: hiberante.cfg.xml" />

      configLocation属性指定一个Hibernate配置未见

      configLocations属性指定多个配置文件, 用逗号分隔

      LocalSessionFactoryBean利用Hibernate配置文件创建一个SessionFactory代理对象, 以便和Spring的事务管理机制配合工作: 当数据访问代码使用SessionFactory时, 可以获取线程绑定的Session, 不管工作在本地或全局的事务, 都能正确参与到当前的事务管理中

    2. 更具Spring风格的配置

      可以在Spring容器中定义数据源, 指定映射文件, 设置Hibernate控制属性等信息, 完成集成组装工作, 完全抛开hibernate.cfg.xml配置文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <context:property-placeholder location="classpath:jdbc.properties"/>
      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/>
      <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" p:dataSource-ref="dataSource">

      <property name="mappingLocations">
      <list>
      <value>classpath*:/com/smart/org/domain/Forum.hbm.xml</value>
      </list>
      </property>
      <!-- 指定Hibernate配置属性 -->
      <property name="hibernateProperties">
      <props>
      <prop key="hibernate.dialect">
      org.hibernate.dialect.MySQLDialect
      </prop>
      <prop key="hibernate.show_sql">true</prop>
      </props>
      </property>
      </bean>

    使用HibernateTemplate

    Spring提供了使用模板的支持类HibernateDapSupport, 并通过getHibernateTemplate()方法向子类开发模板类实例的调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 保存实体对象
    getHibernateTemplate().save(forum);

    // 更改实体对象
    getHibernateTemplate().update(forum);

    // 获取实体对象
    getHibernateTemplate().get(Forum.class, forumId);

    // 使用HQL查询
    getHibernateTemplate().find("from Forum f where f.forumName like ?", forumName + "%");

    // 使用Iterate返回结果
    getHibernateTemplate().iterate("select count(f.forumId) from Forum f").next();
    1. 常用的API方法

      • Serializable save(Object entity): 保存实体对象, 并返回主键值. void persist(Object entity)方法类似
      • void update(Object entity): 更新实体对象
      • void saveOrUpdate(Object entity): 保存或更新一个实体. 与<T> T merge(T entity)方法类似
      • void delete(Object entity): 删除一个实体
      • List find(String queryString): 根据HQL查询实体.
      • List findByNamedQuery(String queryName): 执行命名查询
      • List findByCriteria(DetachedCriteria criteria): Criteria版本查询.
    2. 使用回调接口

      Spring定义了一个回调接口HibernateCallback, 该接口有唯一方法:

      1
      T (Session session) throws HibernateException, SQLException

      该接口配合HibernateTemplate进行工作, 无须关系Hibernate Session的打开/关闭操作, 仅需要定义数据访问逻辑即可.

      • T execute(HibernateCallback action): 执行更新, 新增等炒作
      • List executeFind(HibernateCallback<?> action): 执行数据查询操作, 返回的结果是List
      1
      2
      3
      4
      5
      6
      getHibernateTemplate().execute(new HibernateCallback<Long>() {
      public Long (Session session) throws HibernateException, SQLException {
      Object obj = session.createQuery("select count(f.forumId) from Forum f").list.interator().next();
      return (Long) obj;
      }
      });
    3. 在Spring中配置DAO

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      <context:component-scan base-package="com.smart"/>
      <context:property-placeholder location="classpath:jdbc.properties"/>
      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/>
      <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" p:dataSource-ref="dataSource">

      <property name="mappingLocations">
      <list>
      <value>classpath*:/com/smart/org/domain/Forum.hbm.xml</value>
      </list>
      </property>
      <!-- 指定Hibernate配置属性 -->
      <property name="hibernateProperties">
      <props>
      <prop key="hibernate.dialect">
      org.hibernate.dialect.MySQLDialect
      </prop>
      <prop key="hibernate.show_sql">true</prop>
      </props>
      </property>
      </bean>
      <!-- 配置HibernateTemplate Bean -->
      <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate" p:sessionFactory-ref="sessionFactory"/>
      <!-- 配置Hibernate事务管理器 -->
      <bean id="transactionManager" class="org.srpingframework.orm.hibernate5.HibernateTrancactionManager" p:sessionFactory-ref="sessionFactory"/>
      <tx:annotation-driven transaction-manager="transactionManager"/>

    处理LOB类型数据

    Hibernate定义了一个接口: org.hibernate.usertype.UserType

    Spring提供了几个UserType的实现类, 可以在Hinerbate的映射文件中直接使用这些实现类轻松处理了LOB类型的数据

    • BlobByteArrayType: 将BLOB数据映射为byte[]类型的属性
    • BlobStringType: 将BLOB数据映射为String类型的属性
    • BlobSerializableType: 将BLOB数据映射为Serializable类型的属性
    • ClobStringType: 将CLOB数据映射为String类型的属性

    添加Hibernate事件监听器

    LocalSessionFactoryBean允许通过eventListeners属性向Hibernate注册事件监听器

    Spring本身提供了一个Hibernate事件监听器IdTransferringMergeEventListen 大专栏  Blue的博客er

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="eventListeners">
    <map>
    <!-- 事件监听器类型 -->
    <entry key="merge">
    <!-- 事件监听器实现类 -->
    <bean class="org.springframework.orm.hibernate5.support.IdTransferringMergeEventListener" />
    </entry>
    </map>
    </property>
    </bean>

    Hibernate预定义的类型: auto-flush, mrege, create, delete, dirty0check, evict, flush, flush-entity, load, load-collectioin, lock, refresh, replicate, save-update

    使用注解配置

    使用注解对Forum进行ORM配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    @Table(name="t_forum")
    public class Forum implements Serializable {
    @Id
    @Column(name="forum_id")
    private int forumId;

    @Column(name="forum_name")
    prvate String forumName;

    @Column(name="forum_desc")
    private String forumDesc;

    // setter, getter
    }

    Hiberante通过AnnotationConfiguration的addAnnotatedClass()或addPackage()方法加载使用JPA注解的实体类, 获取映射的元数据信息, 并在此基础上创建SessionFactory实例.

    addPackage并不是价值类包下所有标注了ORM注解的实体类, 而是加载类包下package-info.java文件中定义的Annotation

    使用AnnotationSessionFactoryBean创建基于JPA注解的SessionFactory

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 通过AnnotationSessionFactoryBean定义SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.annotation.AnnotationSessionFactoryBean" p:dataSource-ref="dataSource">
    <property name="packagesToScan" value="com.smart.orm.domain" />
    <property name="annotatedClasses">
    <list>
    <value>com.smart.orm.domain.Forum</value>
    </list>
    </property>
    </bean>

    延迟加载问题

    Hibernate允许对关联对象, 属性进行延迟加载, 但必须保证延迟加载的操作限于同一个Hibernate Session范围内.

    Spring为此专门提供了一个OpenSessionInViewFilter过滤器, 主要功能是使每个请求过程绑定一个HibernateSession, 即使最初的事务已经完成, 也可以在Web层进行延迟加载操作.

    OpenSessionInViewFilter将Hibernate Session绑定到请求线程中, 它将自动被Spring的事务管理器探测到

    在Spring中使用MyBatis

    MyBatis要求开发者编写具体的SQL语句.

    配置SqlMapClient

    每个MyBatis应用程序都以一个SqlSessionFactory对象的实例为核心.

    SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来获取.

    SqlSessionFactoryBuilder对象可以从XML配置文件或Configuration类的实例中构建SqlSessionFactory对象

    MyBatis配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration PUBLIC "-//mybatic.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    <!-- 可控制MyBatis框架允许行为的属性信息 -->
    <settings>
    <setting name="lazyLoadingEnabled" value="false"/>
    </settings>
    <!-- 定义全限定类名的别名, 在映射文件中通过别名代替具体的类名 -->
    <typeAliases>
    <typeAlias alias="Forum" type="com.smart.orm.domain.Forum"/>
    </typeAliases>
    <!-- 映射文件 -->
    <mappers>
    <mapper resource="com/smart/orm/domain/mybatis/Forum.xml"/>
    </mappers>
    </configuration>

    在Spring中配置MyBatis

    1
    2
    3
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:myBatisConfig.xml"/>

    SqlSessionFactoryBean提供了mapperLocations属性, 支持扫描式加载SQL映射文件

    1
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:myBatisConfig.xml" p:mapperLocations="classpath:com/smart/orm/domain/mybatis/*.xml"/>

    编写MyBatis的DAO

    1. 使用SqlSessionTemplate

      1
      2
      3
      <bean class="org.mybatis.spring.SqlSessionTemplate">
      <constructor-arg ref="sqlSessionFactory"/>
      </bean>

      使用SqlSessionTemplate调用SQL映射项完成数据访问操作

      1
      2
      3
      4
      @Autowired
      private SqlSessionTemplate sessionTemplate;
      // 通过selectOne()方法调用Forum.xml映射文件中定义的命名空间为com.smart.orm.dao.mybatic.ForumMybatisDao, 映射项id为getForum的SQL映射项, 并传入参数
      sessionTemplate.selectOne("com.smart.orm.dao.mybatic.ForumMybatisDao.getForum", forumId);

      SqlSessionTemplate模板类提供了多个方便调用的方法

      • List<?> selectList(String statement, Object parameter): 调用select映射项, 返回一个结果对象集合
      • int insert(String statement, Object parameter): 调用insert映射项, 返回插入的记录数
      • int update(String statement, Object parameter): 调用update映射项, 返回更改的记录数
    2. 使用映射接口

      MyBatis提供了一种可将SQL映射文件中的映射项通过名称匹配接口进行调用的方法: 接口名称和映射命名空间相同, 接口方法和映射元素的id相同

      为Forum.xml文件的映射项定义调用接口

      1
      2
      3
      public interface ForumMybatisDao {
      Forum getForum(int forumId);
      }

      Forum.xml文件中的每个映射项对应一个接口方法, 接口方法的签名和映射项的声明匹配

      通过SqlSessionTemplate获取接口的实例

      1
      2
      ForumMybatisDao forumMybatisDao = sessionTemplate.getMapper(ForumMybatisDao.class);
      forumMybatisDao.getForum(forumId);

      mybatis-spring提供了一个转换器MapperScannerConfigurer, 可以将映射接口直接转换为Spring容器中的Bean, 这样就可以在Service汇总注入映射接口的Bean了.

      如下配置即可将接口转换为Bean

      1
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:sqlSessionFactory-ref="sqlSessionFactory" p:basePackage="com.smart.orm.dao.mybatis"/>

      MapperScannerConfigurer将扫描basePackage所指定的包下的所有接口(包括子包), 如果它们在SQL映射文件中定义过, 则将它们动态定义为一个Spring Bean, 这样就可以在Service中直接注入映射接口的Bean

  • 相关阅读:
    计算机视觉在生物力学和运动康复中的应用和研究
    摄影测量(计算机视觉)中的三角化方法
    用于机器人导航辅助的6自由度姿态估计的平面辅助视觉惯性里程计
    一文详解固态激光雷达的里程计(loam_livox)
    聊聊这两年学习slam啃过的书
    一种用于三维物体建模的精确、鲁棒的距离图像配准算法
    汇总|实时性语义分割算法(全)
    Crypto练习之CRC32应用
    Lower-SQL至系统沦陷
    Crypto练习之替换密码
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12239893.html
Copyright © 2011-2022 走看看