记得第一次写项目的时候,傻傻的数据库一张表,代码里就写一个DAO类,几张表就写几个DAO类,大量的反复代码,自己粘着都嫌烦,后来接触了Hibernate,不得不说对我们这样的小白用处还是非常大的。那么多的实体类,一个DAO就能够实现主要的数据库操作了。于是我用的不亦乐乎,但究竟是怎么做的,从来没有考虑过。如今用这些框架已经有一段时间了,原谅我脑洞大开,想自己实现一下这样的类似的功能:



在准备写之前,我们须要一些规则:

    1、由实体类名,能够知道我这个类是存放在哪张表里---这里我採用的是和t_类名

    2、由实体类中的变量名能够知道相应表中的字段名的一一这里我採用f_变量名做为字段名

    3、实体类里,有着对变量的赋值与获取,且方法名有一定的规则----比方我们经常使用的get、set方法 ,这里我也是採用这样的方法



一、利用如上规则设计相关的类与表:

我这里写了两个实体类customer和admin,并在类中多加了一个toString方法,便于后面信息打印查看:

 
package com.java.reflect.database;
public class Customer {
    private Long id;
    private String username;
    private String password;
    private String realname;
    private String address;
    private String email;
    private String mobile;
    
    @Override
    public String toString() {
        return "Customer [id=" + id + ", username=" + username + ", password="
                + password + ", realname=" + realname + ", address=" + address
                + ", email=" + email + ", mobile=" + mobile + "]";
    }
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRealname() {
        return realname;
    }
    public void setRealname(String realname) {
        this.realname = realname;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getMobile() {
        return mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}
 

类似能够写admin。都贴出来的话会非常长,就不贴了,相应的表结构设计例如以下:

 
                                 

二、利用反射拼出相应的数据库操作语句



保存语句拼凑:

 
public static String saveSql(Object o){
        StringBuilder sql = new StringBuilder();
        Class c = o.getClass();
        
        sql.append("INSERT INTO ");
        
        Method[] methods = c.getMethods();
        String cName = c.getName();
        ArrayList<String> fieldNames = new ArrayList<String>();
        ArrayList<Object> fieldValues = new ArrayList<Object>();
        
        String tableName = "t_"+cName.substring(cName.lastIndexOf(".")+1,cName.length());
        
        sql.append(tableName);
        sql.append(" (");
        
        for(Method method : methods){
            String mName = method.getName();
            if(mName.startsWith("get") && !mName.startsWith("getClass")){
                );
                fieldNames.add(fName);
                try{
                    Object value = method.invoke(o, null);
                    if(value instanceof String){
                        fieldValues.add("\""+value+"\"");
                    }
                    else{
                        fieldValues.add(value);
                    }
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
        ;i<fieldNames.size();++i){
            ){
                sql.append(fieldNames.get(i));
            }
            else{
                sql.append(","+fieldNames.get(i));
            }
        }
        sql.append(") values (");
        ;i<fieldValues.size();++i){
            ){
                sql.append(fieldValues.get(i));
            }
            else{
                sql.append(","+fieldValues.get(i));
            }
        }
        sql.append(")");
        return sql.toString();
    }
 

这里的重点在于利用反射拼凑SQL语句的过程----

    1、这个函数的參数类型是什么?怎样接收一个随意的实体类?

    这里我用的是object,由于不管你传什么样的一个參数过来,其都是Objcet类的一个子类。用Object没有问题,这里我在考虑后面利用泛型,只是这种话在后面查询的话。实例化的时候要麻烦一点。

临时先不考虑。

2、怎样知道这个实体类的类名?并找到相应的表?

    利用函数getClass得到这个实体类相应的类。再利用getName得到类名,包含包名,再依照你制定的规则解析出相应的表名



    3、開始拼凑sql语句,由于要重复的改变sql字符串,这里我用的StringBuilder对象。在插入的时候。我们的语句是这种

        INSERT INTO 表名(字段名) VALUES (相应的值)

        这里我们有三个须要知道的变量。表名已经在第二步中拿到

        如今我们考虑拿字段名。拿到后存放到一个list里,首先拿我们全部的方法。找到以get开头的方法,我们依照对变量赋值时命名函数规则。全部以get开头的(我们把getClass排除在外),解析得到相应的字段名。这里相应我的语句:

 String fName = "f_"+mName.substring(3);

        有了字段名。接下来,拿相应的值,也存到相应的list里。这里取值用的method.invoke方法。请參照上面代码,为了拼凑方便,对于字符串。我直接以“xxxx”的形式存储。

有了对应的值。接下就是拼凑了,这个应该没什么难度,最后对于随意一个对象,拼凑的结果例如以下,customer有点长没能截全: 





三、利用已经拼凑好的sql语句,运行。这个应该简单了吧

        运行结果如图:

                

/1a0aa07e-0fe3-40f1-acb3-3bf8b91c0fe1/wH7XOU2B7hk6mDG.NJ6K11Is1C7GqJqJztQNMuBBeD0!/o/dFKSfW96JAAA&bo=zQAsAM0ALAADACU!" style="vertical-align:top; width:205px; height:44px"> 

 

        

/1a0aa07e-0fe3-40f1-acb3-3bf8b91c0fe1/.4qfDNoRX4A*p9pkcCxjZaLoQ953i6T*KsUuxpP*160!/o/dAe37G44IwAA&bo=DwIwAA8CMAADACU!" style="vertical-align:top; width:527px; height:48px">

代码大致是这样子的,可是从健壮性上去考虑的话。还有非常多地方须要改动,这里仅仅是用来简单说明怎样利用反射来实现这样的统一的DAO操作。

 
关于查询,能够自己练习一下,也是相同利用反射拼凑出来,可是查询的关键在于怎样利用反射把查到数据包装成你须要的一个实体类。

