0%

前一阵子接手了一个使用SpringBoot 和spring-data-jpa开发的项目

后期新加入一个小伙伴,表示jpa相比mybatis太难用,多表联合的查询写起来也比较费劲,所以便加入了mybatis的支持

开始的时候

@Configuration @EnableJpaRepositories(“com.xxx.xxx.repository”)
class JpaConfig

使用这种方式去配置的jpa,遇到一个问题,就是能select 但是不能save,所以就修改为配置文件的方式:

下面直接上配置文件:

1、spring的配置

复制代码

<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:tx=“http://www.springframework.org/schema/tx“ xmlns:aop=“http://www.springframework.org/schema/aop“ xmlns:task=“http://www.springframework.org/schema/task“ 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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd

    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"\>

<!-- 扫描注解文件 \-->
<context:component-scan base-package\="com.xxx"/>
<task:annotation-driven/>

<bean id\="springContextHolder" class\="com.xxx.common.config.SpringContextHolder" lazy-init\="false"\></bean\>

<bean id\="configProperties" class\="org.springframework.beans.factory.config.PropertiesFactoryBean"\>
    <property name\="locations"\>
        <list\>
            <value\>classpath\*:jdbc.properties</value\>
            <value\>classpath\*:app.properties</value\>
        </list\>
    </property\>
</bean\>

<bean id\="propertyConfigurer" class\="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"\>
    <property name\="systemPropertiesModeName" value\="SYSTEM\_PROPERTIES\_MODE\_OVERRIDE"/>
    <property name\="fileEncoding" value\="UTF-8"/>
    <property name\="properties" ref\="configProperties"/>
</bean\>

<!-- dataSource 配置 \-->
<bean id\="dataSource" class\="com.alibaba.druid.pool.DruidDataSource" init-method\="init" destroy-method\="close"\>
    <!-- 基本属性 url、user、password \-->
    <!-- <property name="driverClassName" value="${ds.driverClassName}" /> \-->
    <property name\="url" value\="${ds.url}"/>
    <property name\="username" value\="${ds.username}"/>
    <property name\="password" value\="${ds.password}"/>

    <!-- 配置初始化大小、最小、最大 \-->
    <property name\="initialSize" value\="${ds.initialSize}"/>
    <property name\="minIdle" value\="${ds.minIdle}"/>
    <property name\="maxActive" value\="${ds.maxActive}"/>

    <!-- 配置获取连接等待超时的时间 \-->
    <property name\="maxWait" value\="${ds.maxWait}"/>

    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 \-->
    <property name\="timeBetweenEvictionRunsMillis" value\="${ds.timeBetweenEvictionRunsMillis}"/>

    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 \-->
    <property name\="minEvictableIdleTimeMillis" value\="${ds.minEvictableIdleTimeMillis}"/>

    <property name\="validationQuery" value\="${ds.validationQuery}"/>
    <property name\="testWhileIdle" value\="${ds.testWhileIdle}"/>
    <property name\="testOnBorrow" value\="${ds.testOnBorrow}"/>
    <property name\="testOnReturn" value\="${ds.testOnReturn}"/>

    <!-- 打开PSCache,并且指定每个连接上PSCache的大小 \-->
    <property name\="poolPreparedStatements" value\="${ds.poolPreparedStatements}"/>
    <property name\="maxPoolPreparedStatementPerConnectionSize" value\="${ds.maxPoolPreparedStatementPerConnectionSize}"/>

    <!-- 配置监控统计拦截的filters \-->
    <property name\="filters" value\="${ds.filters}"/>

    <!-- 关闭abanded连接时输出错误日志 \-->
    <property name\="logAbandoned" value\="${ds.logAbandoned}"/>
</bean\>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 \-->
<bean id\="sqlSessionFactory" class\="org.mybatis.spring.SqlSessionFactoryBean"\>
    <property name\="dataSource" ref\="dataSource"/>
    <property name\="configLocation" value\="classpath:mybatis-config.xml"/>
    <property name\="typeAliasesPackage" value\="com.xxx.culture.domain"/>
    <!-- 自动扫描mapping.xml文件 \-->
    <property name\="mapperLocations" value\="classpath:mapper/\*\*/\*.xml"/>
</bean\>

<!-- DAO接口所在包名,Spring会自动查找其下的类 \-->
<bean class\="org.mybatis.spring.mapper.MapperScannerConfigurer"\>
    <property name\="basePackage" value\="com.xxx.xxx.dao"/>

</bean\>

<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx \-->
<bean id\="transactionManager" class\="org.springframework.jdbc.datasource.DataSourceTransactionManager"\>
    <property name\="dataSource" ref\="dataSource"/>
