当前位置: 首页 > news >正文

做网站如何使用数据库西安关键词网站排名

做网站如何使用数据库,西安关键词网站排名,做网站以后的趋势,代练中介网站有得做吗前言 学习源码是在学习什么呢? 就是为了通过这些源码级复杂模型中,学习系统框架的架构思维、设计原则和设计模式。在这些源码学习手写的过程中,感受、吸收并也是锻炼一种思维习惯,并尝试把这些思路技术迁移到平常的复杂业务设计开…

前言
学习源码是在学习什么呢?
就是为了通过这些源码级复杂模型中,学习系统框架的架构思维、设计原则和设计模式。在这些源码学习手写的过程中,感受、吸收并也是锻炼一种思维习惯,并尝试把这些思路技术迁移到平常的复杂业务设计开发中。
目标
通常在数据库表字段的命名中,所定义的规范是希望使用小写的英文字母和下划线的方式组合使用,例如:雇员表中的雇员姓名,则使用 employee_name 表字段描述。但这样的字段定义与 Java 代码开发中的 PO 数据库对象中的字段,是不能一一匹配的,因为 Java 代码中会使用驼峰的方式进行命名,同样是雇员姓名在 Java 代码中则是 employeeName 的方式进行表示。

那么这里就有一个问题了,我们在使用 Mybatis 框架的时候,如果遇到这样的字段,则需要通过把数据库表中的下划线的字段名称,映射成 Java 代码中的驼峰字段,这样才能在执行查询操作的时候,正确的把数据库中的结果映射到 Java 代码的返回对象上。注意:另外在 Mybatis 中也可以使用例如 employee_name as employeeName 的方式进行处理,但在整个编程中并不是太优雅,因为所有的查询都要做 as 映射,那么使用一个统一的字段映射更加合理。
设计
在这里插入图片描述
以 XMLMapperBuilder 解析为入口,扩展 resultMapElements 方法,解析 resultMap 映射参数。解析过程涉及到了 MapperBuilderAssistant 映射器构建助手类的使用,所以需要在 XMLMapperBuilder 构造函数中进行初始化。
参数的解析细节主要在 MapperBuilderAssistant 映射构建器助手中完成,包括解析 javaTypeClass、typeHandlerInstance,以及封装 XML 配置的基本字段映射信息。
解析映射配置
整个配置解析都以围绕在 Mybatis ORM 框架中使用 resultMap 映射为主,而 resultMap 的参数映射配置也是用于解决数据库表中的字段与 Java 代码中的对象字段不一致的情况。
在这里插入图片描述
解析入口
基于这样对映射字段的解决方案,所以需要扩展 Mapper XML 映射构建器 configurationElement 方法的处理内容,添加解析 resultMap 操作。这部分的操作也就是在解析整个 select、insert、update、delete 之前就操作这个部分,因为后续解析 select 标签时,如果遇到有 resultMap 的配置参数,则可以直接调用已经解析的 resultMap 参数进行关联。

private void configurationElement(Element element) {// 1.配置namespaceString namespace = element.attributeValue("namespace");if (namespace.equals("")) {throw new RuntimeException("Mapper's namespace cannot be empty");}builderAssistant.setCurrentNamespace(namespace);// 2. 解析resultMapresultMapElements(element.elements("resultMap"));// 3.配置select|insert|update|deletebuildStatementFromContext(element.elements("select"),element.elements("insert"),element.elements("update"),element.elements("delete"));
}

在 XMLMapperBuilder#configurationElement 配置元素解析的方法中,新增加了关于 resultMap 元素的解析,由于可能在一个 Mapper XML 中有多组这样的映射参数配置,所以这里获取的是一个 elements 集合元素。
解析过程

