java反射与注解结合使用(根据传入对象输出查询sql)

  我们在项目开发中有很多地方使用到了注解,关于注解的定义与创建小伙伴可以参考我的文章《java注解》。有任何问题的小伙伴们可以在评论区指出哦,欢迎各位大佬指出问题。

  今天我要说的是使用注解与反射结合使用,来使我们代码根据优雅,更加高大上(咳,装逼神器啊)。

  注解使用@interface 来定义,辣么我们自定义的注解,该使用获取到并且指明该注解的作用呢?java提供了反射机制,通过类的类类型我们可以根据自己需要老操作该类。有管反射的知识,可以参考我的上两章博客。好了,废话不多说,我们上代码:

 需求:创建一个与数据库表对应的实体类,通过使用注解的方式,来生成该实体类的查询sql语句。

  1.创建Table类注解,用于标明该类对应数据库的表名称

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}

  2.创建Column字段注解,用于标明该类中属性与数据库表字段的映射

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
}

  3.创建实体类,并使用注解Table、Column

/**
 * 数据库 user表,对应表字段为 userid/username/age/addredd
 */
@Table("user")
public class User {
    @Column("userid")
    private String userid;
    @Column("username")
    private String username;
    @Column("age")
    private int age;
    @Column("sl")
    private double sl;
    @Column("address")
    private String address;
    // 添加一个不是数据库的字段: 用于测试
    private String noField;

    public double getSl() {
        return sl;
    }

    public void setSl(double sl) {
        this.sl = sl;
    }

    public String getNoField() {
        return noField;
    }

    public void setNoField(String noField) {
        this.noField = noField;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

  4.创建工具类,根据传入该对象,来生成对应的查询sql

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 注解
 */
public class AnnotationUtil {
    /**
     * 根据传入的对象 来生成query sql
     *
     * @param object
     * @return
     */
    public static String getSqlByAnnotation(Object object) throws Exception {
        // 使用StringBuilder 线程安全
        StringBuilder sb = new StringBuilder();
        // 检查参数是否为空
        Objects.requireNonNull(object, "该对象不能为空!");
        // 1.通过反射获取该对象的类类型
        Class c = object.getClass();
        // 2.获取该对象的 类注解: 标明表名
        boolean table_flag = c.isAnnotationPresent(Table.class);
        if (!table_flag) {
            throw new NullPointerException();
        }
        Table table = (Table) c.getDeclaredAnnotation(Table.class);
        sb.append("SELECT * FROM ").append(table.value()).append(" WHERE 1 = 1");
        // 3.获取该对象的 字段注解:显示查询字段
        Field[] fields = c.getDeclaredFields();
        boolean field_flag;
        Column column;
        String field_name;
        Method menthod;
        Object val;
        for (Field field : fields) {
            // 首先得拿到字段名称:通过字段上的注解标明该指定是数据库表对应的字段
            field_flag = field.isAnnotationPresent(Column.class);
            if (!field_flag) {
                continue;
            }
            column = field.getDeclaredAnnotation(Column.class);
            // 其次得拿到字段值 : 通过反射调用类的getXxxx方法
            field_name = field.getName();
            menthod = c.getDeclaredMethod("get" + Character.toUpperCase(field_name.charAt(0)) + field_name.substring(1));
            val = menthod.invoke(object);
            // 判断该字段是否为空,不为空,才进行append
            // 这里要注意:有些属性不赋值时候,java会自动生成默认值,如Double默认为0.0
            // 还有其他类型,小伙伴们可以自行测试
            if (!Objects.isNull(val)) {
                if((val instanceof Double) && (double) val == 0.0){
                    continue;
                }
                sb.append(" AND ").append(column.value()).append(" = ");
                sb.append(val);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        User user = new User();
        user.setUserid("0001");
        user.setAge(23);
        // 用于测试没有带Column注解的字段
        user.setNoField("field");
        try {
            System.out.println(AnnotationUtil.getSqlByAnnotation(user));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

原文地址:https://www.cnblogs.com/www-123456/p/10887576.html

时间: 2024-10-12 03:42:19

java反射与注解结合使用(根据传入对象输出查询sql)的相关文章

JAVA反射与注解实例

1    JAVA反射机制 JAVA反射机制是在运行状况中,号码大全关于恣意一个类,关键词挖掘工具都能够晓得这个类的一切特点和办法:关于恣意一个目标,都能够调用它的恣意一个办法和特点:这种动态获取的信息以及动态调用目标的办法的功能称为java言语的反射机制.或许说,JAVA反射机制指的是咱们能够于运行时加载.探知.运用编译时间完全不知道的classes.换句话说,Java程序能够加载一个运行时才得知称号的class,得悉其完好结构(但不包括methods界说),并生成其目标实体.或对其field

java反射获取注解并拼接sql语句

先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE}) @Retention(Ret

java反射和注解

目录 反射 注解 元属性 自定义注解 使用案例 反射 Class<?> aClass = Class.forName("reflect.Student"); Constructor<?> constructor = aClass.getConstructor();//构造函数,用于创建对象 Object obj = constructor.newInstance(); //创建对象,用于执行函数 Method[] methods = aClass.getMeth

通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMongoSession import java.util.List; import org.bson.Document; import org.bson.conversions.Bson; import com.mongodb.client.MongoCollection; import com.mo

java反射1--产生Class类的实例化对象三个方法

首先每一个类在实例化的时候都会产生一个.class文件.而Class对象既是将.class文件读入内存时,为它创建一个Class对象. 反射就是对Class对象进行操作. 1 package reflect.vo; 2 3 /** 4 * @author guohao 5 * java测试类Student 6 */ 7 public class Student { 8 private String name; 9 private int age; 10 private float score;

Java反射(一) : 获取Class对象

所有反射操作的入口都是java.lang.Class.除了java.lang.reflect.ReflectPermission之外,没有哪个在java.lang.reflect包下面的类有共有构造器.为了获得这些类,有必要去调用Class的适当方法.对象,类名,类型或者已存在的Class,这些是得到Class的几种方法. Object.getClass() 如果可获得一个对象的实例,最简单的获取Class的方法是调用Object.getClass().当然,这必须是继承自Object的引用类型

一个简单java程序模拟与Mysql Server建立连接及发送查询SQL

使用普通socket来模拟与Mysql Server建立连接及发送查询SQL,如下代码所示: Socket socket = new  Socket("127.0.0.1",3306); OutputStream out = socket.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(out); //建立连接报文信息 来自wireshark(捕捉终端执行mysql -u root -p -h

[记录] java反射+注解

框架开发之Java注解的妙用 JAVA反射与注解 Java基础 :反射.注解.代理.线程池.依赖的学习和理解 Java反射与注解 原文地址:https://www.cnblogs.com/zad27/p/12121589.html

获取Java类中注解的详细信息

前言:这篇博客主要是为了后续的获取SpringMVC中的全部请求URL做的准备. public class AnnotationHelper { private static final AnnotationHelper helper = new AnnotationHelper(); protected AnnotationHelper() { } public static AnnotationHelper getInstance() { return helper; } /** * 得到类