侧边栏壁纸
  • 累计撰写 101 篇文章
  • 累计创建 89 个标签
  • 累计收到 9 条评论

spring系列笔记 - 第⼗九章 持久层整合

bearjun
2021-07-15 / 0 评论 / 0 点赞 / 1,096 阅读 / 8,257 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-07-15,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Spring为什么要与持久层进行整合

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

Spring可以和哪些持久层进行整合
1.JDBC
|- JDBCTemplate
2.Hibernate(JPA)
|- HibernateTemplate
3.Mybatis
|- SqlSessionFactory MapperScannerConfigure

Spring与Mybatis进行整合

Mybatis开发步骤:

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

    //此处省略构造方法
    
    //此处省略get/set方法
}
  • 2.实体别名(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>
    <!--给user取别别名-->
    <typeAliases>
        <typeAlias alias="user" type="com.bearjun.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/bearjun?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

</configuration>
  • 3.创建表
create table t_users values (
	id int(11) primary key auto_increment,
	name varchar(12),
	password varchar(12)
);
  • 4.创建DAO接口
public interface UserDAO {
    public void save(User user);
}
  • 5.实现Mapper文件,用于用户的插入操作
<?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.bearjun.mybatis.UserDAO">
    <insert id="save" parameterType="user">
        insert into t_users(name, password) values (#{name}, #{password})
    </insert>
</mapper>
  • 6.注册Mapper文件
<mappers>
	<mapper resource="UserDAOMapper.xml"/>
</mappers>

该操作是在第二步的末尾添加。

  • 7.Mybatis API调用
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("bearjun");
        user.setPassword("123456");
        userDAO.save(user);

        session.commit();
    }
}

Mybatis在开发中存在的问题

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

那如下那些步骤存在问题呢?

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

Spring与Mybatis整合思路

03296-kseb0rb3j6e.png
SqlSessionFactoryBean
mybatis-config.xml主要封装了dataSource数据源信息、TypeAliases别名信息、Mapper文件注册信息(TMD)等信息,然后我们首先可以通过SqlSessionFactory交给spring来管理,这就需要SqlSessionFactoryBean来创建复杂对象。spring系列笔记 - 第⼋章 Spring工厂创建复杂对象(3种方式)。然后通过属性对TMD信息进行注入。这样就不需要config的配置文件了。
MapperScannerConfigure
那现在还有一个问题,Mapper注册文件怎么解决呢?MapperScannerConfigure就可以通过指定的包路径已近类名进行注入。需要注意的是:**MapperScannerConfig所创建的DAO对象,他的Id值是接口,单词首字母小写。**例如:UserDAO --> userDAO

Spring和Mybatis整合的开发步骤

  • 配置文件(ApplicationContext.xml)进行相关配置(只需要配置一次
  • 编码
    • 实体类
    • 创建DAO接口
    • 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/bearjun?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.bearjun.entity"/>
            <!--指定配置文件(映射文件)的路径,还有通用配置-->
            <property name="mapperLocations">
                <list>
                    <value>classpath:mapper/*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.bearjun.dao"/>
        </bean>
</beans>
  • 编码
## 实体类
public class User implements Serializable {
    private Integer id;
    private String name;
    private String password;

	//此处省略构造方法
    
    //此处省略get/set方法
}

## 创建数据库表
create table t_users values (
	id int(11) primary key auto_increment,
	name varchar(12),
	password varchar(12)
);

# dao接口
public interface UserDAO {
    public void save(User user);
}

# Mapper文件配置resources/applicationContext.xml
<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.bearjun.entity"/>
            <property name="mapperLocations">
                <list>
                    <value>classpath:mapper/*Mapper.xml</value>
                </list>
            </property>
        </bean>

        <!--创建DAO对象 MapperScannerConfigure-->
        <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
            <property name="basePackage" value="com.bearjun.dao"/>
        </bean>

</beans>
  • 测试
/**
 * 用于测试: Spring 与 Mybatis 的整合
 */
@Test
public void test() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
    UserDAO userDAO = (UserDAO) ctx.getBean("userDAO");

    User user = new User();
    user.setName("bearjun");
    user.setPassword("6666666");

    userDAO.save(user);
}

Spring与Mybatis整合细节

问题:Spring和Mybatis整合后,为什么DAO不提交事务,但是可以插入到数据库中?
本质上控制连接对象由Connection => (连接池)DataSource

  1. Mybatis提供连接池对象 --> 创建Connection
    Connection.setAutoCommit(false) -->创建了Connection

  2. Durid (C3P0 DBCP) 作为连接池 -->创建了Connection
    Connection.setAutoCommit(true) 默认自动提交事务,每执行一条sql,提交一次事务

答案:因为Spring和Mybatis整合时,引入了外部连接池对象,保持自动提交事务这个机制,不需要手工提交事务的操作。

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

0

评论区