【测试开发】知识点-mybatis,主要使用方式:接口式编程

昨天写了一个 mybatis 的helloWord,虽然能跑起来,但是那种方式还是会存在一些问题。

  • 每次进行增删改查,方法里传入的 sql 唯一标识id 就好长一串。
  • 再者就是传入的查询入参类型是一个object,也就是什么都可以往里面传,如果传"a",肯定查不出来数据。

那么,mybatis 还提供了另一种更高级的使用方式:接口式编程,这也是后续开发中主要使用的方式。

我们可以使用一个接口来描述一个给定的sql语句,它的参数和返回值。

一、接口与配置文件动态绑定

在测试平台项目下的 dao 层新建一个接口com.pingguo.bloomtest.dao.UserMapper:

package com.pingguo.bloomtest.dao;

import com.pingguo.bloomtest.pojo.User;

public interface UserMapper {

    User getUserById(Integer id);
}

定义好了接口,里面有一个方法getUserById,顾名思义就是通过id查询数据,返回 User 对象。

按照以往,定义好了接口,接下来还需要定义出接口的实现类。

但是现在这个接口就是用来查询出 user 表记录数据并封装成 User 对象返回,而在之前定义好的 sql 映射文件UserMapper.xml里,<select>标签里的 sql 也是做这个事情。

<mapper namespace="org.mybatis.example.UserMapper">
    <select id="selectUser" resultType="com.pingguo.bloomtest.pojo.User">
      select * from user where id = #{id}
    </select>
</mapper>

那么,现在就可以把接口与配置文件进行动态绑定:

  • namespace:不要随便写了,对应接口的全类名
  • id: 对应接口里的方法名

改完之后应该是这样了:

<mapper namespace="com.pingguo.bloomtest.dao.UserMapper">
    <select id="getUserById" resultType="com.pingguo.bloomtest.pojo.User">
      select * from user where id = #{id}
    </select>
</mapper>

再写一个测试方法查询一下:

@Test
    void test2() throws IOException {
        // 根据配置文件,创建一个 SqlSessionFactory 对象
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        // 获取 SqlSession 实例,可以执行已经映射的 sql 语句
        SqlSession session = sqlSessionFactory.openSession();
        // 获取接口的实现类对象
        UserMapper userMapper = session.getMapper(UserMapper.class);

        User user = userMapper.getUserById(4);
        System.out.println(user);
    }

getMapper方法可以获取到这个接口的实现对象。

第一步因为要经常使用,所以抽出去了:

public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

执行测试,查询成功。

那么问题来了,这个接口还没写实现类,那么

`UserMapper userMapper = session.getMapper(UserMapper.class);`

获取到的是什么?

加个打印System.out.println(userMapper.getClass());看下输出。

原来是个代理对象

所以说,只要把接口和 xml文件进行动态绑定,mybatis 会为接口自动创建一个代理对象,然后由代理对象去执行增删改查方法。

二、关于 SqlSession

SqlSession代表和数据库的一次会话。用完必须关闭,我上面的事例应该加上session.close();

另外,SqlSession也是非线程安全

  • 线程安全:就是在多线程环境下也不会出现数据不一致,
  • 非线程安全: 就有可能出现数据不一致的情况。

所以不能像这样写:

如果这样写,可能会出现A线程 用了 SqlSession,然后关掉了,但是线程B 还在用。所以每次使用都应该去获取新的对象,不要放在成员变量中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值