MyBatis核心组件浅谈

本文深入探讨MyBatis的四大核心组件:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession与SQLMapper,详细解释它们的功能与作用,包括如何使用XML配置与代码创建SqlSessionFactory,SqlSession的事务控制,以及SQLMapper的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们今天来看一看MyBatis的“表面现象”——组件,并且讨论一下他们的作用。
MyBatis的核心组件分为4个部分:

  • SqlSessionFactoryBuilder(构造器):它会根据配置或者代码来生成SqlSessionFactory,采用的是分布构建的Builder模式。
  • SqlSessionFactory(工厂接口):依靠它来生成SqlSession,使用的是工厂模式。
  • SqlSession(会话):一个既可以发生SQL来执行返回结果,也可以获取Mapper的接口。在现在的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是MyBatis提供的SQL Mapper接口编程技术,它能提高代码的可读性和可维护性。
  • SQL Mapper(映射器):MyBatis新设计存在的组件,它由一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。它负责发送SQL去执行,并返回结果。

在这里插入图片描述
下面我在来细细的说一说各个组件。

1、SqlSessionFactory(工厂接口)
使用MyBatis首先是使用配置或者代码去生产SqlSessionFactory,二MyBatis提供了构造器SqlSessionFactoryBuilder。它提供了一个类org.apache.ibatis.session.Configuration作为引导,采用的是Build模式。具体的分步则是在Configuration类里面完成的。

1)、使用XML构建SqlSessionFactory
mybatis-config.xml:

<?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>
    <typeAliases><!-- 别名-->
        <typeAlias alias="role" type="com.learn.ssm.pojo.Role"></typeAlias>
    </typeAliases>
    <!-- 数据库环境 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSourse type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm"></property>
                <property name="username" value="root"></property>
                <property name="password" value="hjw19990825"></property>
            </dataSourse>
        </environment>
    </environments>
    <!-- 映射文件 -->
    <mappers>
        <mapper resource="com/learn/ssm/mapper/RoleMapper.xml"></mapper>
    </mappers>
</configuration>

  • typeAlias元素定义了一个别名role,它代表着com.learn.ssm.pojo.Role这个类。这样定义后,在MyBatis上下文中就可以使用别名去代替全限定名。
  • environment元素的定义,这里描述的是数据库。
  • mapper元素代替引入的那些映射器。
    有了基础配置文件,就可以用一段很简短的代码来生成SqlSessionFactory了,代码如下
SqlSessionFactory SqlSessionFactory=null;
String resource="mybatis-config.xml";
InputStream inputStream;
try{
	inputStream=Resources.getResourceAsStream(resource);
	SqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}catch(IOException e){
	e.printStrackTrace();
}

首先读取mybatis-config.xml,然后通过SqlSessionFactoryBuild的Build方法去创建SqlSessionFacrtory。整个过程比较简单,但是里面的步骤还是比较繁琐的,只是MyBatis采用了Builder模式为开发者隐藏了这些细节。

