造轮子之极简版ORM框架

极简版ORM框架

1. 概述

  • 实现@Table@Column注解
  • 利用反射机制,解析对象,动态生成SQL语句

2. 注解实现

2.1 @Table注解

package com.zipeng.annotation;

import java.lang.annotation.*;

/**
 * 自定义 @Table 注解
 *
 * @author: zipeng Li
 * 2021/6/1  20:37
 */
@Inherited // 当该注解应用于一个类时,能自动被其子类继承
@Target({ElementType.TYPE}) // 指明该注解的应用范围,当前注解只能应用于类
@Retention(RetentionPolicy.RUNTIME) // 指明该注解可以生存的范围,当前为可以生存于运行时,通过反射可以获取
@Documented // 指明当前注解应该包含在注解项的文档中
public @interface Table {
    String value() default "";
}

2.2 @Column注解

package com.zipeng.annotation;

import java.lang.annotation.*;

/**
 * 自定义Column注解
 *
 * @author: zipeng Li
 * 2021/6/1  20:48
 */
@Inherited // 可被继承
@Target({ElementType.FIELD}) // 只能用于成员域【包括enum常量】
@Retention(RetentionPolicy.RUNTIME) // 可以保留在运行时
@Documented // 需要生成在说明文档中
public @interface Column {
    String value() default "";
}

3. 自定义解析器

import com.zipeng.annotation.Table;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 用来解析自定义注解
 *
 * @author: zipeng Li
 * 2021/6/1  20:55
 */
public class AnnotationParser {

    /**
     * 通过注解来组装查询条件,生成查询语句
     * @param obj
     * @return
     */
    public static String assembleSqlFromObj(Object obj){
        // 1. 获取对象的 @Table 注解
        Table tableAnnotation = obj.getClass().getAnnotation(Table.class);
        // 2. 使用 StringBuffer 来构造最终的 sql。 线程安全
        StringBuffer sbSql = new StringBuffer();
        // 3. 根据注解获取表名
        String tableName = tableAnnotation.value();
        // 4. 构造最基本的查询语句
        sbSql.append("select * from " + tableName + " where 1=1 ");
        // 5. 获取加了注解的字段
        Field[] fields = obj.getClass().getDeclaredFields();
        // 6. 遍历每一个字段
        for(Field f: fields){
            // 6.1 获取字段名
            String fieldName = f.getName();
            // 6.2 构造get方法名
            String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
            // 6.3 获取字段的 @Column 注解
            Column columnAnnotation = f.getAnnotation(Column.class);
            if(columnAnnotation != null){
                Object invoke = null;
                try {
                    // 6.4 获取字段的 get 方法
                    Method method = obj.getClass().getMethod(methodName);
                    // 6.5 执行 get 方法,获取对应属性
                    invoke = method.invoke(obj);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 6.7 构造sql语句
                sbSql.append("and " + columnAnnotation.value() + "='" + invoke.toString() + "' ");
            }
        }
        // 7. 返回构造结果
        return sbSql.toString();
    }
}

4. 测试

package com.zipeng;

import com.zipeng.annotation.parser.AnnotationParser;
import com.zipeng.entity.User;

/**
 * @author: zipeng Li
 * 2021/6/1  21:41
 */
public class Test {
    public static void main(String[] args) {
        User user = new User("123", "小蓝");
        String s = AnnotationParser.assembleSqlFromObj(user);
        System.out.println(s);

        User user01 = new User("12321", "欢欢");
        String str = AnnotationParser.assembleSqlFromObj(user01);
        System.out.println(str);
    }
}
select * from t_user where 1=1 and id='123' and name='小蓝' 
select * from t_user where 1=1 and id='12321' and name='欢欢' 

后序

  • 我是一名大三本科生,专业是软件工程【一本】。目前,正在准备找实习以及秋招,意向岗位是Java后端开发工程师。为此,在码云托管了一个项目,以整理我所有所学知识。涉及内容:计算机网络、操作系统、Java基础、主流Java后端框架、设计模式、Web前端框架等内容。欢迎大家访问我的开源项目编程之路
  • 码云地址:https://gitee.com/alizipeng/the-way-of-programming
  • 以上内容均记载在我的开源项目中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值