【面试之持久化框架】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配置:
mybatis的一些配置
mybatisconfig.xml
和spring整合的配置文件
jpa的配置文件persistenceContext.xml,hibernate实现
spring配置文件中
·实现上的区别: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"/>
相关文章推荐
- iOS经典面试题总结--内存管理
- 关于最近遇到的一些iOS面试题<1>
- 每个程序员应该阅读的10本经典书籍
- Java线程面试题 Top 50
- 如何判断自己是否具有成为一名优秀程序员的潜质及如何成为一名优秀的程序员
- Java 线程面试问题
- 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
- iOS面试题
- leetcode之Lowest Common Ancestor of a Binary Search Tree
- 程序员技术练级攻略
- java面试题及答案(基础题122道,代码题19道)
- PHP:招PHP高级工程师的面试题
- 浅谈关于“中文编程”是否会成为中国程序员的一颗“银弹”
- 【转】每个程序员应该阅读的10本经典书籍
- .NET面试题解析(03)-string与字符串操作
- 自动化测试面试
- 面试总结 —— 高级JAVA工程师
- 码农十年连载一
- 什么是真正的程序员
- 什么是真正的程序员