您的位置:首页 > 职场人生

【面试之持久化框架】hibernate、mybatis、jpa规范

2016-03-04 10:46 621 查看
1.hibernate 和 mybatis 的区别

·实现上的区别:mybatis只有一个核心jar包,另外和spring整合需要mybatis-spring的jar包,使用缓存需要mybatis-ehcache的jar包,而hibernate需要一系列的jar包,这也侧面反映了mybatis相对小巧,简单,而hibernate相对来说比较强大,复杂;mybatis的配置主要包括一个用于映射各种类的xml文件以及和实体类一一对应的映射文件,hibernate包括hibernate.cfg.xml和实体类的配置文件hibernate.hbm.xml。

·hibernate属于全自动的ORM框架,着力点在于POJO和数据库表之间的映射,完成映射即可自动生成和执行sql;而mybatis相对来说属于半自动的ORM框架,着力点在于POJO和SQL之间的映射,自己编写sql语句,然后通过配置文件将所需的参数和返回的字段映射到POJO。如果说hibernate属于ORM Mapping,那么mybatis相当于SQL Mapping.

·从上面的描述也可以看出,hibernate整合的项目比mybatis整合的项目更容易移植,因为hibernate使用的HQL语句与具体的数据库无关,而mybatis编写的sql语句都是和数据库相关联的,可移植性差。

·hibernate拥有自己的日志统计slf4j,而mybatis自身不带有日志记录。

·缓存方面,都可以使用第三方的缓存。hibernate有一级缓存和二级缓存之分,一级缓存属于session级别的缓存,需要对session的生命周期进行管理,二级缓存属于sessionFactory级别的缓存;mybatis虽然也有一级缓存,但是和spring整合使用时每次都是重新打开一个session进行操作,所以是无法使用,当然可以开启二级缓存,被所有sqlsessiong共享。

·mybatis需要手动写sql语句,这既是好的一面也是不好的一面,与hibernate相比好的一面在于可以高度优化sql语句以提升系统性能;不好的一面在于工作量相对比较大;如果牵扯到数据库的修改,则mybatis相对于hibernate的修改量更大

·学习成本上,hibernate相对来说,周期比较长。

第三方缓存 ehcache配置:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">

<!-- Sets the path to the directory where cache .data files are created.

If the path is a Java System Property it is replaced by
its value in the running VM.

The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir"/>

<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.

The following attributes are required for defaultCache:

maxInMemory       - Sets the maximum number of objects that will be created in memory
eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.

-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>

<!--Predefined caches.  Add your cache configuration settings here.
If you do not have a configuration for your cache a WARNING will be issued when the
CacheManager starts

The following attributes are required for defaultCache:

name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
maxInMemory       - Sets the maximum number of objects that will be created in memory
eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.

-->

<!-- Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes.

If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
//秒-->
<cache name="parameterCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="300"
overflowToDisk="false"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>

<!-- Sample cache named sampleCache2
This cache contains 1000 elements. Elements will always be held in memory.
They are not expired. -->
<!--  <cache name="sampleCache2"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/> -->

<!-- Place configuration for your caches following -->

</ehcache>
micro(比较全的配置)

<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>

<cache
name="com.raipeng.micro.core.module.common.entity.ConfigEntity"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
eternal="true"
overflowToDisk="true"
diskSpoolBufferSizeMB="50"
/>


mybatis的一些配置

mybatisconfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.*.sales.entity"/>
</typeAliases>
<mappers>
<mapper resource="com/*/sales/front/repository/mybatis/sales.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/saleOrder.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/distributorAccount.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/snsUser.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/rechargeOrder.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/poster.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/withdrawRecord.xml"/>
<mapper resource="com/*/sales/front/repository/mybatis/flowProduct.xml"/>
</mappers>
</configuration>
其中一个pojo

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.*.sales.entity.DistributorAccount">
<resultMap id="distributorAccountResultMap" type="distributorAccount">
<id property="id" column="id"></id>
<result property="operatorId" column="operator_id"></result>
<result property="orderNo" column="orderno"></result>
<result property="price" column="price"></result>
<result property="mobile" column="mobile"></result>
<result property="flowPackage" column="flow_package"></result>
<result property="operatorType" column="operator_type"></result>
<result property="status" column="status"></result>
<result property="createdDate" column="created_date"></result>
<result property="finishDate" column="finish_date"></result>
<result property="lastModified" column="last_modified"></result>
<result property="remark" column="remark"></result>
<result property="sellerId" column="seller_id"></result>
<result property="version" column="version"></result>
<result property="refundOperatorId" column="refund_operator_id"></result>
</resultMap>

