Spring整合Mybatis(1)

Spring整合Mybatis(1)

使用配置文件形式整合Spring+Mybatis。其中Spring使用注解模式,没有使用Spring配置类(使用
<context:component-scan> 用来自动扫描和注册组件)。Mybatis使用.xml配置模式,在spring-mybatis.xml中加载并使用指定位置的 mybatis.xml 文件作为 MyBatis 的配置文件,在mybatis.xml指定映射器(Mapper)的配置文件位置。

1. 整体结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
src
├── main
│ ├── java
│ │ └── camellia
│ │ ├── SpringApplaction.java
│ │ ├── dao
│ │ │ └── UserDao.java
│ │ ├── pojo
│ │ │ └── User.java
│ │ └── service
│ │ ├── UserService.java
│ │ └── impl
│ │ └── UserServiceImpl.java
│ └── resources
│ ├── camellia
│ │ └── dao
│ │ └── UserMapper.xml
│ ├── jdbc.properties
│ ├── mybatis.xml
│ └── mybatis-spring.xml

[!Top]
注意:映射器(Mapper)的配置文件位置要放在相应的DAO接口的同名目录下,这样它们编译之后在同一目录下。

编译后的结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
target
└── classes
├── camellia
│ ├── SpringApplaction.class
│ ├── pojo
│ │ └── User.class
│ ├── service
│ │ ├── UserService.class
│ │ └── impl
│ │ └── UserServiceImpl.class
│ └── dao
│ ├── UserDao.class
│ └── UserDao.xml
├── jdbc.properties
├── mybatis.xml
└── mybatis-spring.xml

2. 整合步骤

整合思路:我们要将Mybatis的对象都交给Spring容器管理,所以要明确将哪些对象交给容器管理。在Mybatis中执行SQL的是SqlSession,而它是由SqlSessionFactory这个类中的openSession方法创建的。所以Mybatis的核心是SqlSessionFactory。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<configuration>

<!--引入外部属性资源文件-->
<properties resource="jdbc.properties"></properties> |——————————>配置数据库,我们可以在Spring通配置数据库连接池实现。
|
<!-- 简化resultType属性用来指定查询结果集的封装类型 --> |
<typeAliases> |
<package name="com.camellia.pojo"/> |
</typeAliases> //可继续保留在,mybatis.xml中。 |
|
<environments default="dev"> |————|
<environment id="dev"> |
<transactionManager type="JDBC"/> |
<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>


<mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<package name="com.camellia.dao"/>

<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

</configuration>

数据库配置文件

1
2
3
4
5
6

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/learn
jdbc.username=root
jdbc.password=24211

创建mybatis-spring.xml:开辟空间

  • xmlns:context="http://www.springframework.org/schema/context"

  • http://www.springframework.org/schema/context

  • http://www.springframework.org/schema/context/spring-context.xsd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

<?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
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 自动扫描和注册组件 -->
<context:component-scan base-package="camellia"></context:component-scan>

<!-- 加载jdbc连接配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

</beans>

配置数据库连接池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 自动扫描和注册组件 -->
<context:component-scan base-package="camellia"></context:component-scan>

<!-- 加载jdbc连接配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- 配置数据库连接池,即第三方bean。 注意:这里的name值是固定的-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

</beans>

配置SqlSessionFactoryBean

在Spring和Mybatis的整合包中提供了一个SqlSessionFactoryBean,这个类中提供了创建SqlSessionFactory对象的方法。
更重要的一点事他继承了FactoryBean,这意味着我们不用像配置实例工厂一样先配置实例工厂的Bean,然后再引用工厂方法。
直接配置实例工厂的Bean即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//部分源码
public class SqlSessionFactoryBean
implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ContextRefreshedEvent> {

private SqlSessionFactory sqlSessionFactory;

@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}

}

在纯Mybatis中,我们创建对象经过以下步骤。

1
2
3
4
5
6
// 1.创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2.创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
// 3.创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
  1. 在SqlSessionFactoryBean中提供了SqlSessionFactoryBuilder对象

  2. 在SqlSessionFactoryBean中也提供SqlSessionFactory对象

  3. sqlSessionFactoryBuilder.build(Resources.getResourceAsStream(“mybatis-config.xml”))信息如何注入?

    • 在整合思路中可知,我们抽取出来的是数据库的配置。在这里我们使用数据库连接池,并且声明为bean。
    • 很巧的是SqlSessionFactoryBean提供了private DataSource dataSource;字段,所以我们可以通过依赖注入的方式将数据库连接池传入。

以上分析可以得出SqlSessionFactoryBean配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 自动扫描和注册组件 -->
<context:component-scan base-package="camellia"></context:component-scan>

<!-- 加载jdbc连接配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- 配置数据库连接池,即第三方bean。 注意:这里的name值是固定的-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<!-- 配置SqlSessionFactoryBean,并注入依赖-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>

</beans>

配置 MyBatis 扫描 DAO 接口

通过以上步骤我们实现了:

  1. 启用Spring注解
  2. 配置数据库连接池
  3. 解决了创建执行SQL语句对象的问题

DAO层是操作数据库的,现在的问题是我们DAO层要通过动态代理实现类以及执行哪个SQL XML映射文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?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
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 自动扫描和注册组件 -->
<context:component-scan base-package="camellia"></context:component-scan>

<!-- 加载jdbc连接配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- 配置数据库连接池,即第三方bean。 注意:这里的name值是固定的-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<!-- 配置SqlSessionFactoryBean,并注入依赖-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 扫描Dao包,创建动态代理对象,他会自动存储到IOC容器中。 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="camellia.dao"></property>
</bean>

</beans>

加载配置 MyBatis 的行为和属性。

1
2
3
4
5
6
<!-- 配置SqlSessionFactoryBean,并注入依赖-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 加载该配置文件用于配置 MyBatis 的行为和属性。 -->
<property name="configLocation" value="classpath:mybatis.xml" />
</bean>

因为一个项目可能涉及多个SQL XML映射文件,所以可以配置在MyBatis配置文件中。在有新的SQL XML映射文件我们配置到这里即可。

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<mappers>
<mapper resource="camellia/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>

当然你也可以通过MyBatis配置文件配置SQL XML映射文件,直接指定映射文件。

   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <property name="dataSource" ref="dataSource" />
       <property name="mapperLocations" value="camellia/dao/UserMapper.xml"/>
   </bean>

到此整合完毕。