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

截图

数据库设计

执行结果

相关推荐
Victor35639 分钟前
MySQL(138)如何设置数据归档策略?
后端
Victor35640 分钟前
MySQL(137)如何进行数据库审计?
后端
FreeBuf_8 小时前
黄金旋律IAB组织利用暴露的ASP.NET机器密钥实施未授权访问
网络·后端·asp.net
张小洛9 小时前
Spring AOP 是如何生效的(入口源码级解析)?
java·后端·spring
why技术10 小时前
也是出息了,业务代码里面也用上算法了。
java·后端·算法
白仑色12 小时前
完整 Spring Boot + Vue 登录系统
vue.js·spring boot·后端
ZhangApple14 小时前
微信自动化工具:让自己的微信变成智能机器人!
前端·后端
Codebee14 小时前
OneCode 3.0: 注解驱动的Spring生态增强方案
后端·设计模式·架构
bobz96514 小时前
kubevirt virtinformers
后端
LuckyLay14 小时前
Django专家成长路线知识点——AI教你学Django
后端·python·django