【Spring 持久层】Spring 与 Mybatis 整合

持久层整合总述

1、Spring 框架为什么要与持久层技术进行整合?

  • JavaEE开发需要持久层进行数据库的访问操作
  • JDBC、Hibernate、MyBatis 进行持久开发过程存在大量的代码冗余
  • Spring 基于模板设计模式对于上述的持久层技术进行了封装

2、Spring 可以与哪些持久层技术进行整合?

  • JDBC —— JDBCTemplate
  • Hibernate(JPA)—— HibernateTemplate
  • MyBatis —— SqlSessionFactoryBeanMapperScannerConfigure

Mybatis 开发步骤回顾

  1. 实体类 User
public class User implements Serializable {
    private Integer id;
    private String name;
    private String password;

    public User() {
    }

    public User(Integer id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
  1. 实体别名 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Confi 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="user" type="com.yusael.mybatis.User"/>
    </typeAliases>
    
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/yus?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
</configuration>
  1. 表 t_users
create table t_users values (
	id int(11) primary key auto_increment,
	name varchar(12),
	password varchar(12)
);
  1. 创建 DAO 接口:UserDAO
public interface UserDAO {
    public void save(User user);
}
  1. 实现Mapper文件:UserDAOMapper.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.yusael.mybatis.UserDAO">
    <insert id="save" parameterType="user">
        insert into t_users(name, password) values (#{name}, #{password})
    </insert>
</mapper>
  1. 注册 Mapper 文件 mybatis-config.xml
<mappers>
	<mapper resource="UserDAOMapper.xml"/>
</mappers>
  1. MybatisAPI 调用
public class TestMybatis {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
            										.build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        UserDAO userDAO = session.getMapper(UserDAO.class);
        
        User user = new User();
        user.setName("yusael");
        user.setPassword("123456");
        userDAO.save(user);

        session.commit();
    }
}

Mybatis 开发中存在的问题

问题:配置繁琐、代码冗余

1. 实体
2. 实体别名				配置繁琐
3. 表
4. 创建 DAO 接口
5. 实现 Mapper 文件
6. 注册 Mapper 文件			配置繁琐
7. Mybatis API 调用			代码冗余

Spring 与 Mybatis 整合思路

Spring 与 Mybatis 整合的开发步骤

  • 配置文件(ApplicationContext.xml)进行相关配置(只需要配置一次
  • 编码
    1.实体类
    2.表
    3.创建DAO接口
    4.Mapper文件配置

Spring 与 Mybatis 整合的编码

搭建开发环境 pom.xml

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.2.6.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>2.0.4</version>
</dependency>

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.12</version>
</dependency>

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.43</version>
</dependency>

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.4</version>
</dependency>

Spring 配置文件的配置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
        <!--连接池-->
        <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/yus?useSSL=false"/>
            <property name="username" value="root"/>
            <property name="password" value="1234"/>
        </bean>

        <!--创建SqlSessionFactory SqlSessionFactoryBean-->
        <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <!-- 指定实体类所在的包 -->
            <property name="typeAliasesPackage" value="com.yusael.entity"/>
            <!--指定配置文件(映射文件)的路径,还有通用配置-->
            <property name="mapperLocations">
                <list>
                    <value>classpath:com.yusael.dao/*Mapper.xml</value>
                </list>
            </property>
        </bean>

        <!--创建DAO对象 MapperScannerConfigure-->
        <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
            <!--指定DAO接口放置的包-->
            <property name="basePackage" value="com.yusael.dao"/>
        </bean>

</beans>

编码

  1. 实体 com.yusael.entity.User
public class User implements Serializable {
    private Integer id;
    private String name;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
  1. t_user
create table t_users values (
	id int(11) primary key auto_increment,
	name varchar(12),
	password varchar(12)
);
  1. DAO接口 com.yusael.dao.UserDAO
public interface UserDAO {
    public void save(User user);
}
  1. Mapper文件配置 resources/applicationContext.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.shimmer.dao.UserDao">
    <insert id="save" parameterType="User">
        insert into `t_users`(name,password) values (#{name},#{password})
    </insert>
</mapper>
  1. 测试
/**
 * 用于测试: Spring 与 Mybatis 的整合
 */
@Test
public void test() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
    UserDAO userDAO = (UserDAO) ctx.getBean("userDAO");

    User user = new User();
    user.setName("xiaojr");
    user.setPassword("999999");

    userDAO.save(user);
}

Spring 与 Mybatis 整合细节

问题:Spring 与 Myabatis 整合后,为什么 DAO 不提交事务,但是数据能够插入数据库中?

  1. Mybatis 提供的连接池对象 —> 创建 Connection
    Connection.setAutoCommit(false) 手工的控制了事务,操作完成后,需要手工提交。
  2. Druid(C3P0、DBCP)作为连接池 —> 创建 Connection
    Connection.setAutoCommit(true) 默认值为 true,保持自动控制事务,一条 sql 自动提交。

答案:因为 Spring 与 Mybatis 整合时,引入了外部连接池对象,保持自动的事务提交这个机制Connection.setAutoCommit(true),不需要手工进行事务的操作,也能进行事务的提交。

注意:实战中,还是会手工控制事务(多条SQL一起成功,一起失败),后续 Spring 通过 事务控制 解决这个问题。

原文地址:https://www.cnblogs.com/shimmernight/p/13502521.html