<select id="selectDistributorAccountList" parameterType="distributorAccountForm" resultMap="distributorAccountResultMap">
select o.* from rp_app_account o
<where>
o.seller_id = #{operatorId}
<if test="beginDateStr != null and beginDateStr != ''">
AND DATE_FORMAT(o.last_modified,'%Y-%m-%d') >= str_to_date(#{beginDateStr},'%Y-%m-%d')
</if>
<!--%Y-%m-%d %H:%i:%s-->
<if test="endDateStr != null and endDateStr != ''">
<![CDATA[
and DATE_FORMAT(o.last_modified,'%Y-%m-%d') <= str_to_date(#{endDateStr},'%Y-%m-%d')
]]>
</if>
<if test="operatorType != null and operatorType != ''">
and o.operator_type = #{operatorType}
</if>
</where>
order by o.last_modified desc
limit #{offset},#{pageSize}
</select>

<insert id="saveDistributorAccount" >
insert into rp_app_account (operator_id,orderno,price,mobile,flow_package,operator_type,status,created_date,finish_date,last_modified,remark,seller_id,version)
values (#{operatorId},#{orderNo},#{price},#{mobile},#{flowPackage},#{operatorType},#{status},now(),#{finishDate},now(),#{remark},#{sellerId},#{version})
</insert>

<update id="updateStatusByOrderNo" >
update rp_app_account set status = #{status} ,last_modified = now(),refund_operator_id = #{refundOperatorId} where orderno = #{orderNo}
</update>
</mapper>
DaoImpl继承该抽象类即可使用sqlsession

import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;

/**
*
* @author
*
*/
public abstract class AbstractMyBatisBaseRepository extends
SqlSessionDaoSupport {
@Autowired
public final void init(SqlSessionTemplate sessionTemplate) {
this.setSqlSessionTemplate(sessionTemplate);
}
}


和spring整合的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
<context:property-placeholder location="classpath:sysconfig.properties" />

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.mysql.driverClassName}"
p:url="${jdbc.mysql.url}" p:username="${jdbc.mysql.username}"
p:password="${jdbc.mysql.password}" p:maxActive="100000" p:maxIdle="10"
p:testOnBorrow="true" p:validationQuery="select 1" >

<description>开发环境本地库配置</description>
</bean>

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

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="mod*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="find*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="load*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="query*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="export*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="cancle*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="logout*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>

<!-- 通过AOP实现横向切入 -->

<aop:config>
<aop:advisor pointcut="execution(* com.raipeng.sales.*.service.*.*(..))" advice-ref="txAdvice" />
</aop:config>
</beans>
配置cache

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <context:component-scan base-package="com.raipeng.sales" />
<tx:annotation-driven />

<cache:annotation-driven cache-manager="cacheManager" />

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcache" />

<!-- Ehcache library setup -->
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml" />

</beans>
都导入到spring配置文件中,用import

jpa的配置文件persistenceContext.xml,hibernate实现

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> 
<jpa:repositories base-package="com.raipeng.micro.core.module.**.dao" />

<jpa:auditing/>

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

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
p:jndiName="java:comp/env/jdbc/microDB"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:packagesToScan="com.raipeng.micro.core.module.**.entity"
p:jpaVendorAdapter-ref="jpaVendorAdapter"
p:jpaProperties-ref="jpaProperties"/>

<util:properties id="jpaProperties">
<prop key="hibernate.show_sql">${config.hibernate.show.sql}</prop>
<prop key="hibernate.format_sql">${config.hibernate.show.sql}</prop>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="javax.persistence.validation.mode">none</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.provider_configuration">ehcache.xml</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="javax.persistence.sharedCache.mode">ENABLE_SELECTIVE</prop>
</util:properties>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

</beans>


spring配置文件中

<import resource="classpath*:persistenceContext.xml"/>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: