Mapping a JDBC ResultSet to an object

前端 未结 8 1267
生来不讨喜
生来不讨喜 2020-12-04 18:14

I have a user class that has 16 attributes, things such as firstname, lastname, dob, username, password etc... These are all stored in a MySQL database and when I want to re

8条回答
  •  南笙
    南笙 (楼主)
    2020-12-04 18:35

    Let's assume you want to use core Java, w/o any strategic frameworks. If you can guarantee, that field name of an entity will be equal to the column in database, you can use Reflection API (otherwise create annotation and define mapping name there)

    By FieldName

    /**
    
    Class clazz - a list of object types you want to be fetched
    ResultSet resultSet - pointer to your retrieved results 
    
    */
    
        List fields = Arrays.asList(clazz.getDeclaredFields());
        for(Field field: fields) {
            field.setAccessible(true);
        }
    
        List list = new ArrayList<>(); 
        while(resultSet.next()) {
    
            T dto = clazz.getConstructor().newInstance();
    
            for(Field field: fields) {
                String name = field.getName();
    
                try{
                    String value = resultSet.getString(name);
                    field.set(dto, field.getType().getConstructor(String.class).newInstance(value));
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
            }
    
            list.add(dto);
    
        }
    

    By annotation

    @Retention(RetentionPolicy.RUNTIME)
    public @interface Col {
    
        String name();
    }
    

    DTO:

    class SomeClass {
    
       @Col(name = "column_in_db_name")
       private String columnInDbName;
    
       public SomeClass() {}
    
       // ..
    
    }
    

    Same, but

        while(resultSet.next()) {
    
            T dto = clazz.getConstructor().newInstance();
    
            for(Field field: fields) {
                Col col = field.getAnnotation(Col.class);
                if(col!=null) {
                    String name = col.name();
                    try{
                        String value = resultSet.getString(name);
                        field.set(dto, field.getType().getConstructor(String.class).newInstance(value));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
    
            list.add(dto);
    
        }
    

    Thoughts

    In fact, iterating over all Fields might seem ineffective, so I would store mapping somewhere, rather than iterating each time. However, if our T is a DTO with only purpose of transferring data and won't contain loads of unnecessary fields, that's ok. In the end it's much better than using boilerplate methods all the way.

    Hope this helps someone.

提交回复
热议问题