最新要闻
- 环球观焦点:AMD发布23.2.2版驱动:RX 7900显卡小打鸡血 性能提升14%
- 天天最新:大理州5个新能源装备制造项目投产
- 深圳一外卖小哥疑送餐时猝死:曾拼命跑上六楼
- 环球热头条丨向上捅破天 吉利银河支持低轨卫星技术:全球无盲区定位
- 13代酷睿i9+满血4060显卡!华硕天选4正式开售 到手价8999元
- 当前短讯!造车新势力 电动自行车品牌“VELOTRIC”A轮融资:获5000万元
- 中疾控提醒:近期水痘处于高发期 要注意做好防护!
- 13代酷睿+RTX 4060!七彩虹将星X16 Pro图赏
- 19999元起 雷蛇推出2023款灵刃15游戏本:i7+RTX 4060
- 股价大涨7% 阿里发布Q3财报:营收2477.6亿 利润超456亿
- 天天通讯!《黑豹》《蚁人》皆扑街 漫威超级英雄为何在国内失宠?
- 男子一脚急刹车醒来直接四肢瘫痪 医生提醒:车祸受伤后别随意拖拽
- 焦点快看:系列首次支持:三星Galaxy Tab S9平板终于支持IP67防水
- 每日热文:三星S23首销:仅重168g的骁龙8 Gen2旗舰 屏幕比小米13更小
- 涨价2000只是开胃菜!销售:特斯拉还要涨价
- 全球今热点:电工化身“Tony”,为留守老人解决“头”等大事
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
day02-自己实现Mybatis底层机制-01
自己实现Mybatis底层机制-01
主要实现:封装SqlSession到执行器+Mapper接口和Mapper.xml+MapperBean+动态代理Mapper的方法
【资料图】
1.Mybatis整体架构分析
对上图的解读:
1)mybatis 的核心配置文件
mybatis-config.xml:进行全局配置,全局只能有一个这样的配置文件
XxxMapper.xml 配置多个SQL,可以有多个 XxxMapper.xml 配置文件
2)通过 mybatis-config.xml 配置文件得到 SqlSessionFactory
3)通过 SqlSessionFactory 得到 SqlSession,用 SqlSession 就可以操作数据了
4)SqlSession 底层是 Executor(执行器),有两个重要的实现类
5)MappedStatement 是通过 XxxMapper.xml 来定义的,用来生成 statement 对象
6)参数输入执行并输出结果集,无需动手判断参数类型和参数下标位置,且自动将结果集映射为Java对象
2.搭建开发环境
(1)创建maven项目
(2)在pom.xml 中引入必要的依赖
UTF-8 1.8 1.8 1.8 dom4j dom4j 1.6.1 mysql mysql-connector-java 5.1.49 org.projectlombok lombok 1.18.4 junit junit 4.12
(3)创建数据库和表
-- 创建数据库CREATE DATABASE `li_mybatis`;USE `li_mybatis`;-- 创建monster表CREATE TABLE `monster`(`id` INT NOT NULL AUTO_INCREMENT,`age` INT NOT NULL,`birthday` DATE DEFAULT NULL,`email` VARCHAR(255) NOT NULL,`gender` TINYINT NOT NULL,-- 1 male,0 female`name` VARCHAR(255) NOT NULL,`salary` DOUBLE NOT NULL,PRIMARY KEY(`id`))CHARSET=utf8-- insertINSERT INTO `monster` VALUES(NULL,200,"2000-11-11","nmw@qq.com",1,"牛魔王",8888);
3.设计思路
解读:
传统的方式操作数据库1)得到 MySession 对象2)调用 MyExecutor 的方法完成操作3)MyExecutor 的连接是从 MyConfiguration 获取
Mybatis 操作数据库的方式1)得到 MySession 对象2)不直接调用 MyExecutor 的方法3)而是通过 MyMapperProxy 获取 Mapper 对象4)调用 Mapper 的方法,完成对数据库的操作5)Mapper 最终还是动态代理方式,使用 MyExecutor 的方法完成操作6)这里比较麻烦的就是 MyMapperProxy 的动态代理机制如何实现
4.任务阶段1
阶段1任务:通过配置文件,获取数据库连接
4.1分析
4.2代码实现
(1)在src 的 resources目录下创建 my-config.xml,模拟原生的 mybatis 配置文件
(2)创建 MyConfiguration 类,用来读取xml文件,建立连接
因为这里重点是实现 Mybatis 的底层机制,为了简化操作,就不使用数据库连接池了,直接使用原生的connection 连接
package com.li.limybatis.sqlsession;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;/** * @author 李 * @version 1.0 * 用来读取xml文件,建立连接 */public class MyConfiguration { //属性-类的加载器 private static ClassLoader loader = ClassLoader.getSystemClassLoader(); //读取xml文件并处理 public Connection build(String resource) { Connection connection = null; try { //先加载配置文件 my-config.xml,获取对应的InputStream InputStream stream = loader.getResourceAsStream(resource); //解析 my-config.xml文件 SAXReader reader = new SAXReader(); Document document = reader.read(stream); //获取 xml文件的根元素 Element root = document.getRootElement(); System.out.println("root=" + root); //根据root解析,获取Connection connection = evalDataSource(root); } catch (Exception e) { e.printStackTrace(); } return connection; } //解析 my-config.xml 的信息,并返回 Connection private Connection evalDataSource(Element node) { if (!"database".equals(node.getName())) { throw new RuntimeException("root节点应该是"); } //连接DB的必要参数 String driverClassName = null; String url = null; String username = null; String password = null; //遍历node下的子节点,获取其属性值 for (Object item : node.elements("property")) { //i就是对应的 property节点 Element i = (Element) item; //property节点的 name属性的值 String name = i.attributeValue("name"); //property节点的 value属性的值 String value = i.attributeValue("value"); //判断值是否为空 if (name == null || value == null) { throw new RuntimeException("property节点没有设置name或value属性!"); } switch (name) { case "url": url = value; break; case "username": username = value; break; case "driverClassName": driverClassName = value; break; case "password": password = value; break; default: throw new RuntimeException("属性名没有匹配到.."); } } //获取连接 Connection connection = null; try { Class.forName(driverClassName); connection = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } return connection; }}
5.任务阶段2
阶段2任务:通过实现执行器机制,对数据表进行操作
5.1分析
我们把对数据库的操作封装到一套Executor机制中,程序具有更好的拓展性,结构更加清晰。这里我们先实现传统的方式连接数据库,即通过MyExecutor直接操作数据库。
5.2代码实现
(1)生成 entity 类 Monster.java
package com.li.entity;import lombok.*;import java.util.Date;/** * @author 李 * @version 1.0 * Monster类和 monster有映射关系 * * 注解说明: * @Getter 给所有属性生成 getter方法 * @Setter 给所有属性生成 setter方法 * @ToString 生成toString方法 * @NoArgsConstructor 生成一个无参构造器 * @AllArgsConstructor 生成一个全参构造器 * @Data 会生成上述除了无参/全参构造器的所有方法,此外还会生成equals,hashCode等方法 */@Getter@Setter@ToString@NoArgsConstructor@AllArgsConstructorpublic class Monster { private Integer id; private Integer age; private String name; private String email; private Date birthday; private double salary; private Integer gender;}
(2)Executor 接口
package com.li.limybatis.sqlsession;/** * @author 李 * @version 1.0 */public interface Executor { //泛型方法 public T query(String statement, Object parameter);}
(3)执行器实现类 MyExecutor.java
package com.li.limybatis.sqlsession;import com.li.entity.Monster;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;/** * @author 李 * @version 1.0 */public class MyExecutor implements Executor { private MyConfiguration myConfiguration = new MyConfiguration(); /** * 根据sql,返回查询结果 * * @param sql * @param parameter * @param * @return */ @Override public T query(String sql, Object parameter) { //获取连接对象 Connection connection = getConnection(); //查询返回的结果集 ResultSet set = null; PreparedStatement pre = null; try { //构建PreparedStatement对象 pre = connection.prepareStatement(sql); //设置参数,如果参数多,可以使用数组处理 pre.setString(1, parameter.toString()); //查询返回的结果集 set = pre.executeQuery(); //把结果集的数据封装到对象中-monster //说明:这里做了简化处理,认为返回的结果就是一个monster记录,完善的写法应该使用反射机制 Monster monster = new Monster(); //遍历结果集,将数据封装到monster对象中 while (set.next()) { monster.setId(set.getInt("id")); monster.setName(set.getString("name")); monster.setEmail(set.getString("email")); monster.setAge(set.getInt("age")); monster.setGender(set.getInt("gender")); monster.setBirthday(set.getDate("birthday")); monster.setSalary(set.getDouble("salary")); } return (T) monster; } catch (Exception e) { e.printStackTrace(); } finally { try { if (set != null) { set.close(); } if (pre != null) { pre.close(); } if (connection != null) { connection.close(); } } catch (Exception e) { e.printStackTrace(); } } return null; } //编写方法,通过myConfiguration对象返回连接 private Connection getConnection() { Connection connection = myConfiguration.build("my-config.xml"); return connection; }}
(4)进行测试
@Testpublic void query() { Executor executor = new MyExecutor(); Monster monster = (Monster) executor.query("select * from monster where id = ?", 1); System.out.println("monster--" + monster);}
测试结果:
6.任务阶段3
阶段3任务:将执行器封装到SqlSession
6.1代码实现
(1)创建 MySqlSession 类,将执行器封装到SqlSession中。
package com.li.limybatis.sqlsession;/** * @author 李 * @version 1.0 * MySqlSession:搭建Configuration(连接)和Executor之间的桥梁 */public class MySqlSession { //执行器 private Executor executor = new MyExecutor(); //配置 private MyConfiguration myConfiguration = new MyConfiguration(); //编写方法selectOne,返回一条记录 public T selectOne(String statement,Object parameter){ return executor.query(statement, parameter); }}
(2)测试
@Testpublic void selectOne() { MySqlSession mySqlSession = new MySqlSession(); Monster monster = (Monster) mySqlSession.selectOne("select * from monster where id=?", 1); System.out.println("monster=" + monster);}
测试结果:
-
day02-自己实现Mybatis底层机制-01
自己实现Mybatis底层机制-01主要实现:封装SqlSession到执行器+Mapper接口和Mapper xml+MapperBean+动...
来源: day02-自己实现Mybatis底层机制-01
世界快资讯:CSS背景设置与Emmet语法
环球观焦点:AMD发布23.2.2版驱动:RX 7900显卡小打鸡血 性能提升14%
天天最新:大理州5个新能源装备制造项目投产
深圳一外卖小哥疑送餐时猝死:曾拼命跑上六楼
环球热头条丨向上捅破天 吉利银河支持低轨卫星技术:全球无盲区定位
13代酷睿i9+满血4060显卡!华硕天选4正式开售 到手价8999元
当前短讯!造车新势力 电动自行车品牌“VELOTRIC”A轮融资:获5000万元
中疾控提醒:近期水痘处于高发期 要注意做好防护!
13代酷睿+RTX 4060!七彩虹将星X16 Pro图赏
19999元起 雷蛇推出2023款灵刃15游戏本:i7+RTX 4060
股价大涨7% 阿里发布Q3财报:营收2477.6亿 利润超456亿
全球快报:第八章 从源文件到可执行文件
天天通讯!《黑豹》《蚁人》皆扑街 漫威超级英雄为何在国内失宠?
男子一脚急刹车醒来直接四肢瘫痪 医生提醒:车祸受伤后别随意拖拽
焦点快看:系列首次支持:三星Galaxy Tab S9平板终于支持IP67防水
每日热文:三星S23首销:仅重168g的骁龙8 Gen2旗舰 屏幕比小米13更小
涨价2000只是开胃菜!销售:特斯拉还要涨价
全球今热点:电工化身“Tony”,为留守老人解决“头”等大事
环球聚焦:邓超谈《中国乒乓》排片少:大家的不容易我非常理解
今亮点!摩根大通已限制员工使用ChatGPT:数据安全更重要
世界视讯!我国第三款国产ECMO产品获批上市:性能达到国际水平
全球即时:月薪4万招人去非洲养鸡当场长?企业回应:环境艰苦 不招年轻人
当前焦点!Windows 上 Docker 部署 MongoDb 并构建数据持久化
2022最新整理iOS app上架app详细教程
webrtc QOS笔记二 音频buffer数据不足生成很多gap的问题
当前最新:记录--前端项目中运行 npm run xxx 的时候发生了什么?
前沿资讯!科考中的意外收获!中国科学家在非洲发现消失百余年的濒危植物
天天速读:极氪001再遭奇葩故障:中控黑了、仪表花了、HUD“涂马赛克”
刚买两个月的谷歌Pixel 7 Pro翻车:绿屏无响应 用户绝望了
世界今头条!《和平精英》将推出开放世界玩法“绿洲世界” 能发射火箭
焦点信息:连过三科!新疆小伙1天拿到驾驶证
今日热议:低代码选型,论协同开发的重要性
【JVM】运行时内存分配
opencv-python 批量更改图像分辨率并且保留图像原有的透明度
热点!数据库概念
世界滚动:k8s~ingress限流机制
全球即时看!方正证券研究报告:行到水穷处,坐看云起时
环球快资讯丨不怕零下40℃极寒!我国复兴号高寒智能动车组投入运行
天天播报:为防员工摸鱼办公桌旁装监控 员工:很无语、感觉没隐私
《王者荣耀》花木兰新皮肤明日上线:143元 美背歌姬
世界时讯:海底捞回应禁止自带菜:可自带酒水饮品
天天短讯!RTX 4090高画质如何?《原子之心》PC平台性能分析:多配置流畅运行
【世界热闻】单特征线性回归
全球实时:为什么说《ps1屠龙刀》是awk、sed的恩人?
天天最资讯丨C语言在线代码运行编译工具推荐
全球快播:联想首款GeekPro游戏本真机公布:1TB SSD 超高性价比
环球微头条丨我国研发人员总量稳居世界首位 顶尖科技人才加速涌现
跑着跑着天窗会掉 奔驰中国召回超2万辆汽车
68岁成龙18年后再拍《神话2》 定名《传说》 古力娜扎主演
观速讯丨外卖员穿工装禁入成都高端商场 成都SKP回应:内部规定
焦点日报:135期 手绘汽车壁纸|插画 卫士还是老款好看 路虎卫士无水印手机壁纸
每日快讯!手把手教你为基于Netty的IM生成自签名SSL/TLS证书
当前热门:《我想进大厂》之Spring夺命连环10问
《分布式技术原理与算法解析》学习笔记Day20
世界看点:数据治理如何做?火山引擎DataLeap帮助这款产品3个月降低计算成本20%
世界今头条!装饰器设计模式这样学,保你必懂!
当前速讯:手机端ChatGPT搜索来了!微软2周火速上线 @Bing即用
多辆房车霸占高速服务区露营:有车主搭帐篷还晒咸菜
魔兽等游戏停服一个月 暴雪真不着急:两家中国公司抢破头
P1219 [USACO1.5]八皇后 Checker Challenge
世界新资讯:Java单元测试浅析(JUnit+Mockito)
81python装饰器
环球聚焦:《龙之家族》第二季明年首播
环球播报:Nginx基础03:配置文件nginx.conf(Part2)
【独家焦点】Python工具箱系列(二十六)
有奖调研!第五期(2022-2023)传统行业云原生技术落地调研——金融篇
全球快资讯丨A/B 测试成为企业“新窗口”:增长盈利告别经验主义,数据科学才是未来
晨光文具批发总部电话_石家庄晨光办公用品有限公司
环球要闻:新款特斯拉Model 3实车谍照曝光:疑似加长、内饰大改
可口可乐风味饮品!柠檬道日式气泡酒大促:12罐不到30元
前沿资讯!《嗜血印》将推出女祭司1/4比例雕像 性感热辣吸睛
焦点快播:送礼新思路!淘宝公布2023年度丑东西:网红青蛙服入选“年度五丑”
天天快报!C# Socket 通信时,怎样判断 Socket 双方是否断开连接
易基因|ChIP-seq等组学研究鉴定出结直肠癌的致癌超级增强子:Nature子刊
报道:顶象APP加固的“蜜罐”技术有什么作用
为什么带NOLOCK的查询语句还会造成阻塞
全球今亮点!支付宝二面:使用 try-catch 捕获异常会影响性能吗?大部分人都会答错!
名山大川是什么意思?名山大川有哪些?
喜欢被剧透的人是什么心理?喜欢被剧透的人是什么倾向?
每日快报!58岁清华毕业找不到超5000元工作 网友:我不是清华的咋办
天天热门:爷青结!《DNF》端游正式更名《地下城与勇士:创新世纪》:图标、文字调整
全球即时:《原子之心》优化非常好 但Xbox Series S仍存掉帧问题
精致又简约!雷孜LaCie新棱镜移动硬盘评测:速度全程稳如初
小米13 Ultra手机壳曝光:中分四摄、凸起严重
戴拿奥特曼飞鸟信扮演者怎么了?戴拿奥特曼的结局是什么?
四要十不准是什么意思?四要十不准内容有哪些?
童话故事是什么文体?出自童话故事的成语有哪些?
八门神器怎么打不开?八门神器使用教程
格兰仕电烤箱功能及使用方法有哪些?格兰仕电烤箱售后电话是多少?
智能abc输入法属于什么码?智能abc怎么打空格?
联想p700怎么样?联想p700手机参数?
thinkpad平板电脑怎么样?thinkpad平板电脑推荐
天天头条:Linux视频上传及压缩
Java 在线代码运行编译工具推荐
湖北长江产投将入股?集度汽车:正常交流活动
会员收入创单季最高!龚宇:爱奇艺已解决债务问题
每日焦点!原味、藤椒味 肉香酥脆:亚明农家小酥肉15元/斤狂促
【环球报资讯】大批玩家称玩《原子之心》恶心想吐!官方称将更新FOV设置
手机的飞行模式还有这些妙用!看到不点开后悔一生