手撕ORM 框架(泛型+注解+反射)

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

annitation包 : 自定义注解  用于实体类上

TableName:表名和实体类名不一致时使用

TableField:列名和属性名不一致时使用

TablePrimaryKey: 主键上使用,用来区别于其他属性

package com.qy151.annotation;

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

/**
 * @unthor : YSH
 * @date : 20:39 2022/7/14
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface TabelName {
    String value();
}

util包: 公共类

DBUtils:获取连接对象和关闭连接资源

package com.qy151.util;

import java.sql.*;

/**
 * @unthor : YSH
 * @date : 20:06 2022/7/14
 */
/*获取连接对象和关闭连接资源*/
public class DBUtils {
    private static String driverName="com.mysql.cj.jdbc.Driver";
    private static String url="jdbc:mysql://localhost:3306/myda2?serverTimezone=Asia/Shanghai";
    private static String user="你的用户名";
    private static String password="";


    public static Connection getCon() throws Exception {
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url, user, 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();
        }
    }
}

BaseDao类:父类

如何获取类名中泛型T:

//this对应的是子类对象  获取当前类的反射类对象
Class<? extends BaseDao> aClass = this.getClass();
//获取当前反射类的父类反射类----包含了父类的泛型
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
//获取泛型的反射类
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
clazz = (Class<?>) actualTypeArguments[0];

BaseDao里面实现了简单的CRUD操作

package com.qy151.util;

import com.qy151.annotation.TabelFiled;
import com.qy151.annotation.TabelName;
import com.qy151.annotation.TableId;
import com.qy151.entity.Student;

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.List;

/**
 * @unthor : YSH
 * @date : 20:27 2022/7/14
 */
/*T:表示实体类对象*/
public class BaseDao<T> {
    private Class<?> clazz;

    public BaseDao(){
        //this对应的是子类对象 获取当前的反射类对象
        Class<? extends BaseDao> aClass = this.getClass();
        //获取当前反射类的父类反射类--包含父类的泛型
        ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();


        //获取泛型的反射类
        Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
        clazz= (Class<?>) actualTypeArguments[0];
        /*System.out.println(clazz);*/
    }

