将MyBatis 与Spring 进行整合,主要解决的问题就是将SglSessionFactory 对象交由Spring来管理。所以,该整合只需要将SglSessionFactory的对象生成器SgISessionFactoryBean注册在Spring 容器中,再将其注入给Dao 的实现类即可完成整合。实现Spring与MyBatis 的整合。常用的方式:扫描的Mapper 动态代理。Spring 像插线板一样,mybatis框架是插头,可以容易的组合到一起。插线板spring 插上mybatis, 两个框架就是一个整体。
首先创建两张表:
mysql> use ssm;
Database changed
mysql> drop table if exists users;
Query OK, 0 rows affected (0.78 sec)
mysql> drop table if exists accounts;
Query OK, 0 rows affected, 1 warning (0.14 sec)
mysql> create table users(
-> userid int primary key,
-> uname varchar(20),
-> upass varchar(20));
Query OK, 0 rows affected (1.05 sec)
mysql> create table accounts(
-> aid int primary key,
-> aname varchar(20),
-> acontent varchar(50));
Query OK, 0 rows affected (0.47 sec)
添加数据库的可视化:
<!--reasources里面的三个XML文件 -->
<!--SqlMapConfig的文件 -->
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--读取属性文件-->
<!-- <properties resource="jdbc.properties"></properties>-->
<!-- 在这里面设置setting可以用来显示日志-->
<!-- <typeAliases>-->
<!-- <!– 单个注册–>-->
<!-- <typeAlias type="org.example.pojo.student" alias="student"></typeAlias>-->
<!-- <!– 驼峰命名法注册,批量注册–>-->
<!-- <!– <package name="org.example.pojo"/>–>-->
<!-- </typeAliases>-->
<!-- <!–配置环境变量–>-->
<!-- <environments default="development">-->
<!-- <environment id="development">-->
<!-- <!– 这个transaction里面的JDBC表示的是由程序员自己来操作数据库–>-->
<!-- <transactionManager type="JDBC">-->
<!-- </transactionManager>-->
<!-- <!– 这个dataSource里面的POOLED表示的是-->
<!-- jndi表示在服务器端、TOMCAT端来进行数据库的控制-->
<!-- POOLED表示在数据连接池来进行数据库的操作-->
<!-- UNPOOLED表示不使用数据库连接池-->
<!--–>-->
<!-- <dataSource type="POOLED">-->
<!-- <property name="driver" value="${jdbc.driver}"/>-->
<!-- <property name="url" value="${jdbc.url}"/>-->
<!-- <property name="username" value="${jdbc.username}"/>-->
<!-- <property name="password" value="${jdbc.password}"/>-->
<!-- </dataSource>-->
<!-- </environment>-->
<!-- </environments>-->
<!-- <!– 注册map.xml文件–>-->
<!-- <mappers>-->
<!-- <mapper resource="单个mapper文件所在的路径xml文件"></mapper>-->
<!-- </mappers>-->
</configuration>
<!--applicationcontext_mapper的文件 -->
<?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/util"
xmlns:comtext="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 读取数据源配置文件-->
<comtext:property-placeholder location="jdbc.properties"></comtext:property-placeholder>
<!-- 创建数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
</bean>
<!-- 配置sqlSessionFactoryBeam实体类的文件-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--配置数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!--配置mybatis核心文件 -->
<property name="configLocation" value="SqlMapConfig.xml"></property>
<!-- 注册实体类的别名-->
<property name="typeAliasesPackage" value="org.example.pojo"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.example.mapper"></property>
</bean>
</beans>
<!--applicationcontext_service的文件 -->
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example.service"></context:component-scan>
<import resource="applicationcontext_mapper.xml"></import>
</beans>
这里主要展示一下,在UserSerImpl这里来进行UserMapper类的创建:
这里面用到了Autowired的注解
package org.example.service.Impl;
import org.example.mapper.UsersMapper;
import org.example.pojo.Users;
import org.example.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UsersService {
@Autowired
UsersMapper usersMapper;
@Override
public int insert(Users users) {
return usersMapper.insert(users);
}
}
事务管理器:(添加的annotation的注解是tx下面的)
<!-- 创建事务管理器-->
<bean name="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 创建事务管理器的驱动-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
</beans>
还需要再需要注解的上面来添加这两行的注解文件,再出错之后就会有事务的回滚机制就不会将数据库的内容更新
// 事务的传播特性,这里的propagation设置的是required
@Transactional(propagation = Propagation.REQUIRED)
@Service
还可以来设置不回滚,像这里的noRollbackForClassName
// 事务的传播特性,这里的propagation设置的是required
@Transactional(propagation = Propagation.REQUIRED,noRollbackForClassName = "ArithmeticException")
@Service
mysql默认的isolation是可重复读:
事务的两种处理方法:
数据库默认的隔离级别:
每一套框架都有不同的回滚和提交的机制
而mybatis框架使用的是dataSourceTransacationManager就是来创建之前的种种的
事务的传播特性:
常见的场景:
大项目一般都用声明式事务,小项目使用注解式事务:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="applicationcontext_mapper.xml"></import>
<!-- 添加包扫描-->
<context:component-scan base-package="org.example.service"></context:component-scan>
<!-- 添加事务管理器-->
<bean name="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice transaction-manager="dataSourceTransactionManager" id="myadvice">
<tx:attributes>
<tx:method name="**select**" read-only="true"/>
<tx:method name="**insert**" propagation="REQUIRED"/>
<tx:method name="**save**" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="mycut" expression="execution(* org.example.service..*.*(..))"/>
<aop:advisor advice-ref="myadvice" pointcut-ref="mycut"></aop:advisor>
</aop:config>
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
</beans>
加在类上面的注解对所有的类中的方法都起作用,所以需要这种办法,不去一个个去添加注解。
可以通过order来设置这里的优先级级别:
<aop:config>
<aop:pointcut id="mycut" expression="execution(* org.example.service..*.*(..))"/>
<aop:advisor advice-ref="myadvice" order="1" pointcut-ref="mycut"></aop:advisor>
</aop:config>
<tx:annotation-driven transaction-manager="dataSourceTransactionManager" order="100"></tx:annotation-driven>