測试代码:

/1a0aa07e-0fe3-40f1-acb3-3bf8b91c0fe1/HeQy6owjUTVdq0z9LqiGGaskocmRWOu6utHKj.4YkgA!/o/dNiZem99JAAA&bo=AwJvAAMCbwADACU!" style="vertical-align:top; width:515px; height:111px">

打印结果: 

/1a0aa07e-0fe3-40f1-acb3-3bf8b91c0fe1/KLFBBe*EZD1yobXGz2iS3IVb0EuJ4xRibwrrAJzqC00!/o/dGvRg29xJAAA&bo=wgBxAMIAcQADACU!" style="vertical-align:top; width:0px">

/1a0aa07e-0fe3-40f1-acb3-3bf8b91c0fe1/oUM8BuiICbnS2C4u7BO4APESgCj9yKG9WlVFFNPzveY!/o/dKmO6W4.IwAA&bo=wgNYAMIDWAADACU!" style="vertical-align:top; width:870px; height:79px">

这里没用泛型的一个不好的地方在于,操作时常常须要进行强制类型转换。后面能够考虑利用泛型。

利用反射技术实现POJO的数据库操作的更多相关文章

  1. [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

    [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...

  2. Java JDBC利用反射技术将查询结果封装为对象

    1.JDBC将返回结果集封装成对象demo class JdbcDemo { /** * 获取数据库列名 * @param rs * @return */ private static String[ ...

  3. 【转】【Java】利用反射技术,实现对类的私有方法、变量访问

    java关于反射机制的包主要在java.lang.reflect中,structs,hibernate,spring等框架都是基于java的反射机制. 下面是一个关于利用java的反射机制,实现了对私 ...

  4. 万能的JDBC工具类。通过反射机制直接简单处理数据库操作

    package com.YY.util; import java.io.IOException; import java.io.InputStream; import java.sql.Connect ...

  5. JDBC 利用反射技术将查询结果封装为对象(简单ORM实现)

    ORM(Object Relational Mapping)对象关系映射 public class ORMTest { public static void main(String[] args) t ...

  6. 结合java的反射和泛型性质简化JDBC和相应的同步等服务器数据库操作代码

    github地址:https://github.com/hzphzp/HeartTrace_Server 我们的服务器端数据库并没有用sqllite, 而是直接用mysql,并且用JDBC直接进行操作 ...

  7. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  8. Java开发笔记(七十九)利用反射技术操作私有属性

    早在介绍多态的时候,曾经提到公鸡实例的性别属性可能被篡改为雌性,不过面向对象的三大特性包含了封装.继承和多态,只要把性别属性设置为private私有级别,也不提供setSex这样的性别修改方法,那么性 ...

  9. Java开发笔记(八十)利用反射技术操作私有方法

    前面介绍了如何利用反射技术读写私有属性,不单是私有属性,就连私有方法也能通过反射技术来调用.为了演示反射的逆天功能,首先给Chicken鸡类增加下列几个私有方法,简单起见弄来了set***/get** ...

随机推荐

  1. Python面向对象(类之间的关系)(三)

    类与类之间的关系 在我们的世界中事物和事物之间总会有一些联系. 在面向对象中. 类和类之间也可以产生相关的关系 1. 依赖关系 执行某个动作的时候. 需要xxx来帮助你完成这个操作. 此时的关系是最轻 ...

  2. LeetCode(9)Palindrome Number

    题目: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could neg ...

  3. PAT Basic 1051

    1051 复数乘法 复数可以写成 (A+Bi) 的常规形式,其中 A 是实部,B 是虚部,i 是虚数单位,满足 i​2​​=−1:也可以写成极坐标下的指数形式 (R×e​(Pi)​​),其中 R 是复 ...

  4. C#上位机开发(二)—— Hello,World

    上一篇大致了解了一下单片机实际项目开发中上位机开发部分的内容以及VS下载与安装,按照编程惯例,接下来就是“Hello,World!” 1.新建C#项目工程 首先选择新建Windows窗体应用(.NET ...

  5. 大数据学习——kafka+storm+hdfs整合

    1 需求 kafka,storm,hdfs整合是流式数据常用的一套框架组合,现在 根据需求使用代码实现该需求 需求:应用所学技术实现,kafka接收随机句子,对接到storm中:使用storm集群统计 ...

  6. 【bzoj3956】Count 单调栈+可持久化线段树

    题目描述 输入 输出 样例输入 3 2 0 2 1 2 1 1 1 3 样例输出 0 3 题解 单调栈+可持久化线段树 本题是 bzoj4826 的弱化版(我为什么做题总喜欢先挑难的做QAQ) $k$ ...

  7. 【Luogu】P2016战略游戏(树形DP)

    题目链接 设f[i][j]表示以节点i为根的子树在状态j的情况下的最优解. j有两种情况. j=1:i这个根节点有士兵在站岗. j=0:i这个根节点没有士兵在站岗. 转移方程很好想. f[x][]+= ...

  8. 【SDOI2018】战略游戏(同时普及虚树)

    先看一道虚树普及题:给你一棵 $n$ 个点的树,$m$ 次询问,每次询问给你 $k$ 个关键点,求把这些点都连起来的路径并的最短长度.$1\le n,m\le 100000,\space 1\le \ ...

  9. cf670E Correct Bracket Sequence Editor

    Recently Polycarp started to develop a text editor that works only with correct bracket sequences (a ...

  10. Java的反射机制和动态代理

    介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原 ...