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

截图

数据库设计

执行结果

相关推荐
Estar.Lee5 分钟前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610032 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_2 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞2 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货2 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng3 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee3 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书4 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放4 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang4 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net