Spring学习(十五)-整合Hibernate和Mybatis

Spring整合ORM技术

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

  • 方便基础设施的搭建:不同的ORM技术都有一套自己的方案以初始化框架、搭建基础设施等。在Spring中对于不同的ORM框架,首先,始终可以采用相同方式配置数据源;其次,Spring为不同的ORM框架提供相应的FactoryBean,用以初始化ORM框架的基础设施,可以将它们当做普通的Bean对待,唯一的差别只是属性的不同而已。
  • 异常封装:Spring能够转换各种ORM框架所抛出的异常,将ORM框架专有的或检查型异常转换为SpringDAO异常体系中的标准异常。
  • 统一的事务管理:Spring为不同的ORM框架提供了对应的事务管理器,可用声明的方式进行事务管理,并且可以透明地实现本地事务管理到全局JTA事务管理的切换。
  • 允许混合使用多个ORM框架:一般的增删改查使用Hibernate,而数据查询使用iBatis或Spring JDBC,强强联合。
  • 方便单元测试:Spring容器使得替换不同的实现和配置变得非常简单,这些内容包括:Hibernate SessionFactory的位置、JDBC DataSource、事务管理器以及映射对象的实现等,这样也就很容易隔离并测试不同的DAO类。

在Spring中使用Hibernate

Hibernate配置文件

......
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
	p:location="classpath:xxx/xxxx/xxx/jdbc.properties"
	p:fileEncoding="utf-8"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
	destroy-method="close"
	p:driverClassName="${driverClassName}"
	p:url="${url}"
	p:username="${userName}"
	p:password="${password}"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
	p:dataSource-ref="dataSource">
	<!-- 指定hibernate实体类映射文件-->
	<property name="mappingLocations">
		<list>
			<value>classpath*:/xxx/xxx/xxx/xxx.hbm.xml</value>
			<value>classpath*:/xxx/xxx/xxx/xxx.hbm.xml</value>
			<value>classpath*:/xxx/xxx/xxx/xxx.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>
....

数据源、映射文件以及Hibernate属性这三方面的信息在LocalSessionFactoryBean中得到了完美集成。

使用HibernateTemplate

.....
public class BaseDao{
	@Autowired
	private HibernateTemplate hibernateTemplate;
	.....
}

扩展这个BaseDao基类创建一个使用HibernateTemplate的Dao:

.........
@Repository
public class HibernateDao extends BaseDao{
	public void updateForum(Forum forum){
		getHibernateTemplate().update(forum);
	}
	.....
}

Spring中配置DAO

<context:component-scan base-package="xxx.xxx"/>
....
<!-- 配置HibernateTemplate Bean-->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"
	p:sessionFactory-ref="sessionFactory"/>
<!-- 配置Hibernate的事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
	p:sessionFactory-ref="sessionFactory"/>

<tx:annotation-driven transaction-manager="transactionManager"/>
....

在Spring配置文件中首先配置一个HibernateTemplate Bean,它基于SessionFactory工作,使用<context:component-scan>扫描特定的类包以启用注解驱动的Bean,这样@Repository和@Autowired注解就可以起作用,将HibernateDao装配为Spring容器中的Bean了。

Spring中使用MyBatis

配置SqlMapClient

每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来获得。SqlSessionFactoryBuilder对象可以从XML配置文件或Configuration类的实例中构建SqlSessionFactory对象。

mybatisConfig.xml

......
<configuration>
	<settings>
		<setting name="lazyLoadingEnabled" value="false"></setting>
	</settings>
	<typeAliases>
		<typeAliase alias="Forum" type="xxx.xxx.xxx.Forum"/>
		<typeAliase alias="Xxx" type="xxx.xxx.xxx.Xxx"/>
		<typeAliase alias="Xxx" type="xxx.xxx.xxx.Xxx"/>
	</typeAliases>
	<mappers>
		<mapper resource="xxx/xxx/xxx/mybatis/Forum.xml"/>
		<mapper resource="xxx/xxx/xxx/mybatis/Xxx.xml"/>
		<mapper resource="xxx/xxx/xxx/mybatis/Xxx.xml"/>
	</mappers>
</configuration>

<settings>控制mybatis框架运行行为的属性信息,<typeAliases>标签定义全限定类名的别名,在映射文件中可以通过别名代替具体的类名。<mappers>将所有mybatis的映射文件组装起来。

Forum.xml

