前一阵子接手了一个使用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>