自定义实现ORMapping框架

自定义实现ORMapping框架的核心在于反射和注解的应用,关于这部分的内容可以参考文章:
Java反射总结
Java自定义注解的实现

在本篇文章中主要实现save方法,关键在于以下几步:

  • 自定义注解的实现
  • 通过反射获取表名和字段名
  • SQL拼接的实现
  • DBUtils的开发

具体代码如下
annotation:

/**
 * @Author: huhu
 * @Date: 2019-08-10 19:21
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface HuHuBean {

    String value();
}
/**
 * @Author: huhu
 * @Date: 2019-08-10 19:22
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface HuHuField {

    String value();
}

dao:

/**
 * @Author: huhu
 * @Date: 2019-08-10 19:28
 */
public interface BaseDAO {

    /**
     * insert into xxx(col1, col2, col3...) values(?,?,?...)
     *
     * @param t
     * @param <T>
     * @return
     */
    <T>Serializable save(T t);

}
/**
 * @Author: huhu
 * @Date: 2019-08-10 19:35
 */
public class BaseDAOImpl implements BaseDAO {

    /**
     * 入参是T:User
     *
     * insert into t_user (name,age,birth_day) values (?,?,?);
     *
     * t: user
     * user.getId() user.getName() 通过这种方式依次将值给获取出来
     *
     * 常见面试考点:StringBuffer与StringBuilder的区别
     *
     * @param t
     * @param <T>
     * @return
     */
    @Override
    public <T> Serializable save(T t) {

        StringBuilder builder = new StringBuilder("insert into ");
        String table = Tools.getTable(t.getClass());
        builder.append(table).append(" (");

        Class<?> clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //判断获取的字段是否为id,id为自增主键,因此不需要拼接
            if (!field.getName().equals("id")) {
                String column = Tools.getColumn(field);
                builder.append(column).append(",");
            }
        }

        // 删除逗号
        builder.deleteCharAt(builder.toString().length()-1)
                .append(") values (");

        // 有几个?取决于需要拼接几个字段
        for (Field field : fields) {
            if (!field.getName().equals("id")) {
                builder.append("?,");
            }
        }

        // 删除逗号
        builder.deleteCharAt(builder.toString().length()-1)
                .append(")");

//        System.out.println(builder.toString());

        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs =null;
        int index = 1;

