说明
MyBatis版本:3.5.1
相关历史文章(阅读本文之前,您可能需要先看下之前的系列)
Spring Boot MyBatis最全教程:你值得拥有MyBatis能脱离Spring吗一图纵览MyBatis的工作原理
说明
MyBatis版本:3.5.1
相关历史文章(阅读本文之前,您可能需要先看下之前的系列)
Spring Boot MyBatis最全教程:你值得拥有
前言
通过上面我们已经可以构建了SqlSessionFactory,接下来的话就是要怎么获取一个SqlSession。
一、分析
对于SqlSession的构建的话,需要有一个属性Configuration,这个属性在上面的SqlSessionFactory已经有了;另外对于SqlSession的真正的Sql执行是交给了Executor,Executor是真正和数据库进行交互了,所以需要将数据库配置信息传给Executor。
二、编码
2.1 Executor
构造SqlSession需要有Executor,我们先创建一个Executor接口:
package com.kfit.mybatis.session; import java.util.List; import com.kfit.mybatis.config.MapperStatement; public interface Executor { <E> List<E> query(MapperStatement ms, Object parameter); }
我们实现一个最基本的SimpleExecutor:
package com.kfit.mybatis.session.impl; import java.util.List; import com.kfit.mybatis.config.JdbcProperties; import com.kfit.mybatis.config.MapperStatement; import com.kfit.mybatis.session.Executor; public class SimpleExecutor implements Executor { private JdbcProperties jdbcProperties; public SimpleExecutor(JdbcProperties jdbcProperties) { this.jdbcProperties = jdbcProperties; } public <E> List<E> query(MapperStatement ms, Object parameter) { //具体的方法待实现 return null; } }
说明:
(1)这里我们实现了最基本的Simple,在MyBatis有3种情况需要处理,我们实现最简单的方式。
(2)这里我们接收了jdbcproperties为了之后直接进行数据库的连接操作,在mybatis数据库的连接关闭,提交,回滚是有一个事务类Transaction。
2.2 SqlSessionFactory
在SqlSessionFactory中添加一个获取SqlSession的方法:
public interface SqlSessionFactory { public Configuration getConfiguration(); public SqlSession openSession(); }
在DefaultSqlSessionFactory实现openSession()方法:
public SqlSession openSession() { Executor executor = new SimpleExecutor(configuration.getJdbcProperties()); SqlSession sqlSession = new DefaultSqlSession(configuration, executor); return sqlSession; }
2.3 SimpleExecutor数据库操作
我们这个对数据库操作的核心代码:
package com.kfit.mybatis.session.impl; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.kfit.mybatis.config.JdbcProperties; import com.kfit.mybatis.config.MapperStatement; import com.kfit.mybatis.session.Executor; public class SimpleExecutor implements Executor { private JdbcProperties jdbcProperties; public SimpleExecutor(JdbcProperties jdbcProperties) { this.jdbcProperties = jdbcProperties; } public <E> List<E> query(MapperStatement ms, Object parameter) { List<E> ret = new ArrayList<E>(); // 具体的方法待实现 try { // 加载驱动 Class.forName(jdbcProperties.getDriver()); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { // 获取连接 connection = DriverManager.getConnection(jdbcProperties.getUrl(), jdbcProperties.getUsername(), jdbcProperties.getPassword()); // 预编译sql语句 preparedStatement = connection.prepareStatement(ms.getSql()); // 处理sql语句中的占位符 parameterize(preparedStatement, parameter); // 执行sql语句 resultSet = preparedStatement.executeQuery(); // 处理结果 handlerResultSet(resultSet, ret, ms.getResultType()); } catch (SQLException e) { e.printStackTrace(); } return ret; } private void parameterize(PreparedStatement preparedStatement, Object parameter) throws SQLException { if (parameter instanceof String) { preparedStatement.setString(1, (String) parameter); } else if (parameter instanceof Long) { preparedStatement.setLong(1, (Long) parameter); } else if (parameter instanceof Integer) { preparedStatement.setInt(1, (Integer) parameter); } } private <E> void handlerResultSet(ResultSet resultSet, List<E> ret, String className) { Class<E> clazz = null; try { clazz = (Class<E>) Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } try { while (resultSet.next()) { // 通过反射实例化对象 Object entity = clazz.newInstance(); // 使用反射工具将resultSet中的数据填充到entity中 // id,name,sex,age // 获取实体类的所有属性,返回Field数组 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); String fname = field.getName(); Type type = field.getGenericType(); if (type.toString().equals("class java.lang.String")) { String column = resultSet.getString(fname); field.set(entity, column); }else if (type.toString().equals("long")) { Long column = resultSet.getLong(fname); field.set(entity, column); } } ret.add((E) entity); } } catch (SQLException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
说明:
(1)在MyBatis中这个代码是分好几个类进行处理的,这里为了讲解方便,统一放在一个类中。
(2)数据库的连接操作:这里使用jdbc连接数据库获取到connection进行操作。
(3)使用泛型处理返回的结果(handlerResultSet)。
2.4 SqlSession的方法
到这里,我们就可以编写SqlSession的方法了,这里定义两个方法SelectOne和SelectList();
public interface SqlSession { <T> T selectOne(String statement, Object parameter); <E> List<E> selectList(String statement); <E> List<E> selectList(String statement, Object parameter); }
对应的DefaultSqlSession:
package com.kfit.mybatis.session.impl; import java.util.List; import com.kfit.mybatis.config.Configuration; import com.kfit.mybatis.session.Executor; import com.kfit.mybatis.session.SqlSession; public class DefaultSqlSession implements SqlSession { private Configuration configuration; private Executor executor; public DefaultSqlSession(Configuration configuration,Executor executor) { this.configuration= configuration; this.executor = executor; } public <E> List<E> selectList(String statement) { return executor.query(configuration.getMapperStatement(statement),null); } public <E> List<E> selectList(String statement,Object parameter) { return executor.query(configuration.getMapperStatement(statement), parameter); } public <T> T selectOne(String statement,Object parameter) { List<T> list = executor.query(configuration.getMapperStatement(statement),parameter); if(list.size()>0) { return list.get(0); } return null; } }
说明:DefaultSqlSession的具体处理交给了Executor,所以这里的具体的实现就比较简单了。
2.5 测试下
在main方法来进行测试一下吧:
public static void main(String[] args) { String resource = "mybatis-config.xml"; InputStream inputStream = App.class.getClassLoader().getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); System.out.println(sqlSessionFactory); System.out.println(sqlSessionFactory.getConfiguration().getJdbcProperties().getUrl()); SqlSession sqlSession = sqlSessionFactory.openSession(); Demo demo = null; List<Demo> demos = null; //使用sqlSession直接查询 demo = sqlSession.selectOne("com.kfit.mybatis.demo.mapper.DemoMapper.getById",1L); System.out.println(demo); demos = sqlSession.selectList("com.kfit.mybatis.demo.mapper.DemoMapper.getAll"); System.out.println(demos); }
这个方法和之前写mybatis的使用方式上是一模一样的,运行看下效果吧:
Demo[id=1, name=张三1]
[Demo [id=1, name=张三1], Demo [id=9, name=张三], Demo [id=10, name=张三], Demo [id=11, name=张三], Demo [id=12, name=张三], Demo [id=13, name=张三]]
看到如此帅气的结果,这是爽歪歪,厉害了我的哥。本篇就先介绍到这里,下一篇我们将会介绍无敌的Mapper实现。
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
à悟空学院:https://t.cn/Rg3fKJD
学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!
SpringBoot视频:http://t.cn/A6ZagYTi
Spring Cloud视频:http://t.cn/A6ZagxSR
SpringBoot Shiro视频:http://t.cn/A6Zag7IV
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringData和JPA视频:http://t.cn/A6Zad1OH
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
Sharding-JDBC分库分表实战:http://t.cn/A6ZarrqS
分布式事务解决方案「手写代码」:http://t.cn/A6ZaBnIr
相关推荐
手写mybatis框架源码 不借助其他任何框架,从最底层开始着手,用最简单的代码,将mybatis的底层框架,手写出来,让你对mybatis有一个更加深刻和直观的理解 详见:...
手写mybatis核心流程代码demo手写mybatis核心流程代码demo手写mybatis核心流程代码demo手写mybatis核心流程代码demo手写mybatis核心流程代码demo手写mybatis核心流程代码demo手写mybatis核心流程代码demo手写mybatis...
在IT行业中,开源框架是构建复杂应用程序的基础,而Spring、SpringMVC和MyBatis作为Java领域的三大核心框架,它们的熟练掌握对于开发者来说至关重要。本系列主要关注这些框架在面试中的常见问题,旨在帮助求职者提升...
本篇文章将深入探讨如何手写Mybatis的核心功能,包括基础的数据库访问、XML映射文件解析以及动态代理机制。 一、数据库访问基础 手写Mybatis的第一步是实现基于JDBC的数据库访问。这通常涉及以下步骤: 1. 数据库...
在IT行业中,Java技术栈是企业级应用开发的主流选择,Spring、SpringMVC和MyBatis这三大开源框架更是核心组件。对于求职者来说,掌握这三个框架的深入理解和使用技巧,是通过技术面试的关键。以下是对这三者进行详细...
在IT行业中,Spring、SpringMVC和MyBatis是三个非常重要的开源框架,它们在企业级Java应用开发中占据了核心地位。本压缩包文件提供的面试题系列,旨在帮助求职者和开发者深入理解这三个框架的核心概念、工作原理以及...
本篇文章将基于阿里巴巴P7架构师纯手工打造的MyBatis源码解析资料,深入探讨MyBatis的核心原理及其内部实现机制。本文旨在帮助读者理解MyBatis的工作原理,并为日后进行更深层次的技术研究提供一定的理论基础。 ###...
Mybatis是中国著名的开源持久层框架,它提供了灵活的SQL映射功能和基于Java的映射文件,使得开发者能够方便地将数据库操作与业务逻辑相分离。在本项目中,我们将探讨如何手写模拟Mybatis的注解实现,深入了解其参数...
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。在本文中,我们将深入探讨如何手写MyBatis实现查询所有操作,以加深对其工作原理的理解。 首先,我们需要理解MyBatis的核心组件。MyBatis...
【标题】"手写简易mybatis"涉及到的知识点主要涵盖了MyBatis框架的核心概念和实现原理,这包括了配置文件解析、SQL会话管理、Mapper注解以及动态代理技术的应用。下面将对这些主题进行详细阐述。 首先,**配置文件...
开发工具 框架JAR mybatis-3.4.2开发工具 框架JAR mybatis-3.4.2开发工具 框架JAR mybatis-3.4.2开发工具 框架JAR mybatis-3.4.2开发工具 框架JAR mybatis-3.4.2开发工具 框架JAR mybatis-3.4.2开发工具 框架JAR ...
手写mybatis框架源码 不借助其他任何框架,从最底层开始着手,用最简单的代码,将mybatis的底层框架,手写出来,让你对mybatis有一个更加深刻和直观的理解 详见:...
ORM,全称Object-Relational ...学习并实践手写ORM框架,不仅有助于理解数据库操作的本质,还能加深对MyBatis等成熟ORM框架的理解。通过这种方式,开发者可以更好地掌握数据持久化的原理,提升在实际项目中的应用能力。
手写mybatis实现,剖析mybatis底层原理
采用SpringBoot2.0、MyBatis-Plus、Shiro框架,开发的一套权限系统 采用SpringBoot2.0、MyBatis-Plus、Shiro框架,开发的一套权限系统 采用SpringBoot2.0、MyBatis-Plus、Shiro框架,开发的一套权限系统 采用...
手写实现mybatis,mybatis处理流程图,mybatis实现需要的几个函数,各个函数的调用。
【标题】"仿照 Mybatis 手写 ROM 框架"揭示了这个项目的核心目标——构建一个类似于 Mybatis 的自定义数据访问框架。Mybatis 是一个著名的 Java ORM(对象关系映射)框架,它允许开发者用 SQL 语句直接操作数据库,...
在IT行业中,开源框架是开发高效、稳定应用的基石,Spring、SpringMVC和MyBatis作为Java领域的三大核心框架,被广泛应用于企业级开发。本资料集合专注于这些框架的面试题,旨在帮助求职者和开发者更好地理解和掌握...
MyBatis 是一款著名的持久层框架,它支持定制化 SQL、存储过程以及高级映射。在本项目中,你提供的是一个自编写的 MyBatis 生成工具,它旨在简化数据库与 Java 模型之间的映射工作,提高开发效率。这个工具的特别之...
`fluent-mybatis` 作为一个活跃的开源项目,有着丰富的文档和社区支持,遇到问题时可以快速获取帮助和解决方案。 在 `fluent-mybatis-master` 压缩包中,包含了项目的源码、示例、文档以及构建脚本等资源,开发者...