2)、使用代码创建SqlSessionFactory

        //数据库连接池信息
        PooledDataSource dataSource=new PooledDataSource();
        dataSource.setDriver("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("hjw19990825");
        dataSource.setUrl("jdbc:mysql://localhost:3306/ssm");
        dataSource.setDefaultAutoCommit(false);
        //采用MyBatis的JDBC事务方式
        TransactionFactory transactionFactory=new JdbcTransactionFactory();
        Environment environment=new Environment("development",transactionFactory,dataSource);
        //创建Configuration对象
        Configuration configuration=new Configuration(environment);
        //注册一个MyBatis上下文别名
        configuration.getTypeAliasRegistry().registerAlias("role",Role.class);
        //加入一个映射器
        configuration.addMapper(RoleMapper.class);
        SqlSessionFactory SqlSessionFactory=new SqlSessionFactoryBuilder().build(configuration);
        return SqlSessionFactory;

2、SqlSession
在MyBatis中,SqlSession是其核心接口。在MyBatis中有两个实现类——DefaultSqlSession和SqlSessionManager。DefaultSqlSessio是单线程使用的,而SqlSessionManager是在多线程环境下使用。SqlSession的作用类似于一个JDBC中的Connection对象,代表着一个连接资源的启用。它有3个作用:

  • 获取Mapper接口
  • 发送SQL给数据库
  • 控制数据库事务

我们先来掌握它的创建方法,有了SqlSessionFactory,创建SqlSession就很简单了,代码如下:

SqlSession sqlSession=SqlSessionFactory.openSession();

其实SqlSession只是一个门面接口,在MyBatis中,真正在干活的是Executor,我们只能在底城看到它。
SqlSession控制数据库事务的方法,代码如下:

//定义SqlSession
SqlSession sqlSession=null;
try{
	//打开SqlSession会话
	sqlSession=SqlSessionFactory.openSession();
	//some code ...
	//提交事务
	sqlSession.commit();
}catch(Exeception ex){
	//回滚事务
	sqlSession.rollback();
}finally{
	//在finally语句中确保资源被顺利关闭
	if(sqlSession!=null){
		sqlSession.close();
	}
}

commit方法提交事务,rollback方法回滚事务

3、SQL Mapper(映射器)
映射器是MyBatis中最重要、最复杂的组件,它由一个接口和对应的XML文件(或注解)组成。
他可以配置以下内容:

  • 描述映射规则
  • 提供SQL语句,并可以配置SQL参数类型、返回类型、缓存刷新等信息
  • 配置缓存
  • 提供动态SQL

我们来说一下实现映射器的方式——XML文件形式。不过在此之前,先定义一个POJO,代码如下:

package pojo;

public class Role {
    private Long id;
    private String roleName;
    private String note;

    public Long getId() {
        return id;
    }

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

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}

映射器的主要作用就是将SQL查询到的结果映射为一个pojo,或者将pojo的数据插入到数据库中,并定义一些关于缓存等的重要内容。

然后我们就可以来用XML实现映射器。用XML定义映射器分为两个部分:接口和XML,代码如下:
映射器接口:

public interface RoleMapper{
	public Role getRole(Long id);
}

RoleMapper.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="mapper.RoleMapper">
    <select id="getRole" parameterType="long" resultType="role">
        select id,role_name as rolename,note from t_role where id=#{id}
    </select>
</mapper>
    

  • mapper元素中的属性namespace所对应的是一个接口的全限定名,于是MyBatis上下文就可以通过它找到对应的接口。
  • selcet元素表明这是一条查询语句,属性id表示了这条SQL,属性paramenterType=“long"说明传递给SQL的是一个long型的参数,而resultType=“role”表示返回的是一个role类型的返回值。而role是之前配置文件mybatis-config.xml配置的别名。
  • 这条SQL中的#{id}表示传递进去的参数

有了映射器就可以通过SqlSession发送SQL了,我们以getRole这条SQL为例看看如何发送SQL:

Role role=(Role)sqlSession.selectOne("mapper.getRole",1L);

selectOne方法表示使用查询并且只返回一个对象,而参数一个string对象和一个Object对象。这里是一个Long参数,long参数是它的主键。String对象是有一个命名空间加上SQLid组合而成的,它完全定位了一条SQL,这样MyBatis就会找到相对应的SQL。

SqlSession还可以获取Mapper接口,通过Mapper接口发送SQL,代码如下:

RoleMapper roleMapper=sqlSession.getMapper(RoleMaapper.class);
Role role=roleMapper.getRole(1L);

最后,我们来谈一谈以上两种发送SQL的方式(一种是用SqlSession直接发送,另外一种是通过SqlSession获取Mapper接口在发送),笔者建议采用第二种,理由如下:

  • 使用Mapper接口编程可以消除SqlSession带来的功能性代码,提高可读性,而SqlSession发送SQL,需要一个SQLid去匹配SQL,比较难懂。
  • 使用Mapper.getRole(1L)方式,IDEA会提示错误和校验,而使用sqlSession.selectOne(…)语法,只有在运行中才能知道是否发生了错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值