自定义Mybatis

使用xml配置

## SqlMapConfig,Mybatis主配置文件,记录数据库信息

<?xml version="1.0" encoding="UTF-8" ?>

<!--自定义 mybatis 主配置文件-->
<configuration>
<!--    配置环境-->

    <environments default="mysql">
<!--        配置mysql的环境-->
        <environment id="mysql">
<!--            配置事务类型-->
            <transactionManager type="JDBC"></transactionManager>
<!--            配置数据源 (连接池)-->
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>

        </environment>
    </environments>

<!--    指定映射配置文件的位置,映射配置文件指的 是每个dao独立的配置文件-->

    <mappers>
        <mapper resource="cn/jx/dao/IUserDao.xml"></mapper>
    </mappers>
</configuration>

## 被代理Dao接口 全限定 位置
<?xml version="1.0" encoding="utf-8" ?>


<!--配置 dao接口 全限定位置-->
<mapper namespace="cn.jx.dao.IUserDao">
<!--    配置 dao 方法-->
    <select id="findAll" resultType="cn.jx.domain.User">
        select * from user;
    </select>
</mapper>
## 自定义Mybatis 总体架构
package cn.jx.dao;

import cn.jx.domain.User;
import cn.jx.mybatis.io.Resources;
import cn.jx.mybatis.sqlsession.SqlSession;
import cn.jx.mybatis.sqlsession.SqlSessionFactory;
import cn.jx.mybatis.sqlsession.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import static org.junit.Assert.*;

/**
 * 自定义mybatis使用得 测试类
 */
public class IUserDaoTest {

    @Test
    public void findAll() throws IOException {
//        1.读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");

        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = sqlSessionFactoryBuilder.build(in);
        // 3.使用工厂生产SqlSession对象
        SqlSession sqlSession = build.openSession();

        //4.使用SqlSession 常见 Dao接口的 地理对象
        IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);

//        5.使用代理对象执行方法
        List<User> users = iUserDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
        in.close();
    }
}

## Resource,加载 Mybatis主配置文件
package cn.jx.mybatis.io;

import java.io.InputStream;

/**
 * TOOD
 *
 * @author luo
 * @version 1.0
 * @date 2020/3/3 12:03
 *
 * 使用类加载器读取配置文件
 */
public class Resources {
    /**
     * 根据传入的文件路径, 获取对应的字节输入流
     * @param filePath
     * @return 对应的字节输入流
     */
    public static InputStream getResourceAsStream(String filePath) {
        return Resources.class.getClassLoader().getResourceAsStream(filePath);
    }

}
## SqlSessionFactoryBuilder 用于构建一个SqlSessionFactory工厂

public class SqlSessionFactoryBuilder {

    public SqlSessionFactory build(InputStream config){
        Configuration cfg = XMLConfigBuilder.loadConfiguration(config);
//        默认的 SqlSessionFactory
        return new DefaultSqlSessionFactory(cfg);
    }
}
## XMLConfigBuilder 工具类用于加载出相关配置文件中的配置信息
## DefaultSqlSessionFactory为默认的工厂实现类
	包含openSession(config)方法,返回一个SqlSession
## DefaultSqlSession 创建要实现代理的Dao接口

public class DefaultSqlSession implements SqlSession {

    private Configuration cfg;//数据库 信息
    private Connection connection;

    public DefaultSqlSession(Configuration cfg) {
        this.cfg = cfg;
        connection = DataSourceUtil.getConnection(cfg);
    }

    /**
     * 创建代理对象
     * @param daoInterfaceClass 要实现代理的 Dao接口字节码
     * @param <T>
     * @return 代理对象
     */
    public <T> T getMapper(Class<T> daoInterfaceClass) {
        return  (T) Proxy.newProxyInstance(daoInterfaceClass.getClassLoader(),
                new Class[]{daoInterfaceClass},
                new MapperProxy(cfg.getMappers(),connection)
                );


        /*
        *       daoInterfaceClass.getInterfaces,不可以, 所需参数为 被代理类 所有的实现类,
        *   IUserDao为被代理类(即接口),它实现其本身用 new Class[]{self}  ------- self.getInterfaces  为null
        * */
    }
## MapperProxy 实现invocationHandler
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//        1.获取方法名
        String methodName = method.getName();
//        2.获取方法所在类的名称
        String className = method.getDeclaringClass().getName();
//       3.组合  key
        String key = className+"."+methodName;
//        4.获取 mappers 中Mapper对象
        Mapper mapper = mappers.get(key);
        if(mapper == null){
            throw new IllegalArgumentException("if(mapper == null){");
        }
//6.调用工具类执行查询所有
        return new Executor().selectList(mapper,connection);
    }

//
源码
链接:https://pan.baidu.com/s/1dLFugfDuIMsddEsYrDnjbg
提取码:pv8l
//

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值