XML方式配置
环境搭建
Maven依赖
<!--mybatis的依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.24</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency> <!--mybatis兼容spring的补丁-->
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!--spring的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.17</version>
</dependency>
<!--阿里巴巴的druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
druid的配置文件druid.properties
druid.driver=com.mysql.cj.jdbc.Driver
druid.url=jdbc:mysql:///user?useSSL=false&serverTimezone=UTC
druid.username=userName
druid.password=password
druid.pool.init=100
druid.pool.minIdle=50
druid.pool.maxActive=300
druid.pool.timeout=30000
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: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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/context/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解配置-->
<context:annotation-config/>
<!--扫描注解类所在的包-->
<context:component-scan base-package="xin.students"/>
<!--加载.properties类型的文件,这里加载的druid的配置文件-->
<context:property-placeholder location="classpath:druid.properties"/>
<!--通过spring创建druid的DataSource的创建-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--直接使用类的bean创建-->
<property name="driverClassName" value="${druid.driver}"/>
<property name="url" value="${druid.url}"/>
<property name="username" value="${druid.username}"/>
<property name="password" value="${druid.password}"/>
<property name="initialSize" value="${druid.pool.init}"/>
<property name="minIdle" value="${druid.pool.minIdle}"/>
<property name="maxActive" value="${druid.pool.maxActive}"/>
<property name="maxWait" value="${druid.pool.timeout}"/>
</bean>
<!--通过spring创建mybatis补丁的SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--[必须]装填数据源-->
<property name="dataSource" ref="druidDataSource"/>
<!--[必须,如家加载mybatis的配置文件了就可选]添加mybatis接口类的映射文件,-->
<!--target->classes即为classpath,任何我们需要在classpath前缀中获取的资源都必须在target->classes文件夹中找到。
但是在idea项目中只有被标记为Resource Folders的文件夹下的文件才会被添加至target->classes。-->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
<!--[可选]给包下的类启动起别名-->
<property name="typeAliasesPackage" value="xin.students.pojo"/>
<!--[可选]加载mybatis的主配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--
类似于执行下面的两句话
SqlSession session = sqlSessionFactory.openSession();
UserDao mapper = session.getMapper(UserDao.class);
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--加载sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--用sqlSessionFactory把该包下的所有接口都创建好,放入spring容器,获取时直接用ac.getBean("接口名[首字符小写]")-->
<property name="basePackage" value="xin.students.dao"/>
</bean>
<!--Spring提供的对mybatis的事务管理类-->
<bean id="myTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<!--配置数据源-->
<property name="dataSource" ref="druidDataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="myTransactionManager">
<tx:attributes>
<!--对于所有insert开头的方法,
[propagation="REQUIRED"([一般用于增删改]如果外层函数有事务,就把自身添加进去,如果没有事务就单独创建一个事务)],
[propagation="SUPPORTS"([一般用于查询]如果外层函数有事务,就把自身添加进去,如果没有事务就不开启事务)],
isolation[隔离级别]
READ_UNCOMMITTED(读未提交) READ_COMMITTED(读已提交) REPEATABLE_READ(可供复读) SERIALIZABLE((串行化3)-->
<tx:method name="insert" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
<tx:method name="delete" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
<tx:method name="update" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
<tx:method name="query" isolation="REPEATABLE_READ" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!--事务配置应该给一个service的一个业务,而不是dao中的一个方法-->
<aop:pointcut id="crud" expression="execution(* xin.students.dao.*.*(..))"/>
<!--配置通知类-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="crud"/>
</aop:config>
</beans>
项目结构
注解方式配置
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: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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/context/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解配置-->
<context:annotation-config/>
<!--扫描注解类所在的包-->
<context:component-scan base-package="xin.students"/>
<!--加载.properties类型的文件,这里加载的druid的配置文件-->
<context:property-placeholder location="classpath:druid.properties"/>
<!--通过spring创建druid的DataSource的创建-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--直接使用类的bean创建-->
<property name="driverClassName" value="${druid.driver}"/>
<property name="url" value="${druid.url}"/>
<property name="username" value="${druid.username}"/>
<property name="password" value="${druid.password}"/>
<property name="initialSize" value="${druid.pool.init}"/>
<property name="minIdle" value="${druid.pool.minIdle}"/>
<property name="maxActive" value="${druid.pool.maxActive}"/>
<property name="maxWait" value="${druid.pool.timeout}"/>
</bean>
<!--通过spring创建mybatis补丁的SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--[必须]装填数据源-->
<property name="dataSource" ref="druidDataSource"/>
<!--[必须,如家加载mybatis的配置文件了就可选]添加mybatis接口类的映射文件,-->
<!--target->classes即为classpath,任何我们需要在classpath前缀中获取的资源都必须在target->classes文件夹中找到。
但是在idea项目中只有被标记为Resource Folders的文件夹下的文件才会被添加至target->classes。-->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
<!--[可选]给包下的类启动起别名-->
<property name="typeAliasesPackage" value="xin.students.pojo"/>
<!--[可选]加载mybatis的主配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--
类似于执行下面的两句话
SqlSession session = sqlSessionFactory.openSession();
UserDao mapper = session.getMapper(UserDao.class);
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--加载sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--用sqlSessionFactory把该包下的所有接口都创建好,放入spring容器,获取时直接用ac.getBean("接口名[首字符小写]")-->
<property name="basePackage" value="xin.students.dao"/>
</bean>
<!--Spring提供的对mybatis的事务管理类-->
<bean id="myTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<!--配置数据源-->
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!--声明使用注解完成配置-->
<!--
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.SUPPORTS)
哪个方法[方法所在的类要在spring的容器中]需要事务,就给哪个方法加上这个注解
-->
<tx:annotation-driven transaction-manager="myTransactionManager"/>
</beans>
使用注解
前提是类必须是被spring管理的: @Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.SUPPORTS)
@Service
public class UserServiceImp implements UserService {
//@Autowired 是byType,@Resource 是先byName然后再byType
@Resource
UserDao userDao;
@Override
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.SUPPORTS)
public List<User> listUsers() {
return userDao.queryUsers();
}
}
扩展
注意事项
事务配置应该给一个service的一个业务,而不是dao中的一个方法.