手撕ORM框架

ORM:(Object relative Mapping)对象关系映射框架。帮你自动把数据库中的记录和java实体类对应映射在一起。

框架对应的包

 

annotation包:

        TableName:

package com.lqh.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    String value();
}

        TableField:

package com.lqh.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableField {
    String value();
}

dao包:

        StudentDao:

package com.lqh.dao;

import com.lqh.entity.Student;
import com.lqh.utils.BaseDao;

/**
 * @Author Li Qinghua
 * @Create 2022/7/14 20:30
 */
public class StudentDao extends BaseDao<Student> {
}

entity包:

        Student:

package com.lqh.entity;

import com.lqh.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author Li Qinghua
 * @Create 2022/7/14 20:17
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "tb_student")
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String address;
}

utils包:

        BaseDao:

package com.lqh.utils;

import com.lqh.annotation.TableField;
import com.lqh.annotation.TableId;
import com.lqh.annotation.TableName;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author Li Qinghua
 * @Create 2022/7/14 20:14
 */
public class BaseDao<E> {

    private Connection connection;
    private ResultSet res;
    private PreparedStatement ps;

    private Class<?> clazz;

    public BaseDao(){

        //this对应的是子类对象,获取当前类的反射类对象
        Class<? extends BaseDao> aClass = this.getClass();

        //获取当前反射类的父类反射类--包含父类的泛型
        ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();

        //获取泛型的反射类
        Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();

        //System.out.println("~~~~~~~~~~");
        //System.out.println(Arrays.toString(actualTypeArguments));
        clazz= (Class<?>) actualTypeArguments[0];
        //System.out.println(clazz.getSimpleName());

    }



    public int insert(E e){
        try {
            StringBuffer sql = new StringBuffer("insert into ");

            //获取表名
            Class<?> aClass = e.getClass();

            TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
            String tableName = "";

            //是否存在该注解
            if (tableNameAnnotation != null) {
                tableName = tableNameAnnotation.value();
            } else {
                tableName = aClass.getSimpleName();
            }
            sql.append(tableName);

            //获取反射类对象中所有的属性对象
            Field[] declaredFields = aClass.getDeclaredFields();

            //创建两个集合、分别存放列和列的值
            List<String> columns = new ArrayList<>();
            List<String> values = new ArrayList<>();

            for (Field field : declaredFields) {
                field.setAccessible(true);
                TableField tableField = field.getAnnotation(TableField.class);
                if (tableField != null) {
                    columns.add(tableField.value());
                } else {
                    columns.add(field.getName());
                }

                values.add("'" + field.get(e) + "'");
            }

            sql.append(columns.toString().replace("[", "(").replace("]", ")"));
            sql.append(" values ");
            sql.append(values.toString().replace("[", "(").replace("]", ")"));


            System.out.println(sql);
            connection=DBUtil.getConn();
            ps=connection.prepareStatement(sql.toString());
            int i = ps.executeUpdate();
            return 1;
        }catch (Exception o){
            o.printStackTrace();
        }finally {
            DBUtil.closeAll(res,ps,connection);
        }
        return 0;
    }