        try {
            connection = DBUtils.getConnection();
            // 将拼接好的SQL传入
//            pstmt = connection.prepareStatement(builder.toString());
            // 传入拼接好的sql以及需要返回的字段名id
            pstmt = connection.prepareStatement(builder.toString(), new String[]{"id"});

            for (Field field : fields) {
                if (!field.getName().equals("id")) {
                    String getMethod = Tools.getMethod(field);
                    Method method = clazz.getDeclaredMethod(getMethod);
                    Object obj = method.invoke(t);
                    pstmt.setObject(index++, obj);
                }
            }

            int rowCount = pstmt.executeUpdate();
            System.out.println("rowCount: " + rowCount);
            if (rowCount > 0) {
                rs = pstmt.getGeneratedKeys();
                rs.next();
                // 返回id字段的最新值
                return (Serializable) rs.getObject(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return null;
    }

}

domain:

/**
 * @Author: huhu
 * @Date: 2019-08-10 19:18
 */
@HuHuBean("t_user")
public class User {

    private Integer id;

    private String name;

    private Integer age;

    @HuHuField("birth_day")
    private Date bithday;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBithday() {
        return bithday;
    }

    public void setBithday(Date bithday) {
        this.bithday = bithday;
    }

    public User() {}

    public User(String name, Integer age, Date bithday) {
        this.name = name;
        this.age = age;
        this.bithday = bithday;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", bithday=" + bithday +
                '}';
    }
}

utils:

/**
 * @Author: huhu
 * @Date: 2019-08-11 20:41
 */
public class DBUtils {

    public static Connection getConnection() {

        String url = "jdbc:mysql://localhost:3306/orm";
        String user = "root";
        String password = "root";
        Connection connection = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }

        return connection;
    }

    public static void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
/**
 * @Author: huhu
 * @Date: 2019-08-11 16:31
 */
public class Tools {

    /**
     * 根据注解获取表名
     *
     * @param clazz
     * @return
     */
    public static String getTable(Class<?> clazz) {

        String tableName = "";

        HuHuBean huHuBean = clazz.getAnnotation(HuHuBean.class);

        if (huHuBean != null) {
            // 获取注解中的值
            tableName = huHuBean.value();
        } else {
            // 如果为空,就直接获取类名
            tableName = clazz.getSimpleName();
        }

        return tableName;

    }

    /**
     * 根据注解获取属性名称
     *
     * @param field
     * @return
     */
    public static String getColumn(Field field) {

        String column = "";

        HuHuField huHuField = field.getAnnotation(HuHuField.class);
        if (huHuField != null) {
            // 获取注解中的值
            column = huHuField.value();
        } else {
            // 如果为空,就直接获取字段名
            column = field.getName();
        }

        return column;
    }

    /**
     * 根据字段获取对应的get方法
     *
     * @param field
     * @return
     */
    public static String getMethod(Field field) {
        String fieldName = field.getName();

        // id==>getId
        // name==>getNamet
        String name = fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
        return "get" + name;
    }
}

Test:

/**
 * @Author: huhu
 * @Date: 2019-08-11 17:52
 */
public class BaseDAOImplTest {

    @Test
    public void test01() {
        BaseDAO dao = new BaseDAOImpl();
        User user = new User("HuHu", 22, new Date());

        System.out.println(dao.save(user));

    }
}

测试结果:
在这里插入图片描述
数据插入成功

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:  本项目课程是一门极具综合性和完整性的大型项目课程;课程项目的业务背景源自各类互联网公司对海量用户浏览行为数据和业务数据分析的需求及企业数据管理、数据运营需求。 本课程项目涵盖数据采集与预处理、数据仓库体系建设、用户画像系统建设、数据治理(元数据管理、数据质量管理)、任务调度系统、数据服务层建设、OLAP即席分析系统建设等大量模块,力求原汁原味重现一个完备的企业级大型数据运营系统。  拒绝demo,拒绝宏观抽象,拒绝只讲不练,本课程高度揉和理论与实战,并兼顾各层次的学员,真正从0开始,循序渐进,每一个步骤每一个环节,都会带领学员从需求分析开始,到逻辑设计,最后落实到每一行代码,所有流程都采用企业级解决方案,并手把手带领学员一一实现,拒绝复制粘贴,拒绝demo化的实现。并且会穿插大量的原创图解,来帮助学员理解复杂逻辑,掌握关键流程,熟悉核心架构。   跟随项目课程,历经接近100+小时的时间,从需求分析开始,到数据埋点采集,到预处理程序代码编写,到数仓体系搭建......逐渐展开整个项目的宏大视图,构建起整个项目的摩天大厦。  由于本课程不光讲解项目的实现,还会在实现过程中反复揉和各种技术细节,各种设计思想,各种最佳实践思维,学完本项目并勤于实践的话,学员的收获将远远超越一个项目的具体实现,更能对大型数据系统开发产生深刻体悟,对很多技术的应用将感觉豁然开朗,并带来融会贯通能力的巨大飞跃。当然,最直接的收获是,学完本课程,你将很容易就拿到大数据数仓建设或用户画像建设等岗位的OFFER课程模块: 1. 数据采集:涉及到埋点日志flume采集系统,sqoop业务数据抽取系统等; 2. 数据预处理:涉及到各类字典数据构建,复杂结构数据清洗解析,数据集成,数据修正,以及多渠道数据的用户身份标识打通:ID-MAPPING等;3. 数据仓库:涉及到hive数仓基础设施搭建,数仓分层体系设计,数仓分析主题设计,多维分析实现,ETL任务脚本开发,ETL任务调度,数据生命周期管理等;4. 数据治理:涉及数据资产查询管理,数据质量监控管理,atlas元数据管理系统,atlas数据血缘管理等;5. 用户画像系统:涉及画像标签体系设计,标签体系层级关系设计,各类标签计算实现,兴趣类标签的衰减合并,模型标签的机器学习算法应用及特征提取、模型训练等;6. OLAP即席分析平台:涉及OLAP平台的整体架构设计,技术选型,底层存储实现,Presto查询引擎搭建,数据服务接口开发等;7. 数据服务:涉及数据服务的整体设计理念,架构搭建,各类数据访问需求的restapi开发等;课程所涉及的技术: 整个项目课程中,将涉及到一个大型数据系统中所用到的几乎所有主要技术,具体来说,包含但不限于如下技术组件:l Hadoopl Hivel HBasel SparkCore /SparkSQL/ Spark GRAPHX / Spark Mllibl Sqoopl Azkabanl Flumel lasal Kafkal Zookeeperl Solrl Prestop

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值