Spring 整合 Mybatis
程序员文章站
2022-03-11 21:40:55
...
Spring整合MyBatis
前提
maven 3.6.0
IDEA 2017.02
Druid 数据源
MySQL 5.7
导入依赖
Spring 核心依赖
Spring -jdbc 依赖
Mybatis 依赖
Spring和 MyBtis 的整合依赖
数据库驱动
连接池
依赖配置文件
如果 Mybatis 使用的是 3.X版本 整合包 需要使用 1.3.0 以上的版本
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!-- 如果 Mybatis 使用的是 3.X版本 整合包 需要使用 1.3.0 以上的版本 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
新建目录结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yD1nTe3a-1574059427678)(04- Spring整合Mybatis.assets/1573717415644.png)]
创建Mapper 接口和映射文件
Mapper 接口
public interface UserMapper {
List<User> selectAll();
}
在 resources 中新建一个 mapper 目录 专门存储 sql 映射文件
注意保持四个一致
<?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">
<!--namespace 命名空间-->
<mapper namespace="cn.bdqn.mapper.UserMapper">
<select id="selectAll" resultType="user">
SELECT * FROM smbms_user
</select>
</mapper>
maven 中 默认 不会加载 java 目录中的配置文件
在pom.xml 文件中
<!-- 去加载 src/main/java 中的 sql 映射文件 -->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>true</filtering>
</resource>
</resources>
创建Spring核心配置文件
创建数据源
<!-- 配置数据源连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/smbms"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
创建sqlsessionFactory
<!-- 配置 Mybatis SQLSession 工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 工厂依赖于数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置别名 -->
<property name="typeAliasesPackage" value="cn.bdqn.pojo"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
测试流程
新建UserService 层
public class UserService {
private UserMapper mapper ;
public void setMapper(UserMapper mapper) {
this.mapper = mapper;
}
public void selectAll(){
List<User> users = mapper.selectAll();
for(User user : users){
System.out.println(user.getUserName()+ "\t" + user.getUserPassword());
}
}
}
测试类
@Test
public void test() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) app.getBean("userService");
userService.selectAll();
}
添加所需要的bean
UserService
<bean id="userService" class="cn.bdqn.service.UserService">
<property name="mapper" ref="userMapper"/>
</bean>
mapper
<!-- 配置mapper 对象
扫描 basePackage 包中的所有的 mapper 接口
自动生成 以该接口名称(首字母小写的)命名的 bean
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.bdqn.mapper"/>
</bean>
事务 配置
把拥有多个步骤的事情 看做是一件事情
中间任意一个步骤出现问题, 整件事件失败
事务四大特性
原子性
整体性(一致性)
隔离性
持久性
转账案例
引入aop 的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
1- 数据库设计
USE `smbms`;
/*Table structure for table `account` */
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`id` int(5) NOT NULL,
`name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`balance` int(5) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*Data for the table `account` */
insert into `account`(`id`,`name`,`balance`) values
(10010,'李四',5000),
(10086,'张三',5000);
2- mapper接口
public interface AccountMapper {
/**
* 银行转账 转出方
* outId 转出方 id
* money 转出金额
*/
boolean out(@Param("id") int outId ,@Param("money") double money);
/**
* 银行转账 转入方
* inId 转入方 id
* money 转入金额
*/
boolean in(@Param("id") int inId ,@Param("money") double money);
}
3- mapper sql 映射文件
<?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">
<!--namespace 命名空间-->
<mapper namespace="cn.bdqn.mapper.AccountMapper">
<update id="out" >
UPDATE account SET balance = balance - #{money} WHERE id = #{id}
</update>
<update id="in" >
UPDATE account SET balance = balance + #{money} WHERE id = #{id}
</update>
</mapper>
4- AccountService
public class AccountService {
private AccountMapper mapper;
public void setMapper(AccountMapper mapper) {
this.mapper = mapper;
}
public boolean transfer(int outid, int inid, double money){
// 转出
boolean out = mapper.out(outid, money);
int i = 1/0;
// 转入
boolean in = mapper.in(inid, money);
return out && in;
}
}
5- spring核心配置文件
<!-- 声明一个 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--AOP 理念-->
<!-- 配置增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" />
</tx:attributes>
</tx:advice>
<!-- 配置连接点和切入点 -->
<aop:config>
<aop:pointcut id="pointcutId" expression="execution(* cn..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcutId"/>
</aop:config>
6- 测试
public class AccountTest {
@Test
public void transferTest(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = (AccountService) app.getBean("accountService");
accountService.transfer(10086, 10010, 1000);
}
}
使用注解
配置文件开启注解支持
<!-- 声明一个 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启注解扫描 -->
<context:component-scan base-package="cn.bdqn.service"/>
<!-- 开启 注解式 事务配置 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在需要使用事务的方法上添加注解
@Service
public class AccountService {
@Autowired
private AccountMapper mapper;
public void setMapper(AccountMapper mapper) {
this.mapper = mapper;
}
@Transactional
public boolean transfer(int outid, int inid, double money){
// 转出
boolean out = mapper.out(outid, money);
int i = 1/0;
// 转入
boolean in = mapper.in(inid, money);
return out && in;
}
}
事务的详细配置
传播行为
事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。
如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
一般 查询方式使用该方式
隔离级别
隔离级别 | 对应值 | 可能产生的问题 |
---|---|---|
读未提交 | read_uncommitted | 脏读 |
读已提交 | read_committed | 不可重复读 |
可重复读 | repeatable | 幻读 |
串行化 | serializable | 没有问题 |
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
只读
read-only
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,readOnly = true)
事务超时时间设定
timeout
触发回滚的异常类型
rollback-for
no-rollback-for
// 一旦出现 空指针异常 , 回滚操作
@Transactional(rollbackFor = NullPointerException.class)
上一篇: R 一些非常用函数
推荐阅读
-
Spring4.0系列9-websocket简单应用
-
关于Modoer和Discuz整合有关问题
-
Spring Data Jpa 中级联操作CascadeType的含义
-
将Spring Boot程序打包成docker镜像-超简版
-
spring Boot环境下dubbo+zookeeper的一个基础讲解与示例
-
MyBatis的一级缓存、二级缓存演示以及讲解,序列化异常的处理
-
How to add OpenCV library in spring web application
-
java中Memcached的使用实例(包括与Spring整合)
-
spring mvc代码示例
-
MyBatis自定义SQL拦截器示例详解