    public int delete(Object id){
        StringBuffer sql=new StringBuffer("delete from ");
        try {
            TableName tableName = clazz.getAnnotation(TableName.class);
            if (tableName != null) {
                sql.append(tableName.value() + " where ");
            } else {
                sql.append(clazz.getSimpleName() + " where ");
            }
            Field[] declaredFields = clazz.getDeclaredFields();
            boolean flag = false;
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TableId tableId = field.getAnnotation(TableId.class);
                if (tableId != null) {
                    flag = true;
                    sql.append(tableId.value() + "='" + id + "'");
                    break;
                }
            }

            if (flag == false) {
                throw new RuntimeException("没有添加主键注解!");
            }


            //System.out.println(sql);
            connection = DBUtil.getConn();
            ps = connection.prepareStatement(sql.toString());
            int i = ps.executeUpdate();
            return i;
        }catch (Exception o){
            o.printStackTrace();
        }finally {
            DBUtil.closeAll(res,ps,connection);
        }
        return 1;
    }

    public int update(E e){
        try{
            StringBuffer sql=new StringBuffer("update ");

            Class<?> eClass = e.getClass();

            TableName tableName = eClass.getAnnotation(TableName.class);
            if(tableName!=null){
                sql.append(tableName.value()+" set ");
            }else{
                sql.append(eClass.getSimpleName()+" set ");
            }


            String where=" where ";

            boolean flag=false;
            Field[] eClassFields = eClass.getDeclaredFields();
            for (Field field : eClassFields) {
                field.setAccessible(true);
                TableId tableId = field.getAnnotation(TableId.class);
                if(tableId!=null){
                    flag=true;
                    where+=tableId.value()+"='"+field.get(e)+"'";
                }else{
                    TableField tableField = field.getAnnotation(TableField.class);
                    if(tableField!=null){
                        sql.append(tableField.value()+"='"+field.get(e)+"',");
                    }else {
                        sql.append(field.getName() + "='" + field.get(e) + "',");
                    }
                }
            }

            if(flag==false){
                throw new RuntimeException("No primary key annotation added!");
            }

            String SQL=sql.substring(0,sql.lastIndexOf(","))+where;

            connection=DBUtil.getConn();
            ps=connection.prepareStatement(SQL);
            int i = ps.executeUpdate();
            return 1;
        }catch (Exception o){
            o.printStackTrace();
        }finally {
            DBUtil.closeAll(res,ps,connection);
        }
        return 0;
    }

    public List<E> findAll(){

        List<E> list=new ArrayList<>();

        StringBuffer sql=new StringBuffer("select * from ");
        try {
            TableName tableName = clazz.getAnnotation(TableName.class);
            if (tableName != null) {
                sql.append(tableName.value());
            } else {
                sql.append(clazz.getSimpleName());
            }

            //System.out.println(sql);

            connection = DBUtil.getConn();
            ps = connection.prepareStatement(sql.toString());
            res = ps.executeQuery();

            while (res.next()){
                Object obj = clazz.newInstance();

                Field[] declaredFields = clazz.getDeclaredFields();
                for (Field field : declaredFields) {
                    field.setAccessible(true);
                    TableName annotation = field.getAnnotation(TableName.class);
                    if(annotation!=null){
                        field.set(obj,res.getObject(annotation.value()));
                    }else{
                        field.set(obj,res.getObject(field.getName()));
                    }
                }
                list.add((E) obj);
            }

        }catch (Exception o){
            o.printStackTrace();
        }finally {
            DBUtil.closeAll(res,ps,connection);
        }
        return list;
    }
}

        DBUtil:

package com.lqh.utils;

import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;

/**
 * @Author Li Qinghua
 * @Create 2022/7/14 20:03
 */
public class DBUtil {
    private static String driverName;
    private static String url;
    private static String username;
    private static String password;

    static {
        try {
            Properties properties = new Properties();

            //加载属性配置文件
            properties.load(new FileInputStream("E:\\IDEA练习\\高级\\手撕ORM框架\\src\\main\\resources\\db.properties"));

            //读取属性配置文件的内容
            driverName = properties.getProperty("jdbc.driverName");
            url = properties.getProperty("jdbc.url");
            username = properties.getProperty("jdbc.username");
            password = properties.getProperty("jdbc.password");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static Connection getConn() throws Exception{
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url,username,password);
        return connection;
    }

    public static void closeAll(ResultSet res, PreparedStatement ps,Connection connection){
        try {
            if(res!=null){
                res.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        try {
            if(ps!=null){
                ps.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        try {
            if(connection!=null){
                connection.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

测试:

        Test:

package com.lqh;

import com.lqh.dao.StudentDao;
import com.lqh.entity.Student;

import java.util.List;

/**
 * @Author Li Qinghua
 * @Create 2022/7/14 20:31
 */
public class Test {

    StudentDao sd=new StudentDao();

    @org.junit.Test
    public  void testInsert() {
        int insert = sd.insert(new Student(5,"王五4",25,"周口"));
    }

    @org.junit.Test
    public void testUpdate(){
        int update = sd.update(new Student(1,"ll",9,"zz"));
    }

    @org.junit.Test
    public void testUpdate02(){
        int id = sd.update02(new Student(1,"pp",19,"zpz"));
    }

    @org.junit.Test
    public void testDelete(){
        int delete = sd.delete(5);
    }

    @org.junit.Test
    public void testFindAll(){
        List<Student> list = sd.findAll();
        System.out.println(list);
    }
}

db.properties

jdbc.driverName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db2?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=pAssW0rd

核心代码在BaseDao中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值