久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    只會寫 Mapper 就敢說會 MyBatis?面試官:原理都沒懂

     jacklopy 2025-09-03

    有次我去面試,我人都傻了

    “用過 MyBatis 嗎?”
    “用過!”
    “那說說它怎么把接口變成 SQL 的?”
    “……”
    我當(dāng)場裂開。

    1. 日常場景

    大多數(shù)開發(fā)都是下面這個流程:

    Controller → Service → Mapper → XML

    寫多了,就以為MyBatis只是:

    1. 1. 寫個接口
    2. 2. 寫個 XML
    3. 3. 調(diào)個方法

    直到面試官問:“接口里可沒SQL,怎么就跑起來了?”,我才清醒的知道它沒那么簡單。

    2. 案例

    需求:查用戶信息。

    1. 先整接口

    public interface UserMapper {
        User selectById(Long id);
    }

    2. 再整XML

    <select id="selectById" resultType="com.xxx.User">
        SELECT * FROM t_user WHERE id = #{id}
    </select>

    3. Service里直接調(diào)

    @Autowired
    private UserMapper userMapper;

    public User get(Long id) {
        return userMapper.selectById(id);
    }

    一切看起來歲月靜好,直到面試官問:“userMapper是個接口,Spring怎么給你塞了個能跑的對象?”,這話一出,直接懵了。

    4. 答案在這

    1. 接口咋變成對象?

    答案:MyBatisJDK動態(tài)代理給你整了一個代理對象。

    • · 啟動時掃描 Mapper 接口
    • · 給每個接口整一個 MapperProxy
    • · 代理對象攔著你的調(diào)用,再去找XML里的SQL

    代碼片段:

    UserMapper mapper = (UserMapper) Proxy.newProxyInstance(
        UserMapper.class.getClassLoader(),
        new Class[]{UserMapper.class},
        new MapperProxy(sqlSession)
    );

    2. SQL什么時候拼?

    代理對象收到調(diào)用后,干了兩件小事:

    1. 1. 根據(jù)方法名+參數(shù),找到XML里那條SQL
    2. 2. 把#{}換成真正的?,再把參數(shù)塞進(jìn)去

    也就是SqlSourceBoundSql的過程。

    3. 結(jié)果怎么塞進(jìn)實(shí)體?

    MyBatis偷偷調(diào)了:

    ResultSet → 反射 → User 對象

    全程靠ResultSetHandler干活,字段名對上就行,對不上就用@Results手動指。


    5. 手寫一個極簡 MyBatis

    1. 定義注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Select {
        String value();
    }

    2. 接口

    public interface UserMapper {
        @Select("SELECT * FROM t_user WHERE id = #{id}")
        User selectById(Long id);
    }

    3. 代理類

    public class MyMapperProxy implements InvocationHandler {

        private Connection conn;

        public MyMapperProxy(Connection conn) {
            this.conn = conn;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Select select = method.getAnnotation(Select.class);
            String sql = select.value();
            sql = sql.replace("#{id}", args[0].toString());

            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                User u = new User();
                u.setId(rs.getLong("id"));
                u.setName(rs.getString("name"));
                return u;
            }
            return null;
        }
    }

    4. 啟動器

    Connection conn = DriverManager.getConnection("jdbc:mysql://...""root""root");
    UserMapper mapper = (UserMapper) Proxy.newProxyInstance(
        UserMapper.class.getClassLoader(),
        new Class[]{UserMapper.class},
        new MyMapperProxy(conn)
    );

    System.out.println(mapper.selectById(1L));

    跑起來,控制臺真的打出了用戶信息。

    6. 更多知識點(diǎn)

    • · 一級緩存:同一個SqlSession,第二次查直接拿內(nèi)存
    • · 二級緩存:跨SqlSession,但要配 <cache/>
    • · 插件:分頁、加密、脫敏全靠攔截器鏈
    • · 延遲加載:查用戶不查部門,用到部門再發(fā)SQL

    若是面試能聊到這里,基本已經(jīng)反殺了。

    7. 總結(jié)

    接口 + 代理 → 找SQL → 拼參數(shù) → 反射塞結(jié)果。

    08 彩蛋:面試現(xiàn)場原對話還原

    面試官:“為啥#{}能防SQL注入?”
    我:“因?yàn)樗日嘉唬僭O(shè)參數(shù),JDBC會當(dāng)字符串處理。”
    面試官:“那${}呢?”
    我:“直接拼,容易出事,一般不這樣寫。”
    面試官:“行,過了。”
    我:???

    我是大華,專注分享前后端開發(fā)的實(shí)戰(zhàn)筆記。關(guān)注我,少走彎路,一起進(jìn)步!

     


      本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 国产精品无码a∨麻豆| 久久中文字幕一区二区| 免费无码又爽又刺激毛片| 国产精品日韩中文字幕| 加勒比中文字幕无码一区| 色老头在线一区二区三区| 国产破外女出血视频| 另类国产精品一区二区| 凹凸在线无码免费视频| 国产成人精品午夜2022| 精品久久人妻AV中文字幕| 午夜成人无码免费看网站| 人妻AV中文字幕一区二区三区| 国产一区二区不卡在线| 亚洲人成影院在线观看| 午夜高清福利在线观看| 国产高跟黑色丝袜在线| 视频二区中文字幕在线| 一本久道久久综合狠狠爱| 強壮公弄得我次次高潮A片| 国产人妇三级视频在线观看| 亚洲高清WWW色好看美女| 亚洲AV永久纯肉无码精品动漫| 亚洲 制服 丝袜 无码| 国产偷国产偷亚洲高清人| 欧美亚洲高清国产| 国产精品有码在线观看| 国产成人AV三级在线观看按摩| 午夜福利精品国产二区| 成人网站WWW污污污网站| 成人免费精品网站在线观看影片| 亚洲国产精品日韩在线| 老子影院午夜精品无码| 欧美孕妇乳喷奶水在线观看| 人妻少妇偷人精品一区| 精品乱人伦一区二区三区| 亚洲成AV人片在线观高清| 亚洲一区二区精品动漫| 国产猛男猛女超爽免费视频| 无码人妻人妻经典| 久久精品第九区免费观看|