Mybatis 调用方式有几种?

1、传统调用方式

public interface IUserDao {
    List<User> findAll();
}

public class UserDaoImpl implements IUserDao{
    @Override
    public List<User> findAll() throws Exception{
        String sqlConfigPath = "sqlConfig.xml";
        InputStream inputStream = Resources.getResourceAsStreasm(sqlConfigPath);
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sessionFactory.openSqlSession();
        List<User> userList = session.selectList("com.deppon.mapper.UserMapper.findAll");
        return userList;
    }
}

public class TestMybatisUtil {
    public static void main(String[] args) throws Exception {
        IUserDao userDao = new UserDaoImpl();
        List<User> allUsers = userDao.findAll();
        System.out.println(allUsers);
    }
}

2、通过接口直接调用

public class DefaultSqlSession implements SqlSession{

    private Configuration configuration;

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> T selectOne(String statementId, Object... args) throws IllegalAccessException, IntrospectionException, InstantiationException, SQLException, InvocationTargetException, NoSuchFieldException {
        List<Object> objectList = selectList(statementId, args);
        if(objectList.size() == 1){
            return (T) objectList.get(0);
        }else{
            throw new RuntimeException("没有查询到数据");
        }
    }

    @Override
    public <T> List<T> selectList(String statementId, Object... args) throws IllegalAccessException, IntrospectionException, InstantiationException, SQLException, InvocationTargetException, NoSuchFieldException {
        MapperStatement mapperStatement = configuration.getMapperStatement(statementId);
        Executor executor = new SimpleExecutor();
        return executor.query(configuration,mapperStatement,args);
    }

    @Override
    public <T> T getMapper(Class<?> mapperClass){
        Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // proxy 代理对象的引用 Object proxyInstance
                // 获取 statementId
                String className = method.getDeclaringClass().getName();
                String methodName = method.getName();
                String statementId = className + "." + methodName;
                System.out.println("statementId:" + statementId);
                // 获取方法的返回值
                Type genericReturnType = method.getGenericReturnType();
                // 判断是否进行了 泛型类型参数化
                if(genericReturnType instanceof ParameterizedType){
                    List<Object> objectList = selectList(statementId, args);
                    return objectList;
                }
                return null;
            }
        });
        return (T) proxyInstance;
    }
}


public class TestMyBatisUtil{

    public static void main(String[] args) throws DocumentException {
        String sqlConfigPath = "sqlConfig.xml";
        InputStream inputStream = Resources.getResourceAsStreasm(sqlConfigPath);
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sessionFactory.openSqlSession();
        UserMapper userMapper = session.getMapper(UserMapper.class);
        List<User> userList = userMapper.findAll();
        for(User user:userList){
            System.out.println(user);
        }
}

备注:接口调用实现使用的是JDK的动态代理,生成该接口的代理对象,每次调用这个接口的所有方法,都会去执行代理对象的 invoke 方法。

1、找出 statementId

2、通过 statementId 和 args 调用 DefaultSqlSession 对象的具体方法。

接口调用注意事项:

1、接口所属的全限定类名与 xml 中的 namespace 相同

2、接口的方法名与 xml 中的 id 名相同

3、接口的参数与 xml 中 parameterType 类型一致

4、接口的返回值类型与 xml 中的 resultType 类型一致

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值