JAVA jdbc封装 DbUtilsBean 1.1-查询方法支持指定封装类(内省)-通过自定义注解,支持指定列名

提出问题

当表中列名有 _ 时,如下表,有些字段有 _:

CREATE TABLE `t_notice` (
    `id` VARCHAR(32) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `from_userid` VARCHAR(32) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `to_userid` VARCHAR(32) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `msg` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    PRIMARY KEY (`id`)
)
COMMENT='推送消息日志'
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;

bean为了能够正常运行,名字也必须与 表中列名相同,如下:

public class TNotice2 {

    private String id;
    private String from_userid;
    private String to_userid;
    private String msg;

    public String getId() {
        return id;
    }

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

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getFrom_userid() {
        return from_userid;
    }

    public void setFrom_userid(String from_userid) {
        this.from_userid = from_userid;
    }

    public String getTo_userid() {
        return to_userid;
    }

    public void setTo_userid(String to_userid) {
        this.to_userid = to_userid;
    }
}

bean中的属性名也必须有 _,但是这样 不符合 java 成员变量的命名规则

用 DbUtilsBean 类无法完美的解决这种问题

解决

通过自定义 注解,可以指定表中的列名

定义 @Result 注解

package top.malaoshi.jdbc.annotation;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Result {
    // 该属性指定列名
    String column() default "";


}

修改 IntrospectorUtils 类

取出属性后,继续取出该属性的 @Result 注解,如果有该注解,就取出注解的 column 属性,将该属性作为 Map 中的 key

package top.malaoshi.jdbc;

import top.malaoshi.jdbc.annotation.Result;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class IntrospectorUtils {

    /**
     * 获取setter方法
     * @param clazz
     * @return 返回Map,属性名、Result注解的column作为key,setter方法作为value
     */
    public static Map<String, Method> getSetMethods(Class clazz) throws IntrospectionException, NoSuchFieldException {
        // 使用内省,目的:是反射的简化写法
        BeanInfo bi= Introspector.getBeanInfo(clazz); // 返回 BeanInfo,bean的信息
        // 将信息取出,放入到数组里
        PropertyDescriptor[] pds=bi.getPropertyDescriptors();
        // 将属性 和 相关的set方法,放入到map中
        Map<String,Method> propertyAndSetterMap = new HashMap();
        for( PropertyDescriptor pd : pds){
            String propertyName = pd.getName();
            if("class".equals(propertyName)){
                continue;
            }
            // 取出该属性对应Field类
            Field field = clazz.getDeclaredField(propertyName);
            // 取出该属性的 Result 注解
            Result resultAnn = field.getAnnotation(Result.class);
            String columnName = propertyName;
            if(resultAnn!=null){
                columnName = resultAnn.column();
            }
            // 获取 set方法 的信息
            Method method = pd.getWriteMethod();
            // 如果有 set 方法,就放入到map中
            if(method!=null) {
                propertyAndSetterMap.put(columnName,method);
            }
        }
        return propertyAndSetterMap;
    }

}

测试

定义 bean

成员变量可以不与表中列名相同,但此时要加上 @Result 注解

import top.malaoshi.jdbc.annotation.Result;

public class TNotice {

    private String id;
    @Result(column = "from_userid")
    private String fromUserid;
    @Result(column = "to_userid")
    private String toUserid;
    private String msg;

    public String getId() {
        return id;
    }

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

    public String getFromUserid() {
        return fromUserid;
    }

    public void setFromUserid(String fromUserid) {
        this.fromUserid = fromUserid;
    }

    public String getToUserid() {
        return toUserid;
    }

    public void setToUserid(String toUserid) {
        this.toUserid = toUserid;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "TNotice{" +
                "id='" + id + '\'' +
                ", fromUserid='" + fromUserid + '\'' +
                ", toUserid='" + toUserid + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }
}

测试类

import top.malaoshi.jdbc.ConnectionFactory;
import top.malaoshi.jdbc.DB;
import top.malaoshi.util.Out;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public class TestNotice {

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //东8时区
        String url="jdbc:mysql://localhost:3308/scott?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";

        Connection conn = ConnectionFactory.connect("com.mysql.cj.jdbc.Driver"
                , url
                ,"root"
                ,"");

        DB db = new DB(conn);
        String sql = "select * from t_notice";
        try {
            List<Emp> list = db.query(TNotice.class, sql);

            Out.elementSep(",\n").printList(list);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}

原文出处:/show_1IX6xkXPPodl.html