自定义Mybatis框架
一、开发环境的准备及统一
1、 Jdk环境:JDK 1.8 64bit
2、 Maven环境:MAVEN 3.3.9
二、创建Maven工程并引入坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.william</groupId><artifactId>DIYMybatisFramework</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!--解析xml--><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.1.6</version></dependency></dependencies>
</project>
三、 自定义Mybatis框架配置文件结构约定
1.Sql文件约定
<?xml version="1.0" encoding="utf-8" ?>
<mapper namespace="com.william.dao.UserDao"><select id="findAll" resultType="com.william.domain.User">select * from user</select>
</mapper>
2.框架核心配置文件约定
<?xml version="1.0" encoding="UTF-8" ?>
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://127.0.0.1:3306/web02?characterEncoding=utf8" /><property name="username" value="root" /><property name="password" value="root" /></dataSource></environment></environments><mappers><mapper resource="com/william/mapper/UserMapper.xml"></mapper></mappers>
</configuration>
四、核心组件开发
1.Mapper开发
根据Jdbc存在问题的分析,我们已经知道了要将SQL语句放入配置文件中,这样将来修改SQL语句会比较方便,但放在配置文件中的SQL语句还需要读取出来,这样我们就可以基于面向对象思维定义一个Mapper类,用于将配置文件中的SQL语句保存起来,使用时更方便。定义如下:
package Framework.domain;
/*** @author :lijunxuan* @date :Created in 2019/7/9 12:14* @description :* @version: 1.0*/
public class Mapper {private String resultType;private String sql;public String getResultType() {return resultType;}public void setResultType(String resultType) {this.resultType = resultType;}public String getSql() {return sql;}public void setSql(String sql) {this.sql = sql;}
}
2.Configuration开发
我们以面向对象思维操作自定义框架的核心配置文件时,需要有一个实体类与之对应。Configuration 配置类主要用于保存SqlMapConfig.xml文件中读取的xml结点的信息,以及映射的SQL语句的集合。定义如下:
package Framework.domain;import java.util.HashMap;
import java.util.Map;/*** @author :lijunxuan* @date :Created in 2019/7/9 12:16* @description :* @version: 1.0*/
public class Configuration {private String driverClass;private String username;private String password;private String url;private Map<String,Mapper> xmlMap =new HashMap<>();@Overridepublic String toString() {return "Configuration{" +"driverClass='" + driverClass + '\'' +", username='" + username + '\'' +", password='" + password + '\'' +", url='" + url + '\'' +", xmlMap=" + xmlMap +'}';}public String getDriverClass() {return driverClass;}public void setDriverClass(String driverClass) {this.driverClass = driverClass;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public Map<String, Mapper> getXmlMap() {return xmlMap;}public void setXmlMap(Map<String, Mapper> xmlMap) {this.xmlMap = xmlMap;}
}
3.SqlSession接口开发
package Framework.dao;import java.util.List;public interface SqlSession {/**** @param mapperId 唯一的标识* @return*/public List selectList(String mapperId);/*** 释放资源*/public void close();
}
4.SqlSessionImpl实现类开发
package Framework.dao.Impl;import Framework.dao.SqlSession;
import Framework.domain.Configuration;
import Framework.domain.Mapper;
import Framework.utils.Executer;import java.util.List;/*** @author :lijunxuan* @date :Created in 2019/7/9 12:27* @description :* @version: 1.0*/
public class SqlSessionImpl implements SqlSession {private Configuration cfg;private Executer ex;public SqlSessionImpl(Configuration cfg) {this.cfg = cfg;ex=new Executer(cfg);}@Overridepublic List selectList(String mapperId) {//获取sql语句,结果类型Mapper mapper = cfg.getXmlMap().get(mapperId);String sql = mapper.getSql();String resultType = mapper.getResultType();//执行查询操作return ex.executeQuery(sql,resultType);}@Overridepublic void close() {ex.close();}
}
5.Executor执行器开发
Executor类,用于实现SQL语句的执行,主要是调用JDBC来实现SQL语句的执行。
package Framework.utils;
import Framework.domain.Configuration;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/*** sql操作的执行器(工具类)* @author :lijunxuan* @date :Created in 2019/7/9 12:33* @description :* @version: 1.0*/
public class Executer {private Configuration cfg;public Executer(Configuration cfg) {this.cfg = cfg;}private Connection connection;private PreparedStatement preparedStatement;private ResultSet resultSet;/*** 执行sql查询操作,返回集合* @param sql* @param resultType* @return*/public List executeQuery(String sql, String resultType) {List list=new ArrayList();//1.注册驱动try {Class.forName(cfg.getDriverClass());} catch (ClassNotFoundException e) {e.printStackTrace();}//2.获取连接try {connection = DriverManager.getConnection(cfg.getUrl(), cfg.getUsername(), cfg.getPassword());//获取preparedStatement对象preparedStatement = connection.prepareStatement(sql);//3.执行sql语句resultSet = preparedStatement.executeQuery();//获取数据库的元数据:修饰代码的代码(修饰数据的数据)ResultSetMetaData metaData = resultSet.getMetaData();//获取列的个数int columnCount = metaData.getColumnCount();//创建一个列名的集合List<String> columnNames=new ArrayList<>();//获取所有的列名//列的索引从1开始for (int i = 1; i <=columnCount; i++) {String columnName = metaData.getColumnName(i);columnNames.add(columnName);}//获取实体类对象的字节码文件Class clazz = Class.forName(resultType);//根据字节码反射获取实体类中的所有方法Method[] methods = clazz.getMethods();//setUsername set + username//封装结果集(不体现具体的属性和字段名)while (resultSet.next()){//如果resultSet.next()为true,就应该new一个对象//通过反射来获取对象Object o = clazz.newInstance();for (String columnName : columnNames) {for (Method method : methods) {//比较 set +列名 与方法名if (("set"+columnName).equalsIgnoreCase(method.getName())){//如果相同,就找到列对应的set方法//获取列对应的数据Object columnValue = resultSet.getObject(columnName);//反射调用set方法给属性赋值//参数1:需要赋值的对象//参数2: 方法的参数method.invoke(o,columnValue);}}}list.add(o);}//4.处理结果集} catch (Exception e) {e.printStackTrace();}return list;}/*** 释放资源*/public void close(){if (connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}if (preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}}
}
6.SqlSessionFactory开发
SqlSessionFactory的开发基于工厂模式,工厂模式是我们最常用的用来实例化对象的设计模式,是用工厂方法代替new操作的一种模式。创建对象的时候使用工厂模式会带来更大的可扩展性和尽量少的修改量。
package Framework.factory;import Framework.dao.Impl.SqlSessionImpl;
import Framework.dao.SqlSession;
import Framework.domain.Configuration;/*** 使用工厂模式创建sqlSession对象* @author :lijunxuan* @date :Created in 2019/7/9 15:38* @description :* @version: 1.0*/
public class SqlSessionFactory {private Configuration cgf;public SqlSessionFactory(Configuration cgf) {this.cgf = cgf;}public SqlSession openSession(){return new SqlSessionImpl(cgf);}
}
7.SqlSessionFactoryBuilder开发
package Framework.factory;import Framework.domain.Configuration;
import Framework.domain.Mapper;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.InputStream;
import java.util.List;/*** 使用构建者模式创建SqlSessionFactory对象* 解析xml文件,数据存入Configuration对象中* @author :lijunxuan* @date :Created in 2019/7/9 15:41* @description :* @version: 1.0*/
public class SqlSessionFactoryBuilder {private InputStream inputStream;public SqlSessionFactory build(InputStream inputStream){this.inputStream=inputStream;Configuration cfg=new Configuration();loadCongiguration(cfg);return new SqlSessionFactory(cfg);}/*** 解析xml文件,把xml中的数据读入到实体类中*/private void loadCongiguration(Configuration cfg) {//创建SAXReader对象SAXReader saxReader = new SAXReader();//读取流对象,获取文档对象Document doc =null;try {doc = saxReader.read(inputStream);} catch (DocumentException e) {e.printStackTrace();}//解析文档对象,获取根节点Element rootElement = doc.getRootElement();//获取文档中的所有的propertyList<Element> propertyList = rootElement.selectNodes("//property");//遍历集合对象for (Element propertyElement : propertyList) {//获取节点的name属性值和value属性值String nameValue = propertyElement.attributeValue("name");String valueValue = propertyElement.attributeValue("value");if ("driver".equals(nameValue)){cfg.setDriverClass(valueValue);}if ("url".equals(nameValue)){cfg.setUrl(valueValue);}if ("username".equals(nameValue)){cfg.setUsername(valueValue);}if ("password".equals(nameValue)){cfg.setPassword(valueValue);}}//开始解析mappers标签//获取根节点Element root1 =doc.getRootElement();//获取mappers节点Element mappers = root1.element("mappers");//获取所有mapper节点List<Element> mapperList = mappers.elements("mapper");//循环集合for (Element element : mapperList) {String path = element.attributeValue("resource");loadXmlConfiguration(path,cfg);}}/*** 解析xml映射文件* @param path* @param cfg*/private void loadXmlConfiguration(String path, Configuration cfg) {SAXReader saxReader = new SAXReader();//根据路径获取流对象InputStream inputStream = SqlSessionFactoryBuilder.class.getClassLoader().getResourceAsStream(path);Document document = null;try {document = saxReader.read(inputStream);} catch (DocumentException e) {e.printStackTrace();}//获取根节点Element rootElement = document.getRootElement();//获取namespace的属性值String namespace = rootElement.attributeValue("namespace");/*** element(name) 获取第一个名称为name的子节点* elements(name): 获取所有名称为name的子节点* elements(): 获取的是所有的子节点*///获取根节点下的所有子节点List<Element> elements = rootElement.elements();for (Element element : elements) {String idValue = element.attributeValue("id");String resultTypeValue = element.attributeValue("resultType");String sql=element.getTextTrim();/*** key:唯一的标识*/String key=namespace+"."+idValue;Mapper mapper = new Mapper();mapper.setSql(sql);mapper.setResultType(resultTypeValue);cfg.getXmlMap().put(key,mapper);}}
}
8.自定义Mybatis框架架构图
五、安装到Maven仓库
1.使用Idea自带的打包和安装功能将当前工程打成Jar包安装到本地Maven仓库(双击install图标即可):
2.查看本地Maven仓库
自定义Mybatis框架相关推荐
- MyBatis-学习笔记04【04.自定义Mybatis框架基于注解开发】
Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...
- MyBatis-学习笔记03【03.自定义Mybatis框架】
Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...
- 基于自定义Mybatis框架实现数据库操作
一.场景模拟 基于自定义Mybatis框架和已有的Mysql数据库Mybatis,查询所有用户信息. 二.创建工程并引入自定义Mybatis框架的坐标 <?xml version="1 ...
- java day53【 Mybatis框架概述 、 Mybatis 框架快速入门、自定义 Mybatis 框架 】
第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种 定义认为,框架是可被应用开发者定 ...
- 翻过这座山之自定义mybatis框架
前言: 不知不觉以及工作快两年.但是工作年限增加了,技术却没提升多少.之前一直想着自学来着.但是下班回到家毫无疑问都是被手机或者其他事情所吸引
- Java软件开发:自定义MyBatis持久层框架
自定义MyBatis持久层框架 1 框架概述 1.1 什么是框架 1.2 框架要解决的问题 1.3 软件开发的分层的重要性 2 MyBatis框架 3 JDBC编程 3.1 JDBC程序的回顾 3.2 ...
- Mybatis框架(待完善)
框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法:另一种定义认为,框架是可被应用开发者定制的应用骨架.前者是从应用方面而后者是从目的方面给出的定义 ...
- [转载] 快速学习-Mybatis框架概述
参考链接: Java在竞争性编程中的快速I/O 第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互 ...
- 2-自定义 Mybatis 框架
一.分析流程 二. 前期准备 1.创建 Maven 工程 工程信息如下: Groupid:cn.oesoft ArtifactId:mybatis02 Packing:jar 2.引入相关坐标 < ...
最新文章
- Java虚拟机中获得Runtime实例的方法是什么?
- Android学习笔记43:XML文件解析(Pull方式)
- leetcode111. 二叉树的最小深度(层序遍历10)
- 用Lucene建立搜索索引
- 微信模板消息47001错误
- 视频分析服务器作用,如何选择合适的视频分析解决方案?
- 个人财务软件java_个人账务管理系统java
- ESP8266 + MAX7219 做一个简易的自动同步的倒计时时钟
- 2022-2027年中国电动汽车充电站及充电桩行业市场调研及未来发展趋势预测报告
- 仿真软件测试工程师麦克,仿真工程师面试经验 - 共61条真实仿真工程师面试经验分享 - 职业圈...
- 图:国行HTC 8X修改市场区域
- corodva中使用高德地图web js api
- 密战——惊心动魄的网络犯罪追踪小说
- 华三交换机路由器如何配置dhcp中继(dhcp relay)
- 手机摄像头驱动_华为Mate40和iPhone12换机潮下的手机摄像头行业“三剑客”横评:舜宇光学、欧菲光、丘钛科技...
- 谷歌Android无障碍套件,Android无障碍套件
- sscanf和sscanf_s使用方法
- ELK搭建(五):linux系统日志监控平台搭建
- tab weui 页面切换_tab · WeUI.JS 中文文档 · 看云
- 服务器错误码显示,常见错误码说明
热门文章
- kafka streams_Kafka REST Proxy for MapR Streams入门
- java mic波形识别_会议季Mic Drop:您不应该错过的13场Java演讲
- json怎么读取数据库_如何:使用Json插入数据库并从中读取
- apache camel_学习Apache Camel –实时索引推文
- java restful_Java EE中的RESTful计时器
- 抽象工厂模式设计模式_21世纪的设计模式:抽象工厂模式
- 坚实原则:Liskov替代原则
- java创建类的三个步骤_3个简单步骤即可测试Java 8
- redis 持久化性能_高性能持久消息
- 选择的按钮:将ToggleButtons用作单选按钮