private ResultMap resultMapElement(Element resultMapNode, List<ResultMapping> additionalResultMappings) throws Exception {String id = resultMapNode.attributeValue("id");String type = resultMapNode.attributeValue("type");Class<?> typeClass = resolveClass(type);List<ResultMapping> resultMappings = new ArrayList<>();resultMappings.addAll(additionalResultMappings);List<Element> resultChildren = resultMapNode.elements();for (Element resultChild : resultChildren) {List<ResultFlag> flags = new ArrayList<>();if ("id".equals(resultChild.getName())) {flags.add(ResultFlag.ID);}// 构建 ResultMappingresultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));}// 创建结果映射解析器ResultMapResolver resultMapResolver = new ResultMapResolver(builderAssistant, id, typeClass, resultMappings);return resultMapResolver.resolve();
}

解析的核心过程包括读取 resultMap 标签中,如: 的 id、type 信息。之后开始循环解析标签内的每一条配置元素 如 中的 colum、property 信息。同时这里会把id的配置专门用 ResultFlag 枚举类进行标记。
基础信息解析完成后,就开始调用结果映射器把解析的信息封装成 ResultMap 进行存放。
存放映射对象

public class ResultMapResolver {private final MapperBuilderAssistant assistant;private String id;private Class<?> type;private List<ResultMapping> resultMappings;// ... 省略构造函数public ResultMap resolve() {return assistant.addResultMap(this.id, this.type, this.resultMappings);}}

ResultMapResolver 结果映射器是本章节新增加的内容,其实它的作用就是对解析结果内容的一个封装处理,最终调用的是还是 MapperBuilderAssistant 映射构建器助手,所提供 ResultMap 封装和保存操作。
封装 ResultMap

public class ResultMap {private String id;private Class<?> type;private List<ResultMapping> resultMappings;private Set<String> mappedColumns;private ResultMap() {}public static class Builder {private ResultMap resultMap = new ResultMap();public Builder(Configuration configuration, String id, Class<?> type, List<ResultMapping> resultMappings) {resultMap.id = id;resultMap.type = type;resultMap.resultMappings = resultMappings;}public ResultMap build() {resultMap.mappedColumns = new HashSet<>();// 添加 mappedColumns 字段for (ResultMapping resultMapping : resultMap.resultMappings) {final String column = resultMapping.getColumn();if (column != null) {resultMap.mappedColumns.add(column.toUpperCase(Locale.ENGLISH));}}return resultMap;}}// ... 省略get方法}

ResultMap 中 Builder 建造者负责完成字段的处理,通过把字段统一转换为大写存放到 mappedColumns 映射字段中。并返回 resultMap 对象。其余的信息都可以通过构造函数进行传递。
添加 ResultMap

public class MapperBuilderAssistant extends BaseBuilder {private String currentNamespace;private String resource;// ... 省略部分方法public MapperBuilderAssistant(Configuration configuration, String resource) {super(configuration);this.resource = resource;}public ResultMapping buildResultMapping(Class<?> resultType,String property,String column,List<ResultFlag> flags) {Class<?> javaTypeClass = resolveResultJavaType(resultType, property, null);TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, null);ResultMapping.Builder builder = new ResultMapping.Builder(configuration, property, column, javaTypeClass);builder.typeHandler(typeHandlerInstance);builder.flags(flags);return builder.build();}public ResultMap addResultMap(String id, Class<?> type, List<ResultMapping> resultMappings) {// 补全ID全路径,如:cn.bugstack.mybatis.test.dao.IActivityDao + activityMapid = applyCurrentNamespace(id, false);ResultMap.Builder inlineResultMapBuilder = new ResultMap.Builder(configuration,id,type,resultMappings);ResultMap resultMap = inlineResultMapBuilder.build();configuration.addResultMap(resultMap);return resultMap;}}

在 MapperBuilderAssistant 映射构建器助手中,本章新增加了2个方法,构建 Mapping 方法 buildResultMapping、添加 ResultMap 方法 addResultMap。
而构建 buildResultMapping 方法就是在最开始 Mapper XML 映射构建器解析 buildResultMappingFromContext 所调用的 XMLMapperBuilder#buildResultMapping 方法,封装映射配置中 column、property 字段。
另外一个是 MapperBuilderAssistant#addResultMap 方法,从 ResultMapResolver 结果映射器调用添加 ResultMap,最终就是把这个配置保存到 Configuration 配置项中。
使用映射对象
从 DefaultSqlSession 调用方法,执行 SQL 后,就是对结果的封装,主要体现在 DefaultResultSetHandler#handleResultSets 结果收集器的操作中。

private boolean applyPropertyMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {final List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);boolean foundValues = false;final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();for (ResultMapping propertyMapping : propertyMappings) {final String column = propertyMapping.getColumn();if (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH))) {// 获取值final TypeHandler<?> typeHandler = propertyMapping.getTypeHandler();Object value = typeHandler.getResult(rsw.getResultSet(), column);// 设置值final String property = propertyMapping.getProperty();if (value != NO_VALUE && property != null && value != null) {// 通过反射工具类设置属性值metaObject.setValue(property, value);foundValues = true;}}}return foundValues;
}

从 DefaultResultSetHandler#handleResultSets 方法开始,调用 handleResultSet 方法,创建结果处理器、封装数据和保存结果。

那么在封装数据阶段,则包括了创建对象和封装对象属性,源码参考DefaultResultSetHandler#getRowValue
测试

CREATE TABLE activity  (id  bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增ID',activity_id  bigint(20) NOT NULL COMMENT '活动ID',activity_name  varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '活动名称',activity_desc  varchar(128) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '活动描述',create_time  datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',update_time  datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',PRIMARY KEY (id ),UNIQUE KEY unique_activity_id (activity_id )
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='活动配置';

配置数据源

<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/mybatis?useUnicode=true&characterEncoding=utf8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment>
</environments>

通过 mybatis-config-datasource.xml 配置数据源信息,包括:driver、url、username、password
在这里 dataSource 可以按需配置成 DRUID、UNPOOLED 和 POOLED 进行测试验证。
配置Mapper加载方式

<mappers><!-- XML 配置 --><mapper resource="mapper/Activity_Mapper.xml"/>
</mappers>

配置Mapper XML 语句

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bugstack.mybatis.test.dao.IActivityDao"><resultMap id="activityMap" type="cn.bugstack.mybatis.test.po.Activity"><id column="id" property="id"/><result column="activity_id" property="activityId"/><result column="activity_name" property="activityName"/><result column="activity_desc" property="activityDesc"/><result column="create_time" property="createTime"/><result column="update_time" property="updateTime"/></resultMap><select id="queryActivityById" parameterType="java.lang.Long" resultMap="activityMap">SELECT activity_id, activity_name, activity_desc, create_time, update_timeFROM activityWHERE activity_id = #{activityId}</select></mapper>

映射对象类

public class Activity {/*** 自增ID*/private Long id;/*** 活动ID*/private Long activityId;/*** 活动名称*/private String activityName;/*** 活动描述*/private String activityDesc;/*** 创建人*/private String creator;/*** 创建时间*/private Date createTime;/*** 修改时间*/private Date updateTime;// ... 省略 get/set}

单元测试

@Before
public void init() throws IOException {// 1. 从SqlSessionFactory中获取SqlSessionSqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config-datasource.xml"));sqlSession = sqlSessionFactory.openSession();
}@Test
public void test_queryActivityById(){// 1. 获取映射器对象IActivityDao dao = sqlSession.getMapper(IActivityDao.class);// 2. 测试验证Activity res = dao.queryActivityById(100001L);logger.info("测试结果:{}", JSON.toJSONString(res));
}

测试结果
在这里插入图片描述
总结

结合着整个框架和 ResultMap 提前预留出来的参数解析框架,添加映射类参数的处理操作。在整个解析的过程中,一个 ResultMap 对应多个 ResultMapping 的关系,把每一条映射都存处理成 ResultMapping 信息,都存放到配置项中。前面我们就提到过 Configuration 伴随整个 session 生命周期
所有的解析操作完成以后就是到了接触处理封装中,这里你可以思考怎么把 SQL 执行的结果和对象封装到一起,普通的对象默认按照对象字段即可封装,而带有下划线的属性字段,则需要根据映射的2个字段,下划线对应非下划线的方式,进行匹配处理。最终返回统一的封装对象结果。

好了到这里就结束了手写手写mybatis之解析和使用ResultMap映射参数配置的学习,大家一定要跟着动手操作起来。需要源码的 可si我获取;

http://www.hkea.cn/news/4491/

相关文章:

  • 手机能用的网站项目平台
  • 南宁建站方案国内十大4a广告公司
  • 玉溪网站建设网站建设做电商如何起步
  • 南宁网站建设-中国互联最近发生的新闻
  • 98同城招聘网信息附近seo公司广州
  • pc网站做成移动网站seo网络营销推广
  • 网站的邀请怎么做的徐州seo排名公司
  • 微信小程序云开发收费标准seo入门教程
  • 长沙市网站制作多少钱营销型企业网站建设步骤
  • 办公室设计布局平面图专业网站优化推广
  • 企业网站如何进行定位南宁seo推广
  • 无锡做网站、百度一下首页网页
  • 嘉定房地产网站建设济南网络优化哪家专业
  • 宁波网站怎么建设seo什么职位
  • 响应式网站开发的特点品牌关键词优化哪家便宜
  • 甘肃网站建设专家百度快速收录入口
  • 中国室内设计艺术千年回眸seo免费优化
  • 东莞网站竞价推广seo网站营销推广公司
  • 网站建设维护更新百度谷歌seo优化
  • 建工网校app小辉seo
  • 怎么找做网站的客户网络广告营销策略
  • 怎么免费建立网店网站seo 工具分析
  • 网站做cdn怎么弄网址收录
  • web网站开发 ASP.NET长沙网络营销推广公司
  • 188自助建站系统网站被禁用如何解决
  • 软件工程职业生涯规划书深圳网站搜索优化工具
  • 网站建设文化策划书百度竞价推广怎么做效果好
  • 怎么做淘宝返利网站吗网络推广平台有哪些公司
  • 在线整合营销推广广州seo软件
  • 网站设计深圳网站建设公司seo网站关键词