自定义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仓库

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333110.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 命令之 userconf -- 设置用户账号

文章目录命令介绍常用选项参考示例新增用户账号新增群组删除用户账号删除群组命令介绍 userconf的命令全称是“user config”&#xff0c;该命令是用户账号设置程序。 userconf实际上为linuxconf的符号连接&#xff0c;提供图形界面的操作方式&#xff0c;供管理员建立与管理各…

javafx 动画没效果_通过JavaFX标注制作动画效果

javafx 动画没效果在本文中&#xff0c;您将学习如何使用JavaFX的动画API创建标注。 您可以在https://www.youtube.com/watch?vXTHbB0LRdT4的 YouTube网站上查看这些标注的演示示例。 什么是标注&#xff1f; 我敢肯定&#xff0c;您已经看过广告或科幻电影&#xff0c;它们使…

基于自定义Mybatis框架实现数据库操作

一、场景模拟 基于自定义Mybatis框架和已有的Mysql数据库Mybatis&#xff0c;查询所有用户信息。 二、创建工程并引入自定义Mybatis框架的坐标 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0…

javafx按钮设计风格_Java,JavaFX的流畅设计风格按钮,切换按钮和工具提示

javafx按钮设计风格你好&#xff0c;我们又见面了&#xff01; 这个周末&#xff0c;在业余时间&#xff0c;我继续从事JMetro的工作。 最终结果是新的Button和ToggleButton深色和浅色样式。 这些新样式包括按下按钮时的新动画。 可以通过CSS打开和关闭。 最后&#xff0c;我…

MySQL数据库变量_数据库参数_MySQL变量_系统变量_用户变量

文章目录MySQL 变量分类系统变量查看系统变量设置系统变量如何通过配置文件来设置变量值通过命令行选项来设置变量值动态设置全局级的系统变量设置静态的系统变量设置会话级的系统变量引用系统变量总结用户自定义变量用户变量声明定义用户变量查看用户变量的值参考示例使用命令…

Mybatis框架快速入门

一、场景模拟 基于自定义Mybatis框架和已有的Mysql数据库Mybatis&#xff0c;查询所有用户信息。 二、创建工程并引入Mybatis框架的坐标 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"…

oidc_使用Java EE和OIDC构建Java REST API

oidc“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 Java EE允许您使用JAX-RS和JPA快速轻松地构建Java REST API。 Java EE是保护伞标…

Mybatis实现CRUD操作

项目实现的功能 查询所有用户信息 通过Id查询用户信息 添加用户&#xff08;回显主键&#xff09; 修改用户信息 删除用户信息 通过用户名字模糊查询 一、引入依赖和工程结构 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http…

Linux系统下MySQL的导出数据语句SELECT … INTO OUTFILE的用法

文章目录关于参数 secure_file_priv按默认参数设定导出表数据到文本文件中自定义分隔符&#xff0c;将表数据导出到 txt 文件中自定义分隔符&#xff0c;将表数据导出到 csv 文件中导出数据时&#xff0c;提示“拒绝访问”总结确保 Linux 用户 mysql 对导出的目标目录拥有写入和…

java cxf_拥抱模块化Java平台:Java 10上的Apache CXF

java cxfJava 9版本终于将Project Jigsaw交付给大众已经过去了一年的时间。 这是一段漫长的旅程&#xff0c;但是在那里&#xff0c;所以发生了什么变化&#xff1f; 这是一个很好的问题&#xff0c;答案并不明显和直接。 总的来说&#xff0c; 拼图项目是一种颠覆性的变化&am…

MySQL数据字典

数据字典就类似于系统编目或花名册&#xff0c;它保存数据库服务器上的元数据信息&#xff08;数据库的整体属性信息&#xff09;。 元数据信息包括&#xff1a;数据库的属性信息、数据表的属性信息、字段的属性信息、视图的属性信息、用户信息、统计类信息等。 MySQL 保存元…

Mybatis映射文件SQL语句模糊查询,#和$的区别和注意事项

Mybatis映射文件SQL语句模糊查询 1. “%”#{value}"%" 在参数中不需要添加 %_ 推荐使用 2. ‘%${value}%’ 在参数中不需要添加 %_ 3. #{abc} 在参数中添加 %_ #和$的区别和注意事项 ${}直接拼接 &#xff0c;不会转换类型 如果是简单类型&#xff0c;必须写${…

启动php-fpm服务器_无服务器冷启动不是问题-这就是为什么(对于大多数应用程序)...

启动php-fpm服务器从无服务器开始时&#xff0c;您很快就会学习/听到有关函数冷启动的信息&#xff08;我相信无服务器云功能 API &#xff09;。 首次调用云功能时或长时间不调用后会发生冷启动。 基本上&#xff0c;服务器&#xff08;是的&#xff0c;有服务器&#xff01;&…

声明定义存储过程或者函数时,其中的 delimiter 关键字是干嘛的呢?

我们写 SQL 的时候&#xff0c;MySQL 怎么判断 SQL 是否已经结束了&#xff0c;可以去执行了&#xff1f; 需要一个结束符&#xff0c;当 MySQL 看到这个结束符的时候&#xff0c;表示可以执行前面的语句了&#xff0c;MySQL 默认以分号为结束符。 当我们创建存储过程或者自定…

istio api_Istio的网络API解释了

istio apiIstio 1.0版附带一个网络API&#xff0c;该API包含许多功能并涵盖了各种场景。 联网API在最近几个月中得到了发展&#xff0c;并且可能不会立即说明。 该API的概念和构建块是什么&#xff0c;以及如何使用各个Istio资源类型来通过我们的服务网格路由流量&#xff1f; …

MySQL命令之mysqldump的选项详解

文章目录--opt--skip-opt--add-drop-table--add-locks--skip-add-locks--allow-keywords--all-databases,-A--comments--skip-comments--compact--complete-insert,-c--compress,-C--events,-E--compatible--skip-disable-keys,-K--skip-add-drop-table--quick,-q--skip-quick-…

网关限流(令牌桶算法)

一、需求&#xff1a; 每个ip地址1秒内只能发送1次请求&#xff0c;多出来的请求返回429错误。 二、引入依赖 spring cloud gateway 默认使用redis的RateLimter限流算法来实现。所以我们要使用首先需要引入redis的依赖 <!--redis--> <dependency><groupId&g…

openapi_MicroProfile OpenAPI上的Swagger UI

openapiMicroProfile OpenApi为我们提供了一种使用OpenApi 3描述我们JAX-RS API的标准化方法。如果您以前使用过swagger-jaxrs和swagger- 批注 &#xff0c;由于OpenApi是基于Swagger构建的&#xff0c;因此您会感到非常熟悉。 2015年11月5日&#xff0c;SmartBear与3Scale&am…

MySQL的用户表(user)

文章目录字段 host 中的特殊值介绍user 字段中的特殊值介绍我们查看下这张表的字段 host 和 user&#xff0c;如下所示&#xff1a; mysql> select host,user from user; ----------------------------- | host | user | ----------------------------- |…

BCrypt管理员登录密码验证

一、简单入门测试 BCrypt不支持反运算&#xff0c;只支持密码校验 package com.william.test;import org.springframework.security.crypto.bcrypt.BCrypt;/*** author &#xff1a;lijunxuan* date &#xff1a;Created in 2019/7/11 11:34* description &#xff1a;* ver…