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

ORM:(Object relative Mapping)对象关系映射框。

帮你自动把数据库中的记录和java实体类对应映射在一起。

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

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

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

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

package com.wzh.orm.annotation;

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

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.annotation
 * @ClassName: TableName
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 21:49
 * @Version: 1.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    String value();
}
package com.wzh.orm.annotation;

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

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.annotation
 * @ClassName: TableField
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 21:52
 * @Version: 1.0
 */
@Target(ElementType.FIELD)  //限制注解的使用只能在属性上
@Retention(RetentionPolicy.RUNTIME) //设置注解运行阶段生效
public @interface TableField {
    String value();
}
package com.wzh.orm.annotation;

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

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.annotation
 * @ClassName: TablePrimaryKey
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 21:51
 * @Version: 1.0
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TablePrimaryKey {
    String value() default "id";
}

util包: 公共类

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

package com.wzh.orm.util;

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

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.util
 * @ClassName: DBUtils
 * @Author: 王振华
 * @Description: 获取连接对象和关闭连接资源
 * @Date: 2022/7/15 21:31
 * @Version: 1.0
 */
public class DBUtils {
    private static String driverName;
    private static String url;
    private static String username;
    private static String password;

    //静态代码块
    static{
        Properties properties = new Properties();
        try {
            //加载属性配置文件
            properties.load(new FileInputStream("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 ClassNotFoundException, SQLException {
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url,username,password);
        return connection;
    }

    //关闭连接资源
    public static void closeAll(ResultSet rs,PreparedStatement ps,Connection conn){
        try {
            if(rs!=null){
                rs.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        try {
            if(ps!=null){
                ps.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        try {
            if(conn!=null){
                conn.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.wzh.orm.util;

import com.wzh.orm.annotation.TableField;
import com.wzh.orm.annotation.TableName;
import com.wzh.orm.annotation.TablePrimaryKey;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.util
 * @ClassName: BaseDao
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 21:39
 * @Version: 1.0
 */

//T: 表示实体类对象
public class BaseDao<T> {
    private Class<?> clazz; //实体类的反射类对象  获取泛型T
    private ResultSet rs = null;
    private Connection conn = null;
    private PreparedStatement preparedStatement = null;
    public BaseDao(){
        //this对应的是子类对象  获取当前类的反射类对象
        Class<? extends BaseDao> aClass = this.getClass();
        //获取当前反射类的父类反射类----包含了父类的泛型
        ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
        //获取泛型的反射类
        Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
        clazz = (Class<?>) actualTypeArguments[0];
    }

    //添加
    public int insert(T t){
        try {
            StringBuffer stringBuffer = new StringBuffer("insert into ");
            //获取表名
            Class<?> aClass = t.getClass();
            TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
            String tableName = "";
            //是否存在该注解
            if(tableNameAnnotation!=null){
                tableName = tableNameAnnotation.value();
            }else{
                //通过反射类对象获取类名
                tableName = aClass.getSimpleName();
            }
            stringBuffer.append(tableName);
            //获取反射类对象中所有的属性对象
            Field[] declaredFields = aClass.getDeclaredFields();
            //创建两个集合
            List<String> columns = new ArrayList<>();   //存放所有的列名
            List<String> values = new ArrayList<>();    //存放所有的列值
            for (Field field : declaredFields) {
                field.setAccessible(true);  //设置属性可访问
                //获取属性对象的指定注解
                TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                if(tablePrimaryKeyAnnotation!=null){
                    columns.add(tablePrimaryKeyAnnotation.value());
                }else {
                    if(tableFieldAnnotation!=null){
                        columns.add(tableFieldAnnotation.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("]",")"));

            conn = DBUtils.getConn();
            preparedStatement = conn.prepareStatement(stringBuffer.toString());
            int i = preparedStatement.executeUpdate();
            return i;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            DBUtils.closeAll(rs,preparedStatement,conn);
        }
        return 0;
    }

    //修改
    public int updateById(T t){
        try {
            StringBuffer stringBuffer = new StringBuffer("update ");
            //获取反射类对象
            Class<?> aClass = t.getClass();
            TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
            String tableName = "";
            //是否存在该注解
            if(tableNameAnnotation!=null){
                tableName = tableNameAnnotation.value();
            }else{
                //通过反射类对象获取类名
                tableName = aClass.getSimpleName();
            }
            stringBuffer.append(tableName+" set ");
            String columnValue = "";
            String where = " where ";
            //获取所有的属性对象
            Field[] declaredFields = aClass.getDeclaredFields();
            boolean flag = false;
            for(Field field : declaredFields){
                field.setAccessible(true);  //设置属性可访问
                //获取属性对象的指定注解
                TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                if(tablePrimaryKeyAnnotation!=null){
                    flag = true;
                    where+=tablePrimaryKeyAnnotation.value()+" = '"+field.get(t)+"'";
                }else {
                    if(tableFieldAnnotation!=null){
                        columnValue += tableFieldAnnotation.value()+" = '"+field.get(t)+"',";
                    }else {
                        columnValue += field.getName()+" = '"+field.get(t)+"',";;//获取属性名称
                    }
                }
            }
            if(flag==false){
                throw new RuntimeException("没有添加主键注解");
            }

            //删除最后的逗号
            columnValue = columnValue.substring(0,columnValue.lastIndexOf(","));
            stringBuffer.append(columnValue);
            stringBuffer.append(where);

            conn = DBUtils.getConn();
            preparedStatement = conn.prepareStatement(stringBuffer.toString());
            int i = preparedStatement.executeUpdate();
            return i;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            DBUtils.closeAll(rs,preparedStatement,conn);
        }
            return 0;
    }

    //根据id删除
    public int deleteById(Object id){
        try{
            StringBuffer stringBuffer = new StringBuffer("delete from ");
            //获取表名
            TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
            if(tableNameAnnotation!=null){
                stringBuffer.append(tableNameAnnotation.value());
            }else{
                stringBuffer.append(clazz.getSimpleName());
            }

            stringBuffer.append(" where ");
            Field[] declaredFields = clazz.getDeclaredFields();
            boolean flag = false;
            for(Field field : declaredFields) {
                TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                if(tablePrimaryKeyAnnotation!=null){
                    stringBuffer.append(tablePrimaryKeyAnnotation.value()+" = '"+id+"'");
                    flag = true;
                    break;
                }
            }
            if(flag==false){
                throw new RuntimeException("没有添加主键注解");
            }
            conn = DBUtils.getConn();
            preparedStatement = conn.prepareStatement(stringBuffer.toString());
            int i = preparedStatement.executeUpdate();
            return i;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            DBUtils.closeAll(rs,preparedStatement,conn);
        }
            return 0;
    }

    //查询所有
    public List<T> selectAll(){
        List<T> list = new ArrayList<>();
        try {
            StringBuffer stringBuffer = new StringBuffer("select ");
            //获取所有的属性对象
            Field[] declaredFields = clazz.getDeclaredFields();
            boolean flag = false;
            for(Field field : declaredFields){
                field.setAccessible(true);  //设置属性可访问
                //获取属性对象的指定注解
                TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                if(tablePrimaryKeyAnnotation!=null){
                    flag = true;
                    stringBuffer.append(tablePrimaryKeyAnnotation.value()+",");
                }else {
                    if(tableFieldAnnotation!=null){
                        stringBuffer.append(tableFieldAnnotation.value()+",");
                    }else {
                        stringBuffer.append(field.getName()+",");;//获取属性名称
                    }
                }
            }
            if(flag==false){
                throw new RuntimeException("没有添加主键注解");
            }
            stringBuffer.deleteCharAt(stringBuffer.length()-1);
            stringBuffer.append(" from ");
            //获取表名
            TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
            if(tableNameAnnotation!=null){
                stringBuffer.append(tableNameAnnotation.value());
            }else{
                stringBuffer.append(clazz.getSimpleName());
            }

            conn = DBUtils.getConn();
            preparedStatement = conn.prepareStatement(stringBuffer.toString());
            rs = preparedStatement.executeQuery();
            while(rs.next()){
                Object o = clazz.newInstance();
                Field[] declaredFields1 = clazz.getDeclaredFields();
                boolean flag1 = false;
                for(Field field : declaredFields1){
                    field.setAccessible(true);
                    //获取属性对象的指定注解
                    TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                    TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                    if(tablePrimaryKeyAnnotation!=null){
                        flag1 = true;
                        field.set(o,rs.getObject(tablePrimaryKeyAnnotation.value()));
                    }else {
                        if(tableFieldAnnotation!=null){
                            field.set(o,rs.getObject(tableFieldAnnotation.value()));
                        }else {
                            field.set(o,rs.getObject(field.getName()));
                        }
                    }
                }
                if(flag1==false){
                    throw new RuntimeException("没有添加主键注解");
                }
                list.add((T)o);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeAll(rs,preparedStatement,conn);
        }

        return list;
    }

    //根据id查询
    public T selectById(Object id){
        T t = null;
        try {
            StringBuffer stringBuffer = new StringBuffer("select ");
            //获取所有的属性对象
            Field[] declaredFields = clazz.getDeclaredFields();
            String where = " where ";
            boolean flag = false;
            for(Field field : declaredFields){
                field.setAccessible(true);  //设置属性可访问
                //获取属性对象的指定注解
                TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                if(tablePrimaryKeyAnnotation!=null){
                    flag = true;
                    stringBuffer.append(tablePrimaryKeyAnnotation.value()+",");
                    where += tablePrimaryKeyAnnotation.value()+" = ";
                }else {
                    if(tableFieldAnnotation!=null){
                        stringBuffer.append(tableFieldAnnotation.value()+",");
                    }else {
                        stringBuffer.append(field.getName()+",");;//获取属性名称
                    }
                }
            }
            if(flag==false){
                throw new RuntimeException("没有添加主键注解");
            }
            stringBuffer.deleteCharAt(stringBuffer.length()-1);
            stringBuffer.append(" from ");
            //获取表名
            TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
            if(tableNameAnnotation!=null){
                stringBuffer.append(tableNameAnnotation.value());
            }else{
                stringBuffer.append(clazz.getSimpleName());
            }
            stringBuffer.append(where+id);

            conn = DBUtils.getConn();
            preparedStatement = conn.prepareStatement(stringBuffer.toString());
            rs = preparedStatement.executeQuery();
            while(rs.next()){
                t = (T) clazz.newInstance();
                Field[] declaredFields1 = clazz.getDeclaredFields();
                boolean flag1 = false;
                for(Field field : declaredFields1){
                    field.setAccessible(true);
                    //获取属性对象的指定注解
                    TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                    TablePrimaryKey tablePrimaryKeyAnnotation = field.getAnnotation(TablePrimaryKey.class);
                    if(tablePrimaryKeyAnnotation!=null){
                        flag1 = true;
                        field.set(t,rs.getObject(tablePrimaryKeyAnnotation.value()));
                    }else {
                        if(tableFieldAnnotation!=null){
                            field.set(t,rs.getObject(tableFieldAnnotation.value()));
                        }else {
                            field.set(t,rs.getObject(field.getName()));
                        }
                    }
                }
                if(flag1==false){
                    throw new RuntimeException("没有添加主键注解");
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeAll(rs,preparedStatement,conn);
        }
        return t;
    }

}

entity包 : 实体类Dept

package com.wzh.orm.entity;

import com.wzh.orm.annotation.TableField;
import com.wzh.orm.annotation.TableName;
import com.wzh.orm.annotation.TablePrimaryKey;
import lombok.Data;

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.entity
 * @ClassName: Dept
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 21:26
 * @Version: 1.0
 */


@Data
@TableName("tb_dept")
public class Dept {

    @TableField("name")
    private String deptName;
    @TablePrimaryKey()
    private Integer id;

    private String imgUrl;

    @Override
    public String toString() {
        return "Dept{" +
                "id=" + id +
                ", deptName='" + deptName + '\'' +
                ", imgUrl='" + imgUrl + '\'' +
                '}';
    }


}

dao包: 操作类

package com.wzh.orm.dao;

import com.wzh.orm.entity.Dept;
import com.wzh.orm.util.BaseDao;

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm.dao
 * @ClassName: DeptDao
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 21:30
 * @Version: 1.0
 */
public class DeptDao extends BaseDao<Dept> {
}

 测试:

package com.wzh.orm;

import com.wzh.orm.dao.DeptDao;
import com.wzh.orm.entity.Dept;
import org.junit.Test;

import java.util.List;

/**
 * @ProjectName: ORM0715
 * @Package: com.wzh.orm
 * @ClassName: Test
 * @Author: 王振华
 * @Description:
 * @Date: 2022/7/15 22:36
 * @Version: 1.0
 */
public class TestDeptDao {
    public static void main(String[] args) {
        DeptDao deptDao = new DeptDao();
        Dept dept = new Dept();
        dept.setId(37);
        dept.setDeptName("人事部");
        dept.setImgUrl("=======");
        int insert = deptDao.insert(dept);
    }

    @Test
    public void testUpdate(){
        DeptDao deptDao = new DeptDao();
        Dept dept = new Dept();
        dept.setId(37);
        dept.setDeptName("后勤部");
        dept.setImgUrl("********");
        int insert = deptDao.updateById(dept);
    }
    @Test
    public void testDeleteById(){
        DeptDao deptDao = new DeptDao();
        int i = deptDao.deleteById(35);
        System.out.println(i);
    }
    @Test
    public void testSelectAll(){
        DeptDao deptDao = new DeptDao();
        List<Dept> depts = deptDao.selectAll();
        System.out.println(depts);
    }
    @Test
    public void testSelectById(){
        DeptDao deptDao = new DeptDao();
        Dept dept = deptDao.selectById(2);
        System.out.println(dept);
    }
}

IDEA将项目打包成jar包

【1】把自己的项目打成jar包:

 如果其它项目想要使用的话,在pom.xml添加依赖

 

【2】 如何把一个jar打包到本地自己的仓库,才可以通过maven引入该jar包

还是以上边jar为例,先把刚刚保存的jar包从maven本地仓库清掉

 

比如这是第三方的jar包,随便放到一个路径, 

 我本地仓库在D盘,在d盘敲cmd进入黑窗口。

mvn install:install-file -Dfile=D:/java_idea_2020/dev/maven-shiro1028-1.0-SNAPSHOT.jar -Dpackaging=jar -DgroupId=com.wzh -DartifactId=maven-shiro -Dversion=1.0

 其中DgroupId 对应groupId名,-DartifactId对应artifactId名,-Dversion对应依赖版本号,-Dfile是jar包的绝对路径,-Dpackaging是文件打包方式。请根据自己的需要进行修改。

 此时本地仓库就有了该jar包

 在pom.xml中的引用为

 一切的前提都是要配置好maven环境后才能操作

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

解决方法:

开启idea注解处理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值