</bean\>
<!-- 事务管理 通知 \-->
<tx:advice id\="txAdvice" transaction-manager\="transactionManager"\>
    <tx:attributes\>
        <!-- 对insert,update,delete 开头的方法进行事务管理,只要有异常就回滚 \-->
        <tx:method name\="insert\*" propagation\="REQUIRED" rollback-for\="java.lang.Throwable"/>
        <tx:method name\="update\*" propagation\="REQUIRED" rollback-for\="java.lang.Throwable"/>
        <tx:method name\="delete\*" propagation\="REQUIRED" rollback-for\="java.lang.Throwable"/>
        <tx:method name\="remove\*" propagation\="REQUIRED" rollback-for\="java.lang.Throwable"/>
        <tx:method name\="save\*" propagation\="REQUIRED" rollback-for\="java.lang.Throwable"/>
        <tx:method name\="add\*" propagation\="REQUIRED"/>
        <tx:method name\="flush\*" propagation\="REQUIRED"/>
        <!-- select,count,get,find开头的方法,开启只读,提高数据库访问性能 \-->
        <tx:method name\="select\*" read-only\="true"/>
        <tx:method name\="count\*" read-only\="true"/>
        <tx:method name\="get\*" read-only\="true"/>
        <tx:method name\="find\*" read-only\="true"/>
        <tx:method name\="search\*" read-only\="true"/>
        <!-- 对其他方法 使用默认的事务管理 \-->
        <tx:method name\="\*"/>
    </tx:attributes\>
</tx:advice\>

<!-- 事务 aop 配置 com.xxx.smp.service..\*Impl.\*(..)) \-->
<aop:config\>
    <aop:pointcut id\="serviceMethods" expression\="execution(\* com.xxx.xxx.service..\*(..))"/>
    <aop:advisor advice-ref\="txAdvice" pointcut-ref\="serviceMethods"/>
</aop:config\>
<!-- 配置使Spring采用CGLIB代理 \-->
<aop:aspectj-autoproxy proxy-target-class\="true"/>
<!-- 事务注解支持 \-->
<tx:annotation-driven transaction-manager\="transactionManager"/>

<import resource\="applicationContext-jpa.xml"/>

</beans>

复制代码

2、jpa的配置

初始时遇到一个问题:jpa org.hibernate.LazyInitializationException: could not initialize proxy - no Session

在这儿找到了答案http://my.oschina.net/alexgaoyh/blog/313541

配置如下

复制代码

<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:jpa=“http://www.springframework.org/schema/data/jpa“ xsi:schemaLocation=“http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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“ >

<bean id\="entityManagerFactory" class\="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"\>
    <!-- 指定数据源 \-->
    <property name\="dataSource" ref\="dataSource"/>
    <!-- 指定Entity实体类包路径 \-->
    <property name\="packagesToScan"\>
        <list\>
            <value\>com.xxx.xxx.jpadomain</value\>
        </list\>
    </property\>
    <!-- 指定JPA属性;如Hibernate中指定是否显示SQL的是否显示、方言等 \-->
    <property name\="jpaVendorAdapter"\>
        <bean class\="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"\>
            <!-- 是否生成ddl文件 \-->
            <property name\="generateDdl" value\="true"/>
            <!-- 是否展示sql \-->
            <property name\="showSql" value\="false"/>
            <!-- 必要的数据库库使用的详细信息 \-->
            <property name\="databasePlatform" value\="org.hibernate.dialect.MySQLDialect"/>
            <!-- mysql,自行选择 \-->
            <property name\="database" value\="MYSQL"/>
        </bean\>
    </property\>
    <property name\="jpaProperties"\>
        <props\>
            <prop key\="hibernate.ejb.naming\_strategy"\>org.hibernate.cfg.ImprovedNamingStrategy </prop\>
            <prop key\="hibernate.hbm2ddl.auto"\>update</prop\>
            <prop key\="hibernate.enable\_lazy\_load\_no\_trans"\>true</prop\>
        </props\>
    </property\>
</bean\>

<!-- Spring Data Jpa配置 \-->

<!-- 配置 启用扫描并自动创建代理的功能  factory-class="com.monk.base.jpa.PeakJpaRepositoryFactory"自己定义的bean注解方式,可以不写,直接注解所有包下的 \-->
<jpa:repositories base-package\="com.xxx.xxx.repository" transaction-manager-ref\="transactionManager" entity-manager-factory-ref\="entityManagerFactory"/>

<!-- Jpa 事务配置 \-->
<bean id\="transactionManager" class\="org.springframework.orm.jpa.JpaTransactionManager"\>
    <property name\="entityManagerFactory" ref\="entityManagerFactory"/>
</bean\>

<!-- 开启注解事务 \-->
<tx:annotation-driven transaction-manager\="transactionManager" proxy-target-class\="true"/>

</beans>

复制代码