MyBatis与Spring的整合
环境搭建----
新建一个maven web项目
引入依赖—…
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>Spring_Mybatis</name>
<groupId>MyspringBatis</groupId>
<artifactId>Spring_Mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!--编译编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.7</version>
<configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8888</port>
<maxIdleTime>30000</maxIdleTime>
</connector>
</connectors>
<webAppSourceDirectory>${project.build.directory}/${project.artifactId}-${project.version}
</webAppSourceDirectory>
<contextPath>/</contextPath>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- SPRING 依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<!--数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--<spring 与mybatis中间件-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.18.RELEASE</version>
</dependency>
<!-- aop联盟-->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.3.0</version>
</dependency>
!<!-- 德鲁伊-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
配置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: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/tx/spring-tx.xsd">
<!-- 引入外部配置文件-->
<context:property-placeholder location="jdbc.properties"/>
<!-- 配置数据源 德鲁伊-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc_driverClassName}"/>
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_username}"/>
<property name="password" value="${jdbc_password}"/>
<property name="maxActive" value="${jdbc_maxActive}"/>
<property name="initialSize" value="${jdbc_jdbc_initSize}"/>
</bean>
<!--数据库操作类-->
<bean id ="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 引入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--数据库实务管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 管理的数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- xml配置事务管理-->
<tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="%add%" isolation="DEFAULT" propagation="REQUIRED" />
<tx:method name="%update%" isolation="DEFAULT" propagation="REQUIRED" />
<tx:method name="%delete%" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!--session工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 配置mybatis核心配置文件位置-->
<property name="configLocation" value="mybatisConfig.xml"/>
</bean>
</beans>
配置mybatis全局核心文件
<?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>
<properties resource="jdbc.properties">
</properties>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="defaultFetchSize" value="4"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.gavin.pojo"/>
<package name="com.gavin.mapper"/>
<!-- <package name="com.gavin.pojo"/>-->
</typeAliases>
<!-- 这里用spring进行事务管理就可以了-->
<!-- <environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc_driverClassName}"/>
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_username}"/>
<property name="password" value="${jdbc_password}"/>
</dataSource>
</environment>
</environments>-->
<mappers>
<package name="com.gavin.mapper"/>
</mappers>
</configuration>
配置完毕先别着急往下配置,先检查一下是否配置正确—
链接数据库试试----->>>
注:这里将mybatis文件中的注掉的数据库部分先开启;不然测试会报错;
public class test {
private SqlSession sqlSession=null;
private SqlSessionFactory factory =null;
@Before
public void init() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatisConfig.xml");
factory= new SqlSessionFactoryBuilder().build(resourceAsStream);
}
@Test
public void test(){
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
DruidDataSource dataSource = ac.getBean("dataSource", DruidDataSource.class);
System.out.println(dataSource);
sqlSession=factory.openSession();
BookstoreMapper mapper = sqlSession.getMapper(BookstoreMapper.class);
Bookstore bookstore = mapper.selectByPrimaryKey(1001);
System.out.println(bookstore);
}
@After
public void initAfter(){
sqlSession.close();
}
}
这样spring与mybatis框架就搭建完毕
搭建完毕之后咋那么让mybatis与spring整合起来呢?
Mybatis-Spring整合
其实在导入依赖的时候有一个 mybatis-spring依赖,这个依赖就是用来连接spring与mybatis的中间件;
mybatis通过sqlsession完成对数据库的增删查改,所以在spring中要引入一个对sqlsession的管理对象,
在Mybatis-Spring中提供了SqlSessionTemplate类或SqlSessionDaoSupport类来实现mybatis与sping的整合;
SqlSessionTemplate
Mybatis-Spring的核心类,------ SqlSessionTemplate:
它负责管理MyBatis的SqlSession,调用MyBatis的SQL方法。当调用SQL方法时,SqlSessionTemplate将会保证使用的SqlSession和当前Spring的事务是相关的。它还管理SqlSession的生命周期,包含必要的关闭、提交和回滚操作。
SqlSessionDaoSupport
SqlSessionDaoSupport 一个抽象支持类,它继承了DaoSupport类,主要是作为DAO的基类来使用。可以通过SqlSessionDaoSupport类的getSqlSession()方法来获取所需的SqlSession。
开始写一个小案例---->
实体类---->>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Bookstore implements Serializable {
private Integer bookid;
private String bookname;
private String bookpublish;
private Double bookprice;
private String bookkind;
private Integer bookcount;
private static final long serialVersionUID = 1L;
}
bookmapper.xml
<?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">
<mapper namespace="com.gavin.mapper.BookstoreMapper">
<resultMap id="BaseResultMap" type="com.gavin.pojo.Bookstore">
<id column="bookstore_BookId" jdbcType="INTEGER" property="bookid" />
<result column="bookstore_BookName" jdbcType="VARCHAR" property="bookname" />
<result column="bookstore_BookPublish" jdbcType="VARCHAR" property="bookpublish" />
<result column="bookstore_BookPrice" jdbcType="DOUBLE" property="bookprice" />
<result column="bookstore_BookKind" jdbcType="VARCHAR" property="bookkind" />
<result column="bookstore_BookCount" jdbcType="INTEGER" property="bookcount" />
</resultMap>
<sql id="Base_Column_List">
bookstore.BookId as bookstore_BookId, bookstore.BookName as bookstore_BookName, bookstore.BookPublish as bookstore_BookPublish,
bookstore.BookPrice as bookstore_BookPrice, bookstore.BookKind as bookstore_BookKind,
bookstore.BookCount as bookstore_BookCount
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from bookstore bookstore
where bookstore.BookId = #{bookid,jdbcType=INTEGER}
</select>
</mapper>
mybatis中加入映射文件位置,
开始写java文件----
首先将一张数据库表转为javabean,这里以bookstore为例
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Bookstore implements Serializable {
private Integer bookid;
private String bookname;
private String bookpublish;
private Double bookprice;
private String bookkind;
private Integer bookcount;
private static final long serialVersionUID = 1L;
}
然后编写接口mapper
import com.gavin.pojo.Bookstore;
public interface BookstoreMapper {
Bookstore selectByPrimaryKey(Integer bookid);
}
接口实现类----->>
@Repository("BookStoreMapper")
public class BookStoreMapperImp implements BookstoreMapper {
@Autowired
@Qualifier("sqlSessionFactory")
private SqlSessionFactory sqlSessionFactory ;
public BookStoreMapperImp() {
}
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
@Override
public Bookstore selectByPrimaryKey(Integer bookid) {
SqlSession sqlSession = sqlSessionFactory.openSession();
BookstoreMapper mapper = sqlSession.getMapper(BookstoreMapper.class);
Bookstore bookstore = mapper.selectByPrimaryKey(1001);
sqlSession.close();
return bookstore;
}
}
测试一下---->>>
public class test {
@Test
public void test(){
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
BookstoreMapper mapper = ac.getBean("bookstoreMapper", BookstoreMapper.class);
Bookstore book = mapper.selectByPrimaryKey(1001);
System.out.println(book);
}
}
运行结果---->>
由于curd都会用到sqlsession,所以可以提取出来一个方法用于生产sqlsession实例;
以上是基于传统dao开发的,增产查改都会代码重复量很大,其实可以简化为
将接口实现类去掉,然后在spring配置文件引入一个bean
<!-- mapper接口开发-->
<bean id="bookstoreMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.gavin.mapper.BookstoreMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
接口实现类去掉之后,测试代码---->>>
public class test {
@Test
public void test() {
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
BookstoreMapper bookstoreMapper = ac.getBean("bookstoreMapper", BookstoreMapper.class);
Bookstore bookstore = bookstoreMapper.selectByPrimaryKey(1001);
System.out.println(bookstore);
}
}
这样可以节省一个接口,同时可以让mybatis-spring中的类去管理sqlsession的生命周期;
但是这还不够,如果接口太多…懒惰的人总会有办法
MapperScannerConfigurer了解一下
MapperScannerConfigurer
将接口的bean注释掉,然后再spring配置文件中加入如下配置----->>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.gavin.mapper"/>
</bean>
测试------->>>
关于自动扫描的一些参数详解---->>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置要扫描的包路径,这样就会扫描该包及其子包 -->
<property name="basePackage" value="com.hyc.dao" />
<!-- 指定SqlSessionFactory的bean名称 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 指定SqlSessionTemplate的bean名称,优先级高于SqlSessionFactory -->
<property name="sqlSessionTemplateBeanName" value="com.hyc.mapper" />
<!-- 当包下的类被这个注解@Repository标示的时候才会被扫描 -->
<property name="annotationClass" value="org.springframework.stereotype.Repository" />
</bean>
Mybatis-Spring整合后的工作原理----->
1,传统的Dao模式开发------>>>
首先是Dao接口----Bookmapper
然后是Dao接口实现类----BookmapperImp
然后在实现类的方法体中注入sqlsessionFactory以便在实现类的方法中使用工厂创建sqlsession
通过sqlsession开辟域结合mybatis实现数据库操作;
2,mapper模式开发
需要在引入一个工厂mapperFactoryBean,并配置mapper接口与sqlsessionFactory
<bean id="bookstoreMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--配置mapper接口-->
<property name="mapperInterface" value="com.gavin.mapper.BookstoreMapper"/>
<!--配置SqlSessionFactory-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<!--如果同时配置sqlSessionTemplate和SqlSessionFactory,将优先使用sqlSessionTemplate-->
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
sqlsessionFactory与sqlSessionTemplate
分析一下这两个类之间的区别–>>
首先还是看API
sqlsessionFactory用于生产sqlsession,然后通过sqlsession调用相应方法来实现对数据库的curd操作;
那sqlSessionTemplate与sqlsession有什么区别呢?
sqlsession由sqlsession工厂创建,本身不会管理sqlsession,需要手动的提交/回滚/关闭
而sqlSessionTemplate通过构造方法来注入了sqlsession,实现了对sqlsession的自动管理;
通过mapperScanerConfigure来扫描所有接口
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.gavin.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="sqlSessionTemplateBeanName" value="com.gavin.mapper"/>
<property name="annotationClass" value="org.springframework.stereotype.Repository"/>
简单的画图-----基本运作原理