    /*查询单个和查询所有的公共方法*/
    public List<T> find(String sql) throws Exception{
        List<T> list = new ArrayList<T>();
        Connection connection = DBUtils.getCon();
        PreparedStatement ps = connection.prepareStatement(sql.toString());
        ResultSet rs = ps.executeQuery();

        while (rs.next()){
            Object o = clazz.newInstance();
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field declaredField:declaredFields
            ) {
                declaredField.setAccessible(true);
                TabelFiled tabelFiled = declaredField.getAnnotation(TabelFiled.class);
                if (tabelFiled==null){
                    TableId tableId = declaredField.getAnnotation(TableId.class);
                    if(tableId!=null){
                        declaredField.set(o,rs.getObject(tableId.value()));
                    }else {
                        declaredField.set(o,rs.getObject(declaredField.getName()));
                    }
                }else {
                    declaredField.set(o, rs.getObject(tabelFiled.value()));
                }
            }
            list.add((T) o);
        }
        return list;
    }


    /*根据id查询*/
    public Student findOneById(Object id) throws Exception {


            Student student = null;

            StringBuffer sql = new StringBuffer("select * from ");
            //获取表名
            TabelName tabelNameAnnotation = clazz.getAnnotation(TabelName.class);
            String tabelname = "";
            /*判断是否存在该注解*/
            if (tabelNameAnnotation != null) {
                tabelname = tabelNameAnnotation.value();
            } else {
                tabelname = clazz.getSimpleName();
            }

            //追加表名
            sql.append(tabelname+" where ");
            System.out.println(sql);
            //获取该反射类对象中所有的属性对象
            Field[] declaredFields = clazz.getDeclaredFields();
            boolean flag = false;
            for (Field declaredFiled:declaredFields
            ) {
                TableId tableId = declaredFiled.getAnnotation(TableId.class);
                if (tableId!=null){
                    sql.append(tableId.value()+"='"+id+"'");
                    flag=true;
                    break;
                }
            }
            if (flag==false){
                throw new RuntimeException("没有添加主键注解");
            }
            System.out.println(sql);

        List<T> list = find(sql.toString());
        if (list!=null&&list.size()==1){
            return (Student) list.get(0);
        }
        return null;
    }


    //查询所有
    public List<T> findAll() throws Exception{

            StringBuffer sql = new StringBuffer("select * from ");
            //获取表名
            TabelName tabelNameAnnotation = clazz.getAnnotation(TabelName.class);
            String tabelname = "";
            /*判断是否存在该注解*/
            if (tabelNameAnnotation != null) {
                tabelname = tabelNameAnnotation.value();
            } else {
                tabelname = clazz.getSimpleName();
            }

            //追加表名
            sql.append(tabelname);
            System.out.println(sql);

            return find(sql.toString());

    }

    //删除
    public int delete(Object id){
        try {
            StringBuffer sql = new StringBuffer("delete from ");

            //获取表名
            TabelName tabelNameAnnotation = clazz.getAnnotation(TabelName.class);
            String tabelname = "";
            /*判断是否存在该注解*/
            if (tabelNameAnnotation != null) {
                tabelname = tabelNameAnnotation.value();
            } else {
                tabelname = clazz.getSimpleName();
            }

            //追加表名
            sql.append(tabelname+" where ");
            System.out.println(sql);

            //获取该反射类对象中所有的属性对象
            Field[] declaredFields = clazz.getDeclaredFields();
            boolean flag = false;
            for (Field declaredFiled:declaredFields
                 ) {
                TableId tableId = declaredFiled.getAnnotation(TableId.class);
                if (tableId!=null){
                    sql.append(tableId.value()+"='"+id+"'");
                    flag=true;
                    break;
                }
            }
            if (flag==false){
                throw new RuntimeException("没有添加主键注解");
            }

            System.out.println(sql);
            //获取连接对象
            Connection con = DBUtils.getCon();
            //获取sql语句对象
            PreparedStatement ps = con.prepareStatement(sql.toString());
            //执行sql语句
            int i = ps.executeUpdate();
            return i;

        }catch (Exception e){
            e.printStackTrace();
        }

        return 0;
    }



    //增加
    public int insert(T t) {
        try {
            //Sql:insert into 表名 values(?,?,?......)
            StringBuffer stringBuffer = new StringBuffer("insert into ");

            //获取表名
            Class<?> aClass = t.getClass();
            TabelName tabelNameAnnotation = aClass.getAnnotation(TabelName.class);
            String tabelname = "";
            /*判断是否存在该注解*/
            if (tabelNameAnnotation != null) {
                tabelname = tabelNameAnnotation.value();
            } else {
                tabelname = aClass.getSimpleName();
            }

            //追加表名
            stringBuffer.append(tabelname);

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

            //创建两个集合
            List<String> columns = new ArrayList<String>();//存放所有的列名
            List<String> values = new ArrayList<String>();//存放所有的列值

            for (Field field : declaredFields
            ) {
                field.setAccessible(true);
                //获取所有的列名
                TabelFiled tabelFiled = field.getAnnotation(TabelFiled.class);
                if (tabelFiled != null) {
                    columns.add(tabelFiled.value());
                } else {
                    columns.add(field.getName());
                }
                //获取所有的列值
                values.add("'" + field.get(t) + "'");


            }

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

            stringBuffer.append(" values ");

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

            System.out.println(stringBuffer);
            //获取连接对象
            Connection con = DBUtils.getCon();
            //获取sql语句对象
            PreparedStatement ps = con.prepareStatement(stringBuffer.toString());
            //执行sql语句
            int i = ps.executeUpdate();
            return i;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
        }
        return 0;
    }


    /*修改01*/
    public int update(T t){
        try {
            //update 表名 set 列名 = ? where id=?
            StringBuffer stringBuffer = new StringBuffer("update ");
            /*获取反射对象*/
            Class<?> aClass = t.getClass();
            TabelName tabelNameAnnotation = aClass.getAnnotation(TabelName.class);
            String tablename = "";
            if (tabelNameAnnotation != null) {
                tablename = tabelNameAnnotation.value();
            } else {
                tablename = aClass.getSimpleName();
            }
            stringBuffer.append(tablename + " set ");

            Field[] declaredFields = aClass.getDeclaredFields();

            List<String> columns = new ArrayList<String>();
            List<String> values = new ArrayList<String>();

            for (Field field : declaredFields
            ) {
                field.setAccessible(true);
                TabelFiled tabelFiled = field.getAnnotation(TabelFiled.class);
                if (tabelFiled != null) {
                    columns.add(tabelFiled.value());
                } else {
                    columns.add(field.getName());
                }
                values.add("'" + field.get(t) + "'");
            }
            String remove = columns.remove(0);
            String remove01 = values.remove(0);
            System.out.println(remove + " " + remove01);

            Object[] columnsArray = columns.toArray();
            Object[] valuesArray = values.toArray();
            for (int i = 0; i < columnsArray.length; i++) {
                for (int j = 0; j < valuesArray.length; j++) {
                    if (i == j) {
                        stringBuffer.append(columnsArray[i] + "=" + valuesArray[j] + ",");
                    }
                }
            }


            stringBuffer = new StringBuffer(stringBuffer.substring(0, stringBuffer.length() - 1) + " where " + remove + "=" + remove01);
            System.out.println(stringBuffer);

            Connection con = DBUtils.getCon();
            PreparedStatement ps= con.prepareStatement(stringBuffer.toString());
            int i = ps.executeUpdate();
            return i;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
        }
        return 0;
    }


    /*修改02*/
    public int updateById(T t){
        try {
            //修改--update 表名 set 列名=值,列名=值... where 主键=值;

            StringBuffer sql = new StringBuffer("update ");

            /*获取表名*/
            Class<?> aClass = t.getClass();
            TabelName tabelNameAnnotation = aClass.getAnnotation(TabelName.class);
            String tableName = "";
            if (tabelNameAnnotation != null) {
                tableName = tabelNameAnnotation.value();
            } else {
                tableName = aClass.getSimpleName();
            }
            sql.append(tableName + " set ");
            System.out.println(sql);

            /*获取列值*/
            String columnValue = "";
            String where = " where ";
            Field[] declaredFields = aClass.getDeclaredFields();
            boolean flag = false;
            for (Field field : declaredFields
            ) {
                field.setAccessible(true);
                TabelFiled tabelFiledAnnotation = field.getAnnotation(TabelFiled.class);
                if (tabelFiledAnnotation != null) {
                    columnValue += tabelFiledAnnotation.value() + "='" + field.get(t) + "', ";
                } else {
                    TableId tableIdAnnotation = field.getAnnotation(TableId.class);
                    if (tableIdAnnotation!=null){
                        flag = true;
                        where +=tableIdAnnotation.value()+"='"+field.get(t)+"'";
                    }else {
                        columnValue+= field.getName()+ "='" + field.get(t) + "',";
                    }
                }
            }
            if (flag==false){
                throw new RuntimeException("没有添加主键注解");
            }
            //去除最后一个问号
            columnValue=columnValue.substring(0,columnValue.lastIndexOf(","));
            sql.append(columnValue).append(where);
            System.out.println(sql );

            Connection con = DBUtils.getCon();
            PreparedStatement ps= con.prepareStatement(sql.toString());
            int i = ps.executeUpdate();
            return i;
        }catch (Exception e){
            e.printStackTrace();
        }


        return 0;
    }


}

