采集做网站,网站代优化,建设网站公司招聘,wordpress帖子缩略图#x1f600;前言 本篇博文是学习过程中的笔记和对于MyBatis底层机制的分析思路#xff0c;希望能够给您带来帮助#x1f60a; #x1f3e0;个人主页#xff1a;晨犀主页 #x1f9d1;个人简介#xff1a;大家好#xff0c;我是晨犀#xff0c;希望我的文章可以帮助到… 前言 本篇博文是学习过程中的笔记和对于MyBatis底层机制的分析思路希望能够给您带来帮助 个人主页晨犀主页 个人简介大家好我是晨犀希望我的文章可以帮助到大家您的满意是我的动力
欢迎大家这里是CSDN我总结知识的地方欢迎来到我的博客感谢大家的观看 如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦 文章目录 自己实现MyBatis 底层机制[上]MyBatis 整体架构分析Mybatis 核心框架示意图核心框架示意图的解读 搭建MyBatis 底层机制开发环境1、创建Maven 项目nlc-mybatis2、修改nlc-mybatis\pom.xml3、创建数据库和表4、到此: 项目开发环境搭建完成 Nlc-Mybatis 的设计思路Mybatis 的底层实现设计1. 传统方式操作数据库2.MyBatis操作数据库的方式分析 自己实现MyBatis 底层机制实现任务阶段1- 完成读取配置文件得到数据库连接分析示意图代码实现完成测试测试效果 实现任务阶段2- 编写执行器输入SQL 语句完成操作分析示意图代码实现完成测试 总结 自己实现MyBatis 底层机制[上]
MyBatis 整体架构分析
Mybatis 核心框架示意图 核心框架示意图的解读
mybatis 的核心配置文件 mybatis-config.xml: 进行全局配置全局只能有一个这样的配置文件 XxxMapper.xml 配置多个SQL可以有多个XxxMappe.xml 配置文件通过mybatis-config.xml 配置文件得到SqlSessionFactory通过SqlSessionFactory 得到SqlSession用SqlSession 就可以操作数据了SqlSession 底层是Executor(执行器), 有两个重要的实现类基本执行器和带缓存功能的执行器 有很多方法 MappedStatement 是通过XxxMapper.xml 中定义, 生成的statement 对象参数输入执行并输出结果集, 无需手动判断参数类型和参数下标位置, 且自动将结果集映射为Java 对象
搭建MyBatis 底层机制开发环境
1、创建Maven 项目nlc-mybatis
前面快速入门有创建步骤这里不在描述。
2、修改nlc-mybatis\pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.nlc/groupIdartifactIdnlc-mybatis/artifactIdversion1.0-SNAPSHOT/version!--定义编译器 / source / target 版本即可--propertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetjava.version1.8/java.version/properties!--引入必要的依赖--dependencies!--引入dom4j--dependencygroupIddom4j/groupIdartifactIddom4j/artifactIdversion1.6.1/version/dependency!--引入mysql依赖--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.49/version/dependency!--lombok-简化entity/javabean/pojo开发 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.4/version/dependency!--junit依赖--dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version/dependency/dependencies
/project3、创建数据库和表
CREATE DATABASE nlc_mybatis;
USE nlc_mybatis;
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,name VARCHAR(255) NOT NULL,salary DOUBLE NOT NULL,PRIMARY KEY (id)
) CHARSETutf8
INSERT INTO monster VALUES(NULL, 200, 2000-11-11, nmwsohu.com, 1,牛魔王, 8888.88)4、到此: 项目开发环境搭建完成
Nlc-Mybatis 的设计思路
Mybatis 的底层实现设计 1. 传统方式操作数据库 得到Session对象 调用Executor的方法完成操作 Executor的连接是从Configuration获取的
2.MyBatis操作数据库的方式分析
得到Session不用直接调用Executor的方法完成操作通过MapperProxy获取Mapper对象调用Mapper的方法完成数据库的操作Mapper最终还是动态代理方式使用Executor的方法完成操作MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
自己实现MyBatis 底层机制
实现任务阶段1- 完成读取配置文件得到数据库连接
通过配置文件获取数据库连接。
分析示意图 代码实现
创建nlc-mybatis\src\main\resources\nlc_config.xml
?xml version1.0 encodingUTF-8 ?
database!--配置连接数据库的信息--property namedriverClassName valuecom.mysql.jdbc.Driver/!--配置连接mysql-url1. jdbc:mysql 协议2. 127.0.0.1:3306 : 指定连接mysql的ipport3. mybatis: 连接的DB4. useSSLtrue 表示使用安全连接5. amp; 表示 防止解析错误6. useUnicodetrue : 使用unicode 作用是防止编码错误7. characterEncodingUTF-8 指定使用utf-8, 防止中文乱码8. 不要背直接使用即可--property nameurl valuejdbc:mysql://localhost:3306/nlc_mybatis?useSSLtrueamp;useUnicodetrueamp;characterEncodingUTF-8/property nameusername valueroot/property namepassword value123456/
/database创建nlc-mybatis\sqlsession\NlcConfiguration.java
public class NlcConfiguration {//属性-类的加载器private static ClassLoader loader ClassLoader.getSystemClassLoader();//读取xml文件信息并处理public Connection build(String resource) {Connection connection null;try {//加载配置nlc_mybatis.xml 获取到对应的InputStreamInputStream stream loader.getResourceAsStream(resource);SAXReader reader new SAXReader();Document document reader.read(stream);//获取到nlc_mybatis.xml 的根元素 databaseElement root document.getRootElement();System.out.println(root root);//解析root元素返回Connection connection evalDataSource(root);} catch (Exception e) {e.printStackTrace();}return connection;}//方法会解析nlc_config.xml 信息,并返回Connection//eval: 评估/解析private Connection evalDataSource(Element node) {if (!database.equals(node.getName())) {throw new RuntimeException(root 节点应该是database);}//连接DB的必要参数String driverClassName null;String url null;String username null;String password null;//遍历node下的子节点获取属性值for (Object item : node.elements(property)) {Element i (Element) item;//i 就是 对应property节点String name i.attributeValue(name);String value i.attributeValue(value);//判断是否得到name 和 valueif (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 {//要求JVM查找并加载指定的类到内存中此时将com.mysql.jdbc.Driver 当做参数传入// 就是告诉JVM去com.mysql.jdbc这个路径下找Driver类将其加载到内存中。Class.forName(driverClassName);connection DriverManager.getConnection(url,username,password);} catch (Exception e) {e.printStackTrace();}return connection; //返回Connection}}完成测试
编写nlc-mybatis\src\test\java\com\nlc\test\NlcMybatisTest.java
public class NlcMyBatisTest {Testpublic void build() {NlcConfiguration nlcConfiguration new NlcConfiguration();Connection connection nlcConfiguration.build(nlc_mybatis.xml);System.out.println(connection-- connection);}
}测试效果 实现任务阶段2- 编写执行器输入SQL 语句完成操作
说明通过实现执行器机制对数据表操作。
分析示意图
说明我们把对数据库的操作会封装到一套Executor 机制中程序具有更好的扩展性,结构更加清晰. 代码实现
创建nlc-mybatis\src\main\java\com\nlc\entity\Monster.java
如果使用Data注解需要全参构造器可以添加AllArgsConstructor但是无参构造器必须要显示调用否则会被全参构造器覆盖。
/*** Monster 和 monster表有映射关系* Getter 就会给所有属性 生成对应的getter* Setter 就会给所有属性 生成对应的setter* ToString 生成 toString...* NoArgsConstructor 生成无参构造器* AllArgsConstructor 生成要给全参构造器* Data 会生成上面除全参构造器的所有注解* 如何选择主要还是看自己需要*/
Data
AllArgsConstructor
NoArgsConstructor
ToString
public class Monster {private Integer id;private Integer age;private String name;private String email;private Date birthday;private double salary;private Integer gender;}创建nlc-mybatis\src\main\java\com\nlc\nlcmybatis\sqlsession\Executor.java
public interface Executor {//泛型方法public T T query(String statement, Object parameter);
}创建nlc-mybatis\src\main\java\com\nlc\nlcmybatis\sqlsession\NlcExecutor.java
public class NlcExecutor implements Executor {//属性private NlcConfiguration nlcConfiguration new NlcConfiguration();// 根据 sql 查找结果Overridepublic T T query(String sql, Object parameter) {//得到连接ConnectionConnection connection getConnection();//查询返回的结果集ResultSet set null;PreparedStatement pre null;try {pre connection.prepareStatement(sql);//设置参数, 如果参数多, 可以使用数组处理.pre.setString(1, parameter.toString());set pre.executeQuery();//把set数据封装到对象-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 throwables) {throwables.printStackTrace();} finally {try {if (set ! null) {set.close();}if (pre ! null) {pre.close();}if (connection ! null) {connection.close();}} catch (Exception throwables) {throwables.printStackTrace();}}return null;}//编写方法,通过NlcConfiguration对象返回连接private Connection getConnection() {Connection connection nlcConfiguration.build(nlc_mybatis.xml);return connection;}
}完成测试
修改nlc-mybatis\src\test\java\com\nlc\test\NlcMybatisTest.java , 增加测试方法
Testpublic void query() {Executor executor new NlcExecutor();Monster monster executor.query(select * from monster where id?, 1);System.out.println(monster-- monster);}测试效果 总结
了解底层的机制可以帮助我们更好的学习阅读优秀的源码可以增长我们的功力。适当的debug可以解决我们的疑惑底层是一个非常庞大的集成把握主干就可以了。过于追根究底只会影响自己的心绪会耗费大量时间精力。如果自己感兴趣的话可以多研究一下会发现其中的乐趣点到即止。 文章到这里就结束了如果有什么疑问的地方请指出诸大佬们一起来评论区一起讨论 希望能和诸大佬们一起努力今后我们一起观看感谢您的阅读 如果帮助到您不妨3连支持一下创造不易您们的支持是我的动力