阅读 133

MyBatis入门及进阶 - 代理模式与核心配置详解

分享知识, 不咕自己.

前言

在上一节, 我们创建了一个mybatis_quick_start的项目, 实现了MyBatis最基本的数据操作以及核心配置. 也创建了测试类证明了代码的正确. 上一节的实现方式与JDBC操作相比确实做到了简化操作的目的, 但是依旧没有达到我们想要的效果. 所以这一节我们会继续学习MyBatis配置和实现更高级的用法, 让我们的代码进一步升级.

一、接口加动态代理实现数据操作

接口加动态代理的实现方式, 是我们工作中主流的实现方式. 基于这种方式和MyBatis优秀的封装思想. 让我们在编写代码的时候不用再考虑定位sql的问题. 进一步减少代码中硬编码.
Mapper接口的实现方式需要我们编写Dao层接口, 由MyBatis根据Dao层接口创建接口的动态代理对象来实现数据库操作.接口实现方式需要遵循以下几点约定.

  1. Mapper.xml中的namespace要与Dao层接口的全限定名相同
  2. Dao层接口方法名要与Mapper.xml中定义id相同
  3. Dao层接口的入参类型要与Mapper.xml中每个Sql的parameterType类型相同
  4. Dao层接口的出参类型要与Mapper.xml中每个Sql的resultType类型相同

微信截图_20210511211905.png 注意: 如果出参或者入参类型为List集合类型, 在Mapper.xml文件中resultType和ParameterType的类则与集合泛型中的类型保持一致
了解以上条件后我们就可以开始编写代码了. 回到IDEA中创建一个与pojo包同级的包dao并创建UserDao的接口.在接口中完成一个查询方法的声明.

微信截图_20210511212847.png

public interface UserDao {

    List<User> getListByCondition(User user);
}
复制代码

在UserMapper.xml文件中编写对应的sql代码如下

<mapper namespace="com.lgy.dao.UserDao">

    <!-- 条件查询 -->
    <select id="getListByCondition" resultType="com.lgy.pojo.User" parameterType="com.lgy.pojo.User">
        select * from user where username = #{username}
    </select>

    <!-- 新增 -->
    <insert id="save" parameterType="com.lgy.pojo.User">
        insert into user values(#{id},#{username})
    </insert>

    <!-- 查询 -->
    <select id="getList" resultType="com.lgy.pojo.User">
        select * from user
    </select>

</mapper>
复制代码

完后成我们就可以开始开始测试, 在测试类中编写如下代码

    @Test
    public void testGetListByCondition() throws IOException {
        // 获取配置文件 转换为输入流
        InputStream resourceAsStream =
                Resources.getResourceAsStream("mybatis-config.xml");
        // 获取 SqlSessionFactory 后面细说
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获取sqlSessin
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 通过JDK动态代理获取接口代理对象
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        // 构建入参对象
        User user = new User();
        user.setUsername("jerry");
        // 执行方法
        List<User> users = userDao.getListByCondition(user);
        for (User user1 : users) {
            System.out.println("id = " + user1.getId() +
                    ", username = " + user1.getUsername());
        }
        // 关闭sqlSession
        sqlSession.close();
    }
复制代码

我们提前在上一章创建的测试数据库user表中插入了两个名叫jerry的用户

微信截图_20210511214006.png

运行结果正如我们预期

微信截图_20210511214055.png

Mapper.xml文件中还留有两个方法save和getList没有进行修改, 大家可以作为练习.

二、核心配置

在上一章节中, 我们创建了两个配置文件. mybatis-config.xml(核心配置文件), UserMapper.xml(映射配置文件), 其实对于这两个配置文件的编写我们只是使用了部分配置. 实际上在这两个配置文件中我们可以编写的配置有很多. 每一个配置都有不同的功能.

微信截图_20210511214912.png

详细的配置说明可以去MyBatis中文官网查看

在本章中, 除了我们上一章节使用到的environments(环境配置)和mappers(映射器)之外. 我们仅讲解mybatis-config.xml(核心配置文件)中其他两个常用的两个配置, properties和typeAliases.

properties

在我们实际开发过程中properties属性在MyBatis配置中也是使用的非常多的. 因为我们习惯将数据库相关配置单独提取到一个properties文件中. 再根据mybatis-config.xml(核心配置文件)properties标签中resource属性的值. 加载properties文件中的配置从而让我们可以在mybatis-config.xml(核心配置文件)中使用.

微信截图_20210511220814.png

jdbc.properties配置代码

微信截图_20210511221011.png

MyBatis会解析占位符${}并找到与占位符中的Key对应的值进行替换

注意: properties标签一定要写在environments标签上方, 否则会报错. 上方演示截图仅为了展示

typeAliases

typeAliases: 设置类型别名. mybatis-config.xml(核心配置文件)配置typeAliases标签后. 可以让我在mapper.xml(映射文件)中写更为简短的类型别名, 而不必是全限定名

微信截图_20210511222742.png

配置typeAliases标签后

微信截图_20210511222939.png

注意: typeAliases标签一定要写在environments标签上方, 否则会报错.

typeAliases标签支持配置多个, 但是如若我们有大量的pojo实体又会让我们的配置文件变得臃肿. 所以typeAliases标签中还提供了另一个子标签pakage. 它可以给指定目录下的所有pojo实体自动起别名, 起的别名就是该包下所有类的类名且不区分大小写.

微信截图_20210511223909.png

为了测试该配置不区分大小写特性, 我们故意把resultType和parameterType的值改为UsEr. 在实际开发中建议首字母大写或者全小写.

微信截图_20210511224217.png

修改完之后, 我们运行getListByCondition的测试方法.

微信截图_20210511224349.png

执行成功说明以上配置均为正确.

实际上MyBatis为了简化开发, 已经在源码中内置了许多类型的别名. 如: java.lang.Integer 我们可以简写为 int

查看全部内置类型别名. 可在org.apache.ibatis.type.TypeAliasRegistry中查看. 中文源码地址

三、总结

约定大于配置使我们的代码变得更加简介. 在MyBatis中Dao层接口和映射实体mapper.xml(映射文件)约定必须一致让我们减少了硬编码的问题. typeAliases标签的子标签pakage给指定目录下所有pojo类自动起别名且不区分大小写让我们减少了bug的风险. 合理的约定可以使我们在不增加代码控制的情况下使编程变得更加顺畅. 写代码是基础, 在代码之外我们还可以思考很多.

如果有概念含糊不清或者错误的情况. 欢迎大家指出. 感谢.

文章分类
后端
文章标签