• 利用反射及jdbc元数据实现通用的查询方法


    ---------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.customer类:

    package com.lanqiao.javatest;

    import java.sql.Date;

    public class Customer {
    private int id;
    private String name;
    private String email;
    private Date birth;

    public Customer() {
    super();
    }

    public Customer(int id, String name, String email, Date birth) {
    super();
    this.id = id;
    this.name = name;
    this.email = email;
    this.birth = birth;
    }

    public int getId() {
    return id;
    }

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

    public String getName() {
    return name;
    }

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

    public String getEmail() {
    return email;
    }

    public void setEmail(String email) {
    this.email = email;
    }

    public Date getBirth() {
    return birth;
    }

    public void setBirth(Date birth) {
    this.birth = birth;
    }

    @Override
    public String toString() {
    return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
    }
    }

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    student类:

    package com.lanqiao.javatest;

    public class Student {

    /*
    * FlowID:int,流水号
    * type:int ,英语四六级
    * IDcard:varchar(18),身份证号码
    * examcard:varchar(15),考试证号
    * studentname:varchar(20),学生姓名
    * localtion:varchar(20),区域
    * grade:int,成绩
    */
    private int flowId;
    private int type;
    private String idCard;
    private String examCard;
    private String studentName;
    private String localtion;
    private int grade;

    public Student() {
    super();
    }

    public Student(int flowId, int type, String idCard, String examCard, String studentName, String localtion,
    int grade) {
    super();
    this.flowId = flowId;
    this.type = type;
    this.idCard = idCard;
    this.examCard = examCard;
    this.studentName = studentName;
    this.localtion = localtion;
    this.grade = grade;
    }

    public int getFlowId() {
    return flowId;
    }
    public void setFlowId(int flowId) {
    this.flowId = flowId;
    }
    public int getType() {
    return type;
    }
    public void setType(int type) {
    this.type = type;
    }
    public String getIdCard() {
    return idCard;
    }
    public void setIdCard(String idCard) {
    this.idCard = idCard;
    }
    public String getExamCard() {
    return examCard;
    }
    public void setExamCard(String examCard) {
    this.examCard = examCard;
    }
    public String getStudentName() {
    return studentName;
    }
    public void setStudentName(String studentName) {
    this.studentName = studentName;
    }
    public String getLocaltion() {
    return localtion;
    }
    public void setLocaltion(String localtion) {
    this.localtion = localtion;
    }
    public int getGrade() {
    return grade;
    }
    public void setGrade(int grade) {
    this.grade = grade;
    }

    @Override
    public String toString() {
    return "Person [flowId=" + flowId + ", type=" + type + ", idCard=" + idCard + ", examCard=" + examCard
    + ", studentName=" + studentName + ", localtion=" + localtion + ", grade=" + grade + "]";
    }

    }

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

    反射方法:

    package com.lanqiao.javatest;

    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;

    /**
    * 反射的 Utils 函数集合
    * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
    * @author Administrator
    *
    */
    public class ReflectionUtils {


    /**
    * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
    * 如: public EmployeeDao extends BaseDao<Employee, String>
    * @param clazz
    * @param index
    * @return
    */
    @SuppressWarnings("unchecked")
    public static Class getSuperClassGenricType(Class clazz, int index){
    Type genType = clazz.getGenericSuperclass();

    if(!(genType instanceof ParameterizedType)){
    return Object.class;
    }

    Type [] params = ((ParameterizedType)genType).getActualTypeArguments();

    if(index >= params.length || index < 0){
    return Object.class;
    }

    if(!(params[index] instanceof Class)){
    return Object.class;
    }

    return (Class) params[index];
    }

    /**
    * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
    * 如: public EmployeeDao extends BaseDao<Employee, String>
    * @param <T>
    * @param clazz
    * @return
    */
    @SuppressWarnings("unchecked")
    public static<T> Class<T> getSuperGenericType(Class clazz){
    return getSuperClassGenricType(clazz, 0);
    }

    /**
    * 循环向上转型, 获取对象的 DeclaredMethod
    * @param object
    * @param methodName
    * @param parameterTypes
    * @return
    */
    public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){

    for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
    try {
    //superClass.getMethod(methodName, parameterTypes);
    return superClass.getDeclaredMethod(methodName, parameterTypes);
    } catch (NoSuchMethodException e) {
    //Method 不在当前类定义, 继续向上转型
    }
    //..
    }

    return null;
    }

    /**
    * 使 filed 变为可访问
    * @param field
    */
    public static void makeAccessible(Field field){
    if(!Modifier.isPublic(field.getModifiers())){
    field.setAccessible(true);
    }
    }

    /**
    * 循环向上转型, 获取对象的 DeclaredField
    * @param object
    * @param filedName
    * @return
    */
    public static Field getDeclaredField(Object object, String filedName){

    for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
    try {
    return superClass.getDeclaredField(filedName);
    } catch (NoSuchFieldException e) {
    //Field 不在当前类定义, 继续向上转型
    }
    }
    return null;
    }

    /**
    * 直接调用对象方法, 而忽略修饰符(private, protected)
    * @param object
    * @param methodName
    * @param parameterTypes
    * @param parameters
    * @return
    * @throws InvocationTargetException
    * @throws IllegalArgumentException
    */
    public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
    Object [] parameters) throws InvocationTargetException{

    Method method = getDeclaredMethod(object, methodName, parameterTypes);

    if(method == null){
    throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
    }

    method.setAccessible(true);

    try {
    return method.invoke(object, parameters);
    } catch(IllegalAccessException e) {
    System.out.println("不可能抛出的异常");
    }

    return null;
    }

    /**
    * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
    * @param object
    * @param fieldName
    * @param value
    */
    public static void setFieldValue(Object object, String fieldName, Object value){
    Field field = getDeclaredField(object, fieldName);

    if (field == null)
    throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");

    makeAccessible(field);

    try {
    field.set(object, value);
    } catch (IllegalAccessException e) {
    System.out.println("不可能抛出的异常");
    }
    }

    /**
    * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
    * @param object
    * @param fieldName
    * @return
    */
    public static Object getFieldValue(Object object, String fieldName){
    Field field = getDeclaredField(object, fieldName);

    if (field == null)
    throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");

    makeAccessible(field);

    Object result = null;

    try {
    result = field.get(object);
    } catch (IllegalAccessException e) {
    System.out.println("不可能抛出的异常");
    }

    return result;
    }
    }

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

    实现主方法:

    package com.lanqiao.javatest;

    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.Driver;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Properties;

    import javax.management.ReflectionException;
    import javax.swing.text.FieldView;

    import org.junit.Test;

    import com.mysql.jdbc.ResultSetMetaData;
    import com.mysql.jdbc.Statement;

    /*
    * 建立一个统一的方法可以引用任何类的对象,实现数据库数据的处理
    * 通过一个对象获取任何一个数据库数据
    * */
    public class TestPreparedStatement {


    private static final Class<Customer> Customer = null;
    private static final Class<Student> Student = null;

    =================================================================================
    //连接数据库方法
    public static Connection getConnection() throws Exception{

    //四连接数据必不可少的
    String driverClass=null;
    String jdbcUrl=null;
    String user=null;
    String password=null;

    InputStream in=
    TestPreparedStatement.class.getClassLoader().getResourceAsStream("jdbc.properties");
    //其中getClass与TestConnection.classh互换使用
    Properties properties=new Properties();
    properties.load(in);

    driverClass=properties.getProperty("driver");
    jdbcUrl=properties.getProperty("jdbcUrl");
    user=properties.getProperty("user");
    password=properties.getProperty("password");

    // System.out.println(driverClass+jdbcUrl+user+password);
    Driver driver=(Driver)Class.forName(driverClass).newInstance();
    Properties info=new Properties();
    info.put("user", "root");
    info.put("password", "lxn123");
    Connection connection=driver.connect(jdbcUrl, info);
    return connection;
    }
    //测试类
    public static void testGetConn() throws Exception{
    System.out.println(getConnection());
    }

    ====================================================================================

    关闭资源的方法

    public void close(Connection connection,
    PreparedStatement preparedStatement,ResultSet resultSet) throws Exception{
    if (resultSet!=null) {
    resultSet.close();
    }
    if (preparedStatement!=null) {
    preparedStatement.close();
    }
    if (connection!=null) {
    connection.close();
    }
    }

    ===========================================================================================
    //student类获取数据
    public Student getStudent(String sql,Object...args) throws Exception{
    Student student=null;
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    for(int i=0;i<args.length;i++){
    preparedStatement.setObject(i+1, args[i]);
    }
    resultSet=preparedStatement.executeQuery();
    //resultset里面的nest()方法,把查询到的数据,student获取
    if(resultSet.next()){
    student=new Student();
    student.setFlowId(resultSet.getInt(1));
    student.setType(resultSet.getInt(2));
    student.setIdCard(resultSet.getString(3));
    student.setExamCard(resultSet.getString(4));
    student.setStudentName(resultSet.getString(5));
    student.setLocaltion(resultSet.getString(6));
    student.setGrade(resultSet.getInt(7));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }

    return student;

    }

    ========================================================================================
    //Customer类获取数据
    public Customer getCustomer(String sql,Object...args) throws Exception{
    Customer customer=null;
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    for(int i=0;i<args.length;i++){
    preparedStatement.setObject(i+1, args[i]);
    }
    resultSet=preparedStatement.executeQuery();
    //resultset里面的nest()方法,把查询到的数据,student获取
    if(resultSet.next()){
    customer=new Customer();
    customer.setId(resultSet.getInt(1));
    customer.setName(resultSet.getString(2));
    customer.setEmail(resultSet.getString(3));
    customer.setBirth(resultSet.getDate(4));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }

    return customer;
    }
    =======================================================================================
    //一个通用的方法的模板:可利用反射,实现数据库查询,插入值
    public <T> T getT(Class <T> clazz,String sql,Object...args) throws Exception{
    T entity=null;

    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    for(int i=0;i<args.length;i++){
    preparedStatement.setObject(i+1, args[i]);
    }
    resultSet=preparedStatement.executeQuery();

    //得到ResultSetMetaDate对象,获取数据库中的列和列名
    ResultSetMetaData rsmd=(ResultSetMetaData) resultSet.getMetaData();

    //创建一个Map<String,Object>对象,键:sql查询列的别名;值:列的值;
    Map<String, Object> values=new HashMap<String, Object>();

    //处理结果集,利用ResultSetMetaDate的方法,填充对应的map的对象
    while(resultSet.next()){
    //方法getColumnCount(),是获取ResultSetMetaDate对象获取数据库属性的个数
    for(int i=0;i<rsmd.getColumnCount();i++){
    String columnLabel=rsmd.getColumnLabel(i+1);//获取属性,它是字符串
    Object columnValues=resultSet.getObject(columnLabel);
    // System.out.println(columnValues);
    values.put(columnLabel, columnValues);
    }
    }

    //map不为空,利用反射创建clazz的对象
    if (values.size()>0) {
    entity=clazz.newInstance();

    //遍历map,利用反射class对应的对象的属性赋值
    for (Map.Entry<String, Object> entry: values.entrySet()) {
    String fieldName=entry.getKey();
    Object fieldValues=entry.getValue();
    System.out.println(fieldName+":"+fieldValues);
    //反射获取属性,并修改 xxxx(entity,fieldName,fieldValues);
    ReflectionUtils.setFieldValue(entity, fieldName, fieldValues);
    }

    }

    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }
    return entity;
    }
    //测试getT()方法
    @Test
    public void testGetT() throws Exception{
    String sql="select id,name,email,birth from customer where id=?";
    Customer customer=getT(Customer.class,sql,2);
    System.out.println(customer);

    String sql1="SELECT flow_id flowId,type,id_card idCard,"
    + "exam_card examCard,student_name studentName ,"
    + "localtion,grade FROM test WHERE flow_id=?;";
    Student student=getT(Student.class,sql1,2);
    System.out.println(student);
    }
    =======================================================================================
    //ResultSetMetaDate,是描述ResultSet的元数据对象,即从中可以获取到结果集中有多少列,列名是。。。。。
    //用法:调用ResultSet的getMetaDate()方法,
    //好用的方法:int getColumnCount(),sql语句中包含那些列
    //String getColumnLabel(int column):获取指定列的别名,其中索引从1开始

    public void testResultSetMetaDate() throws Exception{
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    String sql="SELECT flow_id flowid,type,id_card idcard,"
    + "exam_card examcard,student_name studentname ,"
    + "localtion,grade FROM test WHERE flow_id=?;";
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    preparedStatement.setInt(1, 2);
    resultSet=preparedStatement.executeQuery();

    Map<String, Object> values=new HashMap<String, Object>();

    //1.得到ResultSetMetaDate对象,获取数据库中的列和列名
    ResultSetMetaData rsmd= (ResultSetMetaData) resultSet.getMetaData();
    while(resultSet.next()){
    //2.{}打印每一列的列名
    for(int i=0;i<rsmd.getColumnCount();i++){
    String columnLabel=rsmd.getColumnLabel(i+1);//获取指定列的别名
    Object columnValue=resultSet.getObject(columnLabel);//获取指定列的值

    values.put(columnLabel, columnValue);

    }
    }
    System.out.println(values);

    //反射获取
    Class clazz=Student.class;
    Object obj=clazz.newInstance();
    //强制for循环
    for(Map.Entry<String, Object> entry: values.entrySet()){
    String fieldName=entry.getKey();
    Object fieldValues=entry.getValue();
    System.out.println(fieldName+":"+fieldValues);
    }


    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }
    }

    }

    数据库图片:

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    微信小程序TodoList
    C语言88案例-找出数列中的最大值和最小值
    C语言88案例-使用指针的指针输出字符串
  • 原文地址:https://www.cnblogs.com/lxnlxn/p/5769911.html
Copyright © 2020-2023  润新知