.....
<mapper namespace="xxx.xxx.xxx.mybatis.MybatisDao">①
	<select id="getForum" resultType="Forum" parameterType="int">
		SELECT
			forum_id forumId,
			forum_name forumName,
			forum_desc forumDesc
		FROM t_forum
		WHERE forum_id=#{forumId}
	</select>
	<insert id="addForum" parameterType="Forum">
		INSERT INTO t_forum(forum_id,forum_name,forum_desc)
		VALUES(#{forumId},#{forumName},#{forumDesc})
	</insert>
	<update id="updateForum" parameterType="Forum">
		UPDATE t_forum f
		SET forum_name=#{forumName},forum_desc=#{forumDesc}
		WHERE f.forum_id = #{forumId}
	</update>
</mapper>

该文件定义了对Forum实体类进行数据操作时所需要的SQL语句,同时还定义了查询结果和对象属性的映射关系。在①处指定了映射所在的命名空间,每个具体的映射项都有一个id,可以通过命名空间和映射项的id定位具体的映射项,如通过如下语句可以调用getForum的映射语句:

SqlSession session = sqlMapper.openSession();
try{
	Forum forum = (Forum)session.selectOne("xxx.xxx.xxx.mybatis.MybatisDao.getForum",1);
}finally{
	session.close();
}

在Forum.xml中定义了一条SELECT、INSERT以及UPDATE语句映射项,映射项的parameterType指定传入的参数对象,可以是全限定名的类,也可以是类的别名,类别名在myBatis的主配置文件中定义。如果映射项的入参是基础类型或String类型,则可以使用如int、long、string的基础类型名。SELECT映射项拥有返回类型对象。通过resultType指定。映射项中通过#{xxx}绑定parameterType指定参数类的属性,支持级联属性,如#{topic.forumId}。

在Spring配置myBatis

......
<beans>
	<context:component-scan base-package="xxx.xxx.dao.mybatis"/>	
	<context:component-scan base-package="xxx.xxx.service.mybatis"/>
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
		p:location="classpath:xxx/xxxx/xxx/jdbc.properties"
		p:fileEncoding="utf-8"/>
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close"
		p:driverClassName="${driverClassName}"
		p:url="${url}"
		p:username="${userName}"
		p:password="${password}"/>
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
		p:dataSource-ref="dataSource"
		p:configLocation="classpath:mybatisConfig.xml"/>
</beans>

如果在mybatis配置文件mybatisConfig.xml中指定SQL映射文件,必须逐个列出所有的SQL映射文件,比较繁琐。我们可以先将映射文件匹配从mybatisConfig.xml中移除,然后通过<mapperLocations>加载SQL映射文件:

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

这样,SqlSessionFactoryBean将扫描xxx/xxx/xxx/mybatis类路径并加载所有以xml为后缀的映射文件。

使用SqlSessionTemplate

首先在Spring中配置好SqlSessionTemplate Bean:

<bean class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg ref="sqlSessionFactory"/>
</bean>
.......
@Repository
public class MybatisTemplateDao{
	@Autowired
	private SqlSessionTemplate sessionTemplate;
	
	public Forum getForum(int forumId){
		return (Forum)sessionTemplate.selectOne("xxx.xxx.xxx.mybatis.MybatisDao.getForum",forumId);
	}
}

SqlSessionTemplate通过selectOne()方法调用在Forum.xml映射文件中定义的命名空间为:xxx.xxx.xxx.mybatis.MybatisDao、映射项id为:getForum的SQL映射项,并传入参数,返回映射成Forum对象的查询结果。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot可以很方便地整合JPA和MyBatis整合JPA: 1. 在pom.xml中添加JPA依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 2. 配置数据源和JPA属性: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect ``` 3. 创建实体类和Repository接口: ``` @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; // getter和setter } public interface UserRepository extends JpaRepository<User, Long> { } ``` 4. 在Service中使用Repository: ``` @Service public class UserService { @Autowired private UserRepository userRepository; public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } public void saveUser(User user) { userRepository.save(user); } public void deleteUserById(Long id) { userRepository.deleteById(id); } } ``` 整合MyBatis: 1. 在pom.xml中添加MyBatis依赖: ``` <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.</version> </dependency> ``` 2. 配置数据源和MyBatis属性: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.example.demo.entity ``` 3. 创建实体类和Mapper接口: ``` public class User { private Long id; private String name; private Integer age; // getter和setter } @Mapper public interface UserMapper { User getUserById(Long id); void saveUser(User user); void deleteUserById(Long id); } ``` 4. 在Service中使用Mapper: ``` @Service public class UserService { @Autowired private UserMapper userMapper; public User getUserById(Long id) { return userMapper.getUserById(id); } public void saveUser(User user) { userMapper.saveUser(user); } public void deleteUserById(Long id) { userMapper.deleteUserById(id); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值