Jdbc笔记02

Jdbc笔记02

  • 1、class类
    • 1.1、反射是什么
    • 1.2、如何获得一个类对应的Class对象
    • 1.3、Class类常用方法
      • [1. `getName()`](#1. getName())
      • [2. `getSimpleName()`](#2. getSimpleName())
      • [3. `getPackage()`](#3. getPackage())
      • [4. `getSuperclass()`](#4. getSuperclass())
      • [5. `getInterfaces()`](#5. getInterfaces())
      • [6. `getFields()`](#6. getFields())
      • [7. `getDeclaredFields()`](#7. getDeclaredFields())
      • [8. `getMethods()`](#8. getMethods())
      • [9. `getDeclaredMethods()`](#9. getDeclaredMethods())
      • [10. `getConstructors()`](#10. getConstructors())
      • [11. `getDeclaredConstructors()`](#11. getDeclaredConstructors())
      • [12. `newInstance()`](#12. newInstance())
      • [13. `isInterface()`](#13. isInterface())
      • [14. `isArray()`](#14. isArray())
      • [15. `isPrimitive()`](#15. isPrimitive())
      • [16. `getModifiers()`](#16. getModifiers())
      • [17. `getClassLoader()`](#17. getClassLoader())
      • [18. `getResourceAsStream(String name)`](#18. getResourceAsStream(String name))
      • [19. `getAnnotation(Class<T> annotationClass)`](#19. getAnnotation(Class<T> annotationClass))
      • [20. `getDeclaredAnnotations()`](#20. getDeclaredAnnotations())
    • 1.4、实际用处
  • 2、反射与数据库

1、class类

1.1、反射是什么

java程序先经过编译器编译,生成class文件,而class文件的执行场所是在jvm中。

如何要定义一个类来描述所有类的共同特征,应该如何来设计?

java 复制代码
public class Class{
    private String name;//类名
    
    private Package pkl//包名
        
    private Constructor[] constructors;//构造方法,可能有多个
    
    private Field[] fields;//字段
    
    private Method[] methods;//方法
    
    private Class<?> interfaces;//实现的接口
    
    private Class<?> superClass;//继承的父类
    
    //Getter & Setter
}

JVM记载类的过程相当于对文件内容进行解析,解析内容就需要找到共有特征,然后再将这特征存储起来,在使用的时候再取出来,通过Class对象反向推到我们编写的类的内容,然后再进行操作,这个过程称为反射

1.2、如何获得一个类对应的Class对象

java 复制代码
Class<类名> clazz = 类名.class;
Class<? extends 类名> clazz = 对象名.getClass();
Class<? super 类名> clazz = clazz.getSuperClass();
Class clazz = Class.forName("类的全限定名");
Class clazz = 包装类.TYPE;

1.3、Class类常用方法

Class 类是 Java 反射机制的核心,它提供了获取类信息的方法。以下是一些常用的 Class 类方法:

1. getName()

返回类的全限定名(包括包名)。

java 复制代码
String className = clazz.getName();

2. getSimpleName()

返回类的简单名称(不包括包名)。

java 复制代码
String simpleName = clazz.getSimpleName();

3. getPackage()

返回类的包信息。

java 复制代码
Package pkg = clazz.getPackage();

4. getSuperclass()

返回类的直接父类。

java 复制代码
Class<?> superClass = clazz.getSuperclass();

5. getInterfaces()

返回类实现的接口数组。

java 复制代码
Class<?>[] interfaces = clazz.getInterfaces();

6. getFields()

返回类的所有 public 字段,包括继承的字段。

java 复制代码
Field[] fields = clazz.getFields();

7. getDeclaredFields()

返回类的所有字段,包括 privateprotected,但不包括继承的字段。

java 复制代码
Field[] declaredFields = clazz.getDeclaredFields();

8. getMethods()

返回类的所有 public 方法,包括继承的方法。

java 复制代码
Method[] methods = clazz.getMethods();

9. getDeclaredMethods()

返回类的所有方法,包括 privateprotected,但不包括继承的方法。

java 复制代码
Method[] declaredMethods = clazz.getDeclaredMethods();

10. getConstructors()

返回类的所有 public 构造方法。

java 复制代码
Constructor<?>[] constructors = clazz.getConstructors();

11. getDeclaredConstructors()

返回类的所有构造方法,包括 privateprotected

java 复制代码
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();

12. newInstance()

创建类的新实例(需要类具有无参构造方法)。

java 复制代码
Object instance = clazz.newInstance();

13. isInterface()

判断类是否是接口。

java 复制代码
boolean isInterface = clazz.isInterface();

14. isArray()

判断类是否是数组。

java 复制代码
boolean isArray = clazz.isArray();

15. isPrimitive()

判断类是否是基本数据类型。

java 复制代码
boolean isPrimitive = clazz.isPrimitive();

16. getModifiers()

返回类的修饰符(如 public, static 等),可以用 Modifier 类的静态方法来解析。

java 复制代码
int modifiers = clazz.getModifiers();
boolean isPublic = Modifier.isPublic(modifiers);

17. getClassLoader()

返回类的类加载器。

java 复制代码
ClassLoader classLoader = clazz.getClassLoader();

18. getResourceAsStream(String name)

获取资源文件的输入流。

java 复制代码
InputStream inputStream = clazz.getResourceAsStream("config.properties");

19. getAnnotation(Class<T> annotationClass)

获取类的指定注解。

java 复制代码
Annotation annotation = clazz.getAnnotation(MyAnnotation.class);

20. getDeclaredAnnotations()

获取类上的所有注解。

java 复制代码
Annotation[] annotations = clazz.getDeclaredAnnotations();

1.4、实际用处

假设你有一个类MyClass,定义如下

java 复制代码
public class MyClass {
    private MyClass() {
        // 私有无参构造器
    }

    private String name;

    private String getName() {
        return name;
    }

    private void setName(String name) {
        this.name = name;
    }
}

你可以使用反射机制来,创建对象,给对象中的私有属性赋值,调用其中的私有方法

java 复制代码
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // 获取 MyClass 类的 Class 对象
            Class<?> clazz = Class.forName("MyClass");

            // 获取私有的无参构造器
            Constructor<?> constructor = clazz.getDeclaredConstructor();
            // 设置构造器为可访问
            constructor.setAccessible(true);
            // 使用构造器创建对象
            Object obj = constructor.newInstance();

            // 获取私有的 name 字段
            Field nameField = clazz.getDeclaredField("name");
            // 设置字段为可访问
            nameField.setAccessible(true);
            // 设置字段值
            nameField.set(obj, "Reflection Value");

            // 获取私有的 getName 方法
            String methodName = "get" + nameField.substring(0,1).toUpperCase() + nameField.substring(1);
            Method getNameMethod = clazz.getDeclaredMethod(methodName);
            // 设置方法为可访问
            getNameMethod.setAccessible(true);
            // 调用 getName 方法并获取返回值
            String name = (String) getNameMethod.invoke(obj);
            System.out.println("Name: " + name);

            // 获取私有的 setName 方法
            methodName = "set" + nameField.substring(0,1).toUpperCase() + nameField.substring(1);
            Method setNameMethod = clazz.getDeclaredMethod(methodName, nameField.getType());
            // 设置方法为可访问
            setNameMethod.setAccessible(true);
            // 调用 setName 方法
            setNameMethod.invoke(obj, "New Value");

            // 再次调用 getName 方法
            name = (String) getNameMethod.invoke(obj);
            System.out.println("New Name: " + name);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2、反射与数据库

数据库查询出的每一条数据基本上都会封装为一个对象,数据库中的每一个字段值都会存储在对象相应的属性中。如果查询结果的每一个字段都与

例如,通过参数给定Class,就可以通过反射进行封装对象并返回,就不用每一个对象都要写一个查询函数了,只需要一个查询函数给定参数(String sql,Class clazz,Object... params)。


如果字段与属性名不同,例如:字段为good_id,而属性是goodId怎么办呢?

在select的时候 给good_id起一个别名叫 goodId即可解决。


在某些场景下,JDBC和反射可以结合使用,以实现更灵活的功能。例如:

  • 动态ORM(对象关系映射) :通过反射,可以将数据库查询结果(ResultSet)动态映射到Java对象中,而不需要手动编写大量的赋值代码。
  • 动态生成SQL语句 :通过反射获取类的字段信息,动态生成INSERTUPDATE等SQL语句。
示例:动态ORM
java 复制代码
public <T> T mapResultSetToObject(ResultSet rs, Class<T> clazz) throws Exception {
    T obj = clazz.getDeclaredConstructor().newInstance();
    ResultSetMetaData metaData = rs.getMetaData();
    int columnCount = metaData.getColumnCount();

    for (int i = 1; i <= columnCount; i++) {
        String columnName = metaData.getColumnName(i);
        Field field = clazz.getDeclaredField(columnName);
        field.setAccessible(true);
        field.set(obj, rs.getObject(i));
    }
    return obj;
}
相关推荐
想要打 Acm 的小周同学呀25 分钟前
SpringBoot框架开发中常用的注解
java·spring boot·后端·项目开发
TPBoreas31 分钟前
Spring Boot 内置工具类
java·spring boot·后端
浪里渔夫37 分钟前
Lombok @Data无法 import 导入的问题解决办法
java·lombok
w3625012661 小时前
Java NIO
java·开发语言·nio
Java 第一深情1 小时前
面试题解,JVM中的“类加载”剖析
java·jvm
1101 11012 小时前
STM32-笔记28-蓝牙模块
笔记
m0_748244962 小时前
Tomcat 的安装(详细教程)
java·tomcat
一弓虽3 小时前
java 基础学习——java 异常详细介绍
java·学习·throw
CharlesC++3 小时前
JAVA类和对象练习
java·开发语言
π大星星️3 小时前
haproxy+nginx负载均衡实验
linux·运维·服务器·笔记·nginx·负载均衡