注解,泛型,反射的小应用:生成增删改查SQL的语句

来源:互联网 发布:淘宝详情页设计多少钱 编辑:程序博客网 时间:2024/05/01 03:55

注解:

所谓注解就是,给你的某个包、类、字段、方法、局部变量、方法参数等加个标记,这样我们可以在不方便或者不能直接对包,类,字段等等操作时,选择通过注解来简洁进行操作

泛型:

泛型的本质是参数化类型,所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

反射:

反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部信息。
应用:1.决定一个对象的类型
2.可以得到这个类的修饰符、字段、方法、构造器和父类的信息
3.找出一个接口中定义的常量和方法
4.创建一个运行时才得知名称的类的实例
5.获取和设置对象的字段值,即使字段名称直到运行程序时才得知名称
6.调用一个运行时才知道方法名称的对象的方法
7.创建一个新的数组,其大小和元素的类型直到运行时才知到,然后再修改数组中的元素

看完上面的总结,如果对注解,泛型,反射认识还是有些模糊,那么下面的例子,定能让你豁然开朗,理解都在注释中。

例子:

根据所提供的javabean,自动生成相应的增删改查SQL语句

JavaBean(这里是ProductBean)

package yanda.demo7_28;import com.java.base.annotation.PrimaryKey;@Table("product")public class ProductBean {    //对主键加注解    @PrimaryKey("id")    private int id;    private String name;    private float price;    //对get方法加注解    @Column("id")    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @Column("name")    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Column("price")    public float getPrice() {        return price;    }    public void setPrice(float price) {        this.price = price;    }}

Table注解:

package yanda.demo7_28;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 Table {    String value();}

PrimaryKey注解:

package yanda.demo7_28;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 PrimaryKey {    String value();}

Column注解:

package com.java.base.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(value=ElementType.METHOD)// 用于指定数据表的列名称@Retention(RetentionPolicy.RUNTIME)public @interface Column {    String value();}

Dao文件(BaseDao):

package yanda.demo7_28;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Map.Entry;import com.java.base.annotation.PrimaryKey;//定义一个泛型类public class BaseDao<T> {    public boolean add(T t) {        /*         * 通过userBean自动生成insert语句         *insert into product(price,name,id) values('5000.0','iphone','1')         */        Class clazz = t.getClass();//返回此 t的运行时类。        /*通过运行实类,可以调用反射中的        getDeclaredAnnotation(返回对象全部注解),        getDeclaredFields(返回对象的全部属性)        getDeclaredMethods(返回对象的全部方法)*/        Table table = (Table) clazz.getDeclaredAnnotation(Table.class);        String tableName = table.value();        System.out.println(tableName);        Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);        //获取指定行视图和指定列中的单元格的值        Set<Entry<Object, Object>> set = columnAndValue.entrySet();        List<Object> primaryKey = getPrimaryKey(clazz);        String keys = "";        String values = "";        for (Entry<Object, Object> entry : set) {            if(keys.length()>0) {                keys += ",";            }            if(values.length()>0) {                values += ",";            }            keys += entry.getKey();            values += "'"+entry.getValue()+"'";            System.out.println(entry.getKey()+","+entry.getValue());        }        String sql = "insert into "+tableName+"("+keys+") values("+values+")";        System.out.println(sql);        return true;    }    public boolean delete(T t) {        /*         * 通过userBean自动生成delete语句         *          * delete from product where id = 1         */        Class clazz = t.getClass();        //获得Bean        //获取表名称        Table table = (Table) clazz.getDeclaredAnnotation(Table.class);        //getDeclaredAnnotation()返回直接存在于此元素上的所有注释          String tableName = table.value();        System.out.println(tableName);        Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);        //获取指定行视图和制定列中的单元格的值        Set<Entry<Object, Object>> set = columnAndValue.entrySet();        List<Object> primaryKey = getPrimaryKey(clazz);        String keysAndvalues = "";        for (Entry<Object, Object> entry : set) {            /*if(entry.getKey().equals("id")){                keysAndvalues += entry.getKey() + " = " + entry.getValue();            }*/            //上面这个是我没有用PrimaryKey注解时的写法,这个写过于鸡肋,因为如果主键的name不是id就不行了            if(primaryKey.contains(entry.getKey())){                keysAndvalues += entry.getKey() + " = " + entry.getValue();            }        }        String sql = "delete from "+tableName+" where "+keysAndvalues;        System.out.println(sql);        return true;    }    public boolean update(T t) {        /*         * 通过ProductBean自动生成update语句         *          * updata product set price = 5000.0 and name = iphone where id = 1         */        Class clazz = t.getClass();        Table table = (Table) clazz.getDeclaredAnnotation(Table.class);        //getDeclaredAnnotation()返回直接存在于此元素上的所有注释          String tableName = table.value();        System.out.println(tableName);        Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);        //获取指定行视图和制定列中的单元格的值        Set<Entry<Object, Object>> set = columnAndValue.entrySet();        List<Object> primaryKey = getPrimaryKey(clazz);        String keysAndvalues = "";        String FkeysAndvalues = "";        /*int i=1;        for (Entry<Object, Object> entry : set) {            if(i<set.size()){                keysAndvalues += entry.getKey() + " = " + entry.getValue() + " ";                i++;            }            else{                FkeysAndvalues += " " + entry.getKey() + " = " + entry.getValue();            }        }*/        int i = 1;        for(Entry<Object, Object> entry : set){            if(primaryKey.contains(entry.getKey())){                FkeysAndvalues += " " + entry.getKey() + " = " + entry.getValue();                i++;            }            else{                if(1<i&&i < set.size()){                    keysAndvalues += " and ";                    keysAndvalues += entry.getKey() + " = " + entry.getValue();                }                else{                    keysAndvalues += entry.getKey() + " = " + entry.getValue();                    i++;                }            }        }        String sql = "updata "+tableName+" set "+keysAndvalues+" where"+FkeysAndvalues;        System.out.println(sql);        return true;    }    public boolean selete(T t) {        /*         * 通过userBean自动生成selete语句         *          * selete* from product where price = 5000.0 and name = iphone and id = 1         */        Class clazz = t.getClass();        //获得Bean        //获取表名称        Table table = (Table) clazz.getDeclaredAnnotation(Table.class);        //getDeclaredAnnotation()返回直接存在于此元素上的所有注释          String tableName = table.value();        System.out.println(tableName);        Map<Object, Object> columnAndValue = getColumnAndValue(clazz, t);        //获取指定行视图和制定列中的单元格的值        Set<Entry<Object, Object>> set = columnAndValue.entrySet();        String keysAndvalues = "";        for (Entry<Object, Object> entry : set) {            if(keysAndvalues.length()>0) {                keysAndvalues += " and ";            }            keysAndvalues += entry.getKey() + " = " + entry.getValue();        }        String sql = "selete* from "+tableName+" where "+keysAndvalues;        System.out.println(sql);        return true;    }    //按照<列明,属性>的格式输出所有的单元格    private Map<Object, Object> getColumnAndValue(Class<? extends T> clazz, T t) {        //首先声明了一个map键值对        Map<Object, Object> map = new HashMap<>();        //获取clazz类的所有方法        Method[] methods = clazz.getDeclaredMethods();        //获取的是类自身声明的所有方法,包含public、protected和private方法        for (Method method : methods) {            String methodName = method.getName();            if(methodName.startsWith("get")) {                //获得所有的get方法                Column column = method.getDeclaredAnnotation(Column.class);                ////getDeclaredAnnotation()返回直接存在于此元素上的所有注释                  //这个方法里放有参数时,返回指定类型的注解。如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。                try {                    map.put(column.value(), method.invoke(t));                    //invoke执行方法                } catch (IllegalAccessException e) {                    e.printStackTrace();                } catch (IllegalArgumentException e) {                    e.printStackTrace();                } catch (InvocationTargetException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }        return map;    }    private List<Object> getPrimaryKey(Class<? extends T> clazz){        List<Object> list = new ArrayList<>();        Field[] fields = clazz.getDeclaredFields();        //获得某个类的所有声明字段(id,name,price)        for (Field field : fields) {            if(field.isAnnotationPresent(PrimaryKey.class)) {    //Package.isAnnotationPresent()如果指定类型的注释存在于此元素上,则返回true;否则flase                PrimaryKey primaryKey = field.getDeclaredAnnotation(PrimaryKey.class);                try {                    list.add(primaryKey.value());                } catch (IllegalArgumentException e) {                    e.printStackTrace();                }            }        }        return list;    }}

主函数(main):

package yanda.demo7_28;public class Demo7_28_9 {    public static void main(String[] args) throws Exception {        ProductBean productBean = new ProductBean();        productBean.setId(1);        productBean.setName("iphone");        productBean.setPrice(5000);        ProductDao productDao = new ProductDao();        productDao.add(productBean);        productDao.delete(productBean);        productDao.update(productBean);        productDao.selete(productBean);    }}

输出结果:

这里写图片描述