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

截图

数据库设计

执行结果

相关推荐
API_Zevin16 分钟前
如何优化亚马逊广告以提高ROI?
大数据·开发语言·前端·后端·爬虫·python·学习
北极熊的咆哮21 分钟前
Go语言的 的编程环境(programming environment)基础知识
开发语言·后端·golang
白露与泡影1 小时前
Spring Boot中的 6 种API请求参数读取方式
java·spring boot·后端
_Soy_Milk1 小时前
Golang,Let‘s GO!
开发语言·后端·golang
1-programmer1 小时前
【Go研究】Go语言脚本化的可行性——yaegi项目体验
开发语言·后端·golang
努力的小雨2 小时前
KES(KingBaseES)集群部署实战
数据库·后端
我命由我123452 小时前
27.Java 线程间通信(synchronized 实现线程间通信、Lock 实现线程间通信)
java·开发语言·后端·java-ee·intellij-idea·juc·后端开发
星辰大海的精灵2 小时前
SpringBoot 整合 Elastic-Job 实现任务分布式调度
java·spring boot·后端
Q_19284999062 小时前
基于Spring Boot微信小程序电影管理系统
spring boot·后端·微信小程序
念言-ny3 小时前
springboot远程链接Hadoop
hadoop·spring boot·后端