DIY自定义ORM框架

ORM框架简介

ORM(Object-Relational Mapping)是一种可以将对象模型(比如实体类)映射到关系模型(比如数据库表)的技术

注:本文只实现了save方法

常见的ORM框架

Hibernate、MyBatis、Spring Data JPA、Mybatis-Plus

框架设计原理

  1. 连接和关闭数据库;
  2. 对象与数据库表的映射;
  3. 数据库的查询和更新;
  4. 数据库结果集与对象之间的映射

实现

添加依赖

xml 复制代码
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
    </dependency>
</dependencies>

定义注解

@Table

java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
    //关联表名
    String name();
}

@Column

java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    // 关联列名
    String name();
}

实体类

java 复制代码
@Table(name = "user")//关联自定义注解@Table,将类名与表名建立映射
public class User {
    //关联自定义注解@Column,将属性名与列名建立映射
    @Column(name = "id")
    private int id;

    @Column(name = "username")
    private String username;

    @Column(name = "age")
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", age=" + age + "]";
    }   
}

定义ORM框架(核心!!!)

  1. 首先连接数据库
  2. 采用反射获取到注解的内容,也就是通过注解获取到表名和列名
  3. 通过StringBuilder进行sql语句的拼接
  4. 最后执行我们拼接好的sql语句就行
  5. 执行完关闭数据库连接
java 复制代码
package org.example;

import java.sql.Connection;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class ORM {
    private Connection conn;

    //构造方法中设置数据库的url、用户名和密码
    public ORM(String url, String user, String password) {
        try {
            //加载Driver驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取数据库Connection连接对象
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 定义一个数据库添加数据的方法
     * @param obj,实体类对象
     */
    public void save(Object obj) {
        Class clazz = obj.getClass();
        //得到某个实体对象上绑定的Table注解
        Table table = (Table) clazz.getAnnotation(Table.class);
        //得到实体类绑定的表名
        String tableName = table.name();

        //拼接insert into插值语句
        StringBuilder sb = new StringBuilder("INSERT INTO ");
        sb.append(tableName).append(" (");

        //获取实体类中每个属性上关联的列名
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            Column column = field.getAnnotation(Column.class);
            if (column != null) {
                //将列名拼接到insert语句中
                sb.append(column.name()).append(",");
            }
        }
        //去掉insert语句中多余的","
        sb.deleteCharAt(sb.length() - 1).append(") VALUES (");

        //在insert语句中,拼接values语句后面的值
        for (Field field : fields) {
            Column column = field.getAnnotation(Column.class);
            if (column != null) {
                //对私有属性设置可访问性
                field.setAccessible(true);
                try {
                    sb.append("'").append(field.get(obj)).append("',");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //去除insert语句中最后多余的","
        sb.deleteCharAt(sb.length() - 1).append(")");

        try {
            //执行SQL语句
            Statement stmt = conn.createStatement();
            stmt.executeUpdate(sb.toString());
            System.out.println("数据插入成功");
            stmt.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭数据库连接
     */
    public void close() {
        try {
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用我们自定义的ORM框架

java 复制代码
public class Main {
    public static void main(String[] args) {
        ORM orm = new ORM("jdbc:mysql://localhost:3306/activti?useSSL=false", "root", "123456");
        //创建一个用户对象
        User user = new User();
        user.setUsername("aaaaaaa");
        user.setAge(18);
        //调用ORM框架的插入操作
        orm.save(user);
        //关闭数据库连接
        orm.close();
    }
}

截图

数据库设计

执行结果

相关推荐
狗头大军之江苏分军20 小时前
请不要在感情里丢掉你的“我”
前端·后端
BingoGo20 小时前
2025 年必须尝试的 5 个 Laravel 新特性
后端
豆浆Whisky20 小时前
掌握Go context:超越基础用法的正确实践模式|Go语言进阶(13)
后端·go
用户685453759776920 小时前
📁 设计一个文件上传和存储服务:云盘的秘密!
后端
Merrick20 小时前
亲手操作Java抽象语法树
java·后端
今天没ID20 小时前
高阶函数
后端
_光光20 小时前
大文件上传服务实现(后端篇)
后端·node.js·express
初级程序员Kyle20 小时前
开始改变第三天 Java并发(1)
java·后端
无名之辈J20 小时前
GC Overhead 排查
后端