中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行Java?Mybatis中的Mapper原理分析

發布時間:2022-01-06 19:48:20 來源:億速云 閱讀:162 作者:柒染 欄目:開發技術

如何進行Java Mybatis中的Mapper原理分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

    準備

    1.pom文件

     <dependencies>
            <!--mybatis坐標-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.5</version>
            </dependency>
            <!--mysql驅動坐標-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
                <scope>runtime</scope>
            </dependency>
            <!--單元測試坐標-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <!--日志坐標-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.12</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.2</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>

    2.user類-數據庫

    如何進行Java?Mybatis中的Mapper原理分析

    3.實體類

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    public class user {
        private int id;
        private String username;
        private String password;
    }

    4.dao 層

    public interface userDao {
        List<user> findAll();
    }

    5.Mapper 文件

    <?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="dao.userDao">
        <select id="findAll" resultType="mode.user">
            select * from user
        </select>
    </mapper>

    核心配置文件

    <?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>
        <!--通過properties標簽加載外部properties文件-->
        <properties resource="jdbc.properties"></properties>
        <!--自定義別名-->
        <typeAliases>
            <typeAlias type="mode.user" alias="user"></typeAlias>
        </typeAliases>
        <!--數據源環境-->
        <environments default="developement">
            <environment id="developement">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"/>
                    <property name="url" value="${jdbc.url}"/>
                    <property name="username" value="${jdbc.username}"/>
                    <property name="password" value="${jdbc.password}"/>
                </dataSource>
            </environment>
        </environments>
    
        <!--加載映射文件-->
        <mappers>
            <mapper resource="userMapper.xml"></mapper>
        </mappers>
    
    </configuration>

    核心代碼

    import dao.userDao;
    import mode.user;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    public class TestMapper {
        public static void main(String[] args) throws IOException {
            //加載核心配置文件
            InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
            //獲得sqlSession工廠對象
            SqlSessionFactory sqlSessionFactory = new
                    SqlSessionFactoryBuilder().build(resourceAsStream);
            //獲得sqlSession對象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //執行sql語句
            userDao mapper = sqlSession.getMapper(userDao.class);
            List<user> userList = mapper.findAll();
            //打印結果
            System.out.println(userList);
            //釋放資源
            sqlSession.close();
        }
    }

    源碼分析

    1.斷點

    如何進行Java?Mybatis中的Mapper原理分析

    2.查看源碼

    DefaultSqlSession:

    如何進行Java?Mybatis中的Mapper原理分析

    Configuration:

    如何進行Java?Mybatis中的Mapper原理分析

    這是Configuration 類。我們主要看getMapper()方法

    如何進行Java?Mybatis中的Mapper原理分析

    MapperRegistry:

    如何進行Java?Mybatis中的Mapper原理分析

    關鍵代碼:mapperProxyFactory.newInstance(sqlSession);

    MapperProxyFactory:

    如何進行Java?Mybatis中的Mapper原理分析

    返回的是MapperProxy 對象

    MapperProxy:

    源碼:

    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    package org.apache.ibatis.binding;
    import java.io.Serializable;
    import java.lang.invoke.MethodHandles.Lookup;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.util.Map;
    import org.apache.ibatis.lang.UsesJava7;
    import org.apache.ibatis.reflection.ExceptionUtil;
    import org.apache.ibatis.session.SqlSession;
    public class MapperProxy<T> implements InvocationHandler, Serializable {
        private static final long serialVersionUID = -6424540398559729838L;
        private final SqlSession sqlSession;
        private final Class<T> mapperInterface;
        private final Map<Method, MapperMethod> methodCache;
        public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
            this.sqlSession = sqlSession;
            this.mapperInterface = mapperInterface;
            this.methodCache = methodCache;
        }
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            try {
                if (Object.class.equals(method.getDeclaringClass())) {
                    return method.invoke(this, args);
                }
                if (this.isDefaultMethod(method)) {
                    return this.invokeDefaultMethod(proxy, method, args);
                }
            } catch (Throwable var5) {
                throw ExceptionUtil.unwrapThrowable(var5);
            }
            MapperMethod mapperMethod = this.cachedMapperMethod(method);
            return mapperMethod.execute(this.sqlSession, args);
        }
        private MapperMethod cachedMapperMethod(Method method) {
            MapperMethod mapperMethod = (MapperMethod)this.methodCache.get(method);
            if (mapperMethod == null) {
                mapperMethod = new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());
                this.methodCache.put(method, mapperMethod);
            }
            return mapperMethod;
        }
        @UsesJava7
        private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable {
            Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, Integer.TYPE);
            if (!constructor.isAccessible()) {
                constructor.setAccessible(true);
            }
            Class<?> declaringClass = method.getDeclaringClass();
            return ((Lookup)constructor.newInstance(declaringClass, 15)).unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args);
        }
        private boolean isDefaultMethod(Method method) {
            return (method.getModifiers() & 1033) == 1 && method.getDeclaringClass().isInterface();
        }
    }

    如何進行Java?Mybatis中的Mapper原理分析

    在invoke方法中可以看到,如果我們調用的是Object中的方法,不做任何處理,直接調用,否則執行:

    mapperMethod.execute(this.sqlSession, args);

    MapperMethod:

    如何進行Java?Mybatis中的Mapper原理分析

    在MapperMethod 中對SQL語句進行分類反射

    • MapperProxyFactory中,使用JDK的動態代理生成Mapper接口的代理代理類

    • 由動態處理器MapperProxy中調用MapperMethod中的方法處理執行SQL

    • 最后,在MapperMethod中根據執行的方法返回值決定調用SqlSession中的對應方法執行SQL

    看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    台山市| 舞阳县| 景东| 土默特右旗| 贺兰县| 泾阳县| 庆城县| 荆州市| 盐城市| 蓝田县| 福安市| 甘泉县| 花垣县| 白河县| 浑源县| 武定县| 民和| 梅州市| 三河市| 政和县| 巴塘县| 化德县| 克什克腾旗| 县级市| 杭锦旗| 黄大仙区| 介休市| 长白| 宜兰县| 上林县| 嘉祥县| 万全县| 吴桥县| 全州县| 鄂尔多斯市| 武安市| 嵩明县| 漳浦县| 南投县| 五莲县| 商洛市|