entity包:实体类Student

package com.qy151.entity;

import com.qy151.annotation.TabelFiled;
import com.qy151.annotation.TabelName;
import com.qy151.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @unthor : YSH
 * @date : 20:34 2022/7/14
 */
@Data
/*@NoArgsConstructor
@AllArgsConstructor*/
@TabelName(value = "t_student")
public class Student {
    /*private Integer id;*/


    @TabelFiled(value = "name")
    private String studentname;
    private String address;

    //表示该列是主键列
    @TableId(value = "id")
    private Integer sid;
}

dao包:操作类

package com.qy151.dao;

import com.qy151.entity.Student;
import com.qy151.util.BaseDao;

/**
 * @unthor : YSH
 * @date : 20:49 2022/7/14
 */
public class StudentDao extends BaseDao<Student> {
}

Test:测试类

import com.qy151.dao.StudentDao;
import com.qy151.dao.UserDao;
import com.qy151.entity.Student;
import com.qy151.entity.User;
import org.junit.Test;

/**
 * @unthor : YSH
 * @date : 20:49 2022/7/14
 */
public class StudentTest {
    StudentDao studentDao = new StudentDao();

    @Test
    public void insert(){
        Student student = new Student();
        student.setSid(20);
        student.setStudentname("周六");
        student.setAddress("北京");
        studentDao.insert(student);
    }

    @Test
    public void update() {
        Student student = new Student();
        student.setSid(20);
        student.setStudentname("张三");
        student.setAddress("金星");
        studentDao.update(student);
    }

    @Test
    public void updateById() {
        Student student = new Student();
        student.setSid(20);
        student.setStudentname("张三");
        student.setAddress("水星");
        studentDao.updateById(student);
    }

    @Test
    public void delete(){
        Student student = new Student();
        studentDao.delete(20);
    }


    @Test
    public void findAll() throws Exception {
        Student student = new Student();
        System.out.println(studentDao.findAll());
    }

    @Test
    public void findOneById() throws Exception {
        Student student = new Student();
        System.out.println(studentDao.findOneById(10));
    }
}

 

IDEA将项目打包成jar包 

IDEA将项目打包成jar包https://blog.csdn.net/weixin_61634823/article/details/124827963

包含项目中使用的依赖

打包的jar包中Lombok包不能使用,报错

解决方法:

开启idea注解处理

猜你喜欢

转载自blog.csdn.net/Ysuhang/article/details/125841377