MyBatis中将结果集封装到指定类型详解(反射Class.forName详解)

2024-01-11 05:08

本文主要是介绍MyBatis中将结果集封装到指定类型详解(反射Class.forName详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1.将结果集封装到指定类型中
      • 1.1指定类型:
      • 1.2将信息存入到mapper中
      • 1.3反射
        • 1.3.1获取全限定类名,加载类并且实例化
        • 1.3.2执行SQL语句,生成的结果集获取元信息,把每列的数据存入到指定类型中
  • 1.4Class.forName方法扩展
    • 理解 Class.forName()
    • Class.forName() 与 xxx.class的区别
        • 小结:
          • 初始化和实例化的区别:

1.将结果集封装到指定类型中

1.1指定类型:

1.2将信息存入到mapper中

mapper的构造:成员变量:``

private String queryString;//SQL    select * from user
private String resultType;//实体类的全限定类名 com.domain.User

1.3反射

1.3.1获取全限定类名,加载类并且实例化

object obj = Class.forName(mapper.getResultType())newInstance();//加载参数指定的类到内存

1.3.2执行SQL语句,生成的结果集获取元信息,把每列的数据存入到指定类型中

1.4Class.forName方法扩展

理解 Class.forName()

Class 类概念

Class 也是一个 Java 类,保存的是与之对应 Java 类的 meta信息(元信息),用来描述这个类的结构,比如描述一个类有哪些成员,有哪些方法等,一般在反射中使用。

**详细解释:**Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例(Class 对象)。也就是说,在 Java 中,每个 java 类都有一个相应的 Class 对象,用于表示这个 java 类的类型信息。

类加载概念

当使用一个类的时候(比如 new 一个类的实例),会检查此类是否被加载到内存,如果没有,则会执行加载操作。

读取类对应的 class 文件数据,解析此数据,构造一个此类对应的 Class 类的实例。此时JVM就可以使用该类了,比如实例化此类,或者调用此类的静态方法。

Java 也提供了手动加载类的接口,class.forName()方法就是其中之一。(说来说去,其实就是生成这个类的 Class)

类加载器的概念

顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance() 方法就可以创建出该类的一个对象。 基本上所有的类加载器都是 java.lang.ClassLoader 类的一个实例。

类初始化概念

类被加载之后,jvm 已经获得了一个描述类结构的 Class 实例。但是还需要进行类初始化操作之后才能正常使用此类,类初始化操作就是执行一遍类的静态语句,包括静态变量的声明还有静态代码块

Class.forName() 方法

此方法含义是:加载参数指定的类,并且初始化它

在 jdbc 连接数据库中的应用

到这里,不用解释,读者也会明白,在使用 jdbc 方式连接数据库时,为什么要执行 Class.forName(‘驱动类名’) 方法了:将驱动类的 class 文件装载到内存中,并且形成一个描述此驱动类结构的 Class 类实例,并且初始化此驱动类,这样 jvm 就可以使用它了,这就是 Class.forName() 方法的含义。

有数据库开发经验朋友会发现,为什么在我们加载数据库驱动包的时候有的却没有调用 newInstance() 方法呢?即有的 jdbc 连接数据库的写法里是 Class.forName(xxx.xx.xx);而有一 些:Class.forName(xxx.xx.xx).newInstance(),为什么会有这两种写法呢?

刚才提到,Class.forName(" "); 的作用是要求 JVM 查找并加载指定的类,如果在类中有静态初始化器的话,JVM 必然会执行该类的静态代码 段。而在 JDBC 规范中明确要求这个 Driver 类必须向 DriverManager 注册自己,即任何一个 JDBC Driver 的 Driver 类的代码都必须类似如下:

public class MyJDBCDriver implements Driver { static { DriverManager.registerDriver(new MyJDBCDriver()); } 
} 

既然在静态初始化器的中已经进行了注册,所以我们在使用 JDBC 时只需要 Class.forName(XXX.XXX); 就可以了。

Class.forName() 与 xxx.class的区别

所有的类都是在对其第一次使用时,动态加载到 JVM。当程序创建第一个对类的静态成员的引用时,就会加载这个类。这也证明了构造器也是类的静态方法,即使在构造器之前并没有 static 关键字。因此,使用 new 操作符创建类的对象也会被当作对类的静态成员的引用。

因此 Java 程序在他开始运行之前并非被完全加载,其各个部分是在需要时才加载的。

类加载器首先槛车这个类的 Class 对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名称查找 .class 文件。在这个类的字节码被加载时,它们会接收验证,以确保其没有被破坏。

Class 对象尽在需要的时候才被加载。static 初始化是在类加载时进行的

对于 Class.forName(),这个方法是 Class 类的一个 static 成员。Class 对象就和其他对象一样,我们可以获取并操作他的引用。forName() 是取得 Class 对象引用的一种方法。他是用一个包含目标类的文本名的 String 作为输入参数,返回一个 Class 对象的引用。forName() 方法发现某个累还没被加载,就会主动去加载这个类,在加载过程中,该类的是 static 子句将会被执行。

Java 还提供了另一种方法来生成对 Class 对象的引用,即使用类字面常量。形如:xxx.class 的形式。但是这种形式创建 Class 对象引用时,不会自动初始化 Class 对象。初始化被延迟到了对静态方法或者非常数静态域首次引用时才执行。

从对 initable 引用的创建中可以看到,仅使用 .class 语法来获取对类的引用不会发生初始化。但是 Class.forName() 立即就进行了初始化。如果一个 static final 值是“编译期常量”,就像 Initable.staticFinal 那样,那么这个值不需要对 Initable 类进行初始化就可以被读取。但是如果只是将一个域设置为 static 和 final 的,还不足以确保这种行为,例如 Initable.staticFianl2 的访问将强制进行类型的初始化,因为他不是一个编译器常量。

小结:

Class.forName(“ ”) 加载参数到内存,返回一个class(类)对象,并且初始化该类

初始化和实例化的区别:

初始化时机:进入main方法前先会加载jdk基础类和main方法所在的类

​ 其他的类只有被使用到的时候才会被加载

实例化的方式:由执行类实例创建表达式而引起的对象创建(new)。除此之外,我们还可以使用反射机制(Class类的newInstance方法、使用Constructor类的newInstance方法)、使用Clone方法、使用反序列化等方式创建对象

初始化:类加载进来的时候就会对其初始化,静态变量(类加载器),静态代码块,构造器都会加入进内存

e方法、使用Constructor类的newInstance方法)、使用Clone方法、使用反序列化等方式创建对象

初始化:类加载进来的时候就会对其初始化,静态变量(类加载器),静态代码块,构造器都会加入进内存

实例化;一般是先对其初始化再实例化,将类的所有信息加载进内存

这篇关于MyBatis中将结果集封装到指定类型详解(反射Class.forName详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/593261

相关文章

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