DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Projections/DTOs in Spring Data R2DBC
  • Testcontainers With Kotlin and Spring Data R2DBC
  • JQueue: A Library to Implement the Outbox Pattern
  • API Streaming Response with Oracle and Java

Trending

  • Top Book Picks for Site Reliability Engineers
  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 1
  • Building Enterprise-Ready Landing Zones: Beyond the Initial Setup
  • Revolutionizing Financial Monitoring: Building a Team Dashboard With OpenObserve
  1. DZone
  2. Coding
  3. Languages
  4. JDBC ResultSet and Generic Class List Using Java Reflection Annotations

JDBC ResultSet and Generic Class List Using Java Reflection Annotations

Check out this post to learn more about Java reflection annotations to query the JDBC database.

By 
Naveen Yalla user avatar
Naveen Yalla
·
Apr. 17, 19 · Tutorial
Likes (15)
Comment
Save
Tweet
Share
54.3K Views

Join the DZone community and get the full member experience.

Join For Free

When working with web projects, the frequency required to query the database and get results is quite high. This involves a lot of code in your DAO classes and will affect readability and connection backlogs.

If we observe closely, its code is static, except for the Model class type and query in it.

For example, if we need Employee details, we will create the code with Connection, Statement, ResultSet, and closing blocks. If we require Department details, we need to do the same as before, except we change the List type to Department and the query we run through it.

Based on this experience, I came across one article by Roberto Benitez on this blog.

Please go through the above article and come back here to see how I used it to serve the previously discussed problems.

To implement, check out the steps below:

  1. Create a custom annotation
  2. Create a Model class, which contains mapping fields to the ResultSet column names with the created annotation.
  3. Call the ResultSet 
  4. Load the ResultSet for each value into the object
  5. Check for the Primitive type
  6. Auto-box the Primitive type class.

Create the of Custom Annotation

Here is how we created the custom annotation:

@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String columnName();

}


Creation of the Model Class

Here is how we created the Model class, which contains mapping fields for the ResultSet column names with the created annotation:

public Class Employee{
@DBTable(columnName ="emp_id")
private int empId;
@DBTable(columnName ="emp_name")
private String empName;

//Getters and setters
//Default constructor // mandatory
}


Calling the ResultSet

 String query =”select emp_id,emp_name from employee”  
In the above query, column names should be equal to the @DBTable annotation column names.

public <T> List<T> selectQuery(Class<T> type, query) throws SQLException {
    List<T> list = new ArrayList<T>();
    try (Connection conn = dataSource.getConnection()) {
        try (Statement stmt = conn.createStatement()) {
            try (ResultSet rst = stmt.executeQuery(query)) {
                while (rst.next()) {
                    T t = type.newInstance();
                    loadResultSetIntoObject(rst, t);// Point 4
                    list.add(t);
                }
            }
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("Unable to get the records: " + e.getMessage(), e);
        }
    }
    return list;


Loading the ResultSet for Each Value Into the Object

This looks quite interesting. Here's how Java annotations help us:

public static void loadResultSetIntoObject(ResultSet rst, Object object)
        throws IllegalArgumentException, IllegalAccessException, SQLException {
    Class<?> zclass = object.getClass();
    for (Field field : zclass.getDeclaredFields()) {
        field.setAccessible(true);
        DBTable column = field.getAnnotation(DBTable.class);
        Object value = rst.getObject(column.columnName());
        Class<?> type = field.getType();
        if (isPrimitive(type)) {//check primitive type(Point 5)
            Class<?> boxed = boxPrimitiveClass(type);//box if primitive(Point 6)
            value = boxed.cast(value);
        }
        field.set(object, value);
    }
}


Check for Primitive Types

This will return a Primitive type:

public static boolean isPrimitive(Class<?> type) {
    return (type == int.class || type == long.class || type == double.class || type == float.class
            || type == boolean.class || type == byte.class || type == char.class || type == short.class);
}


Auto-Boxing to Primitive Type Class

Here is the code for how we implemented this:

public static Class<?> boxPrimitiveClass(Class<?> type) {
    if (type == int.class) {
        return Integer.class;
    } else if (type == long.class) {
        return Long.class;
    } else if (type == double.class) {
        return Double.class;
    } else if (type == float.class) {
        return Float.class;
    } else if (type == boolean.class) {
        return Boolean.class;
    } else if (type == byte.class) {
        return Byte.class;
    } else if (type == char.class) {
        return Character.class;
    } else if (type == short.class) {
        return Short.class;
    } else {
        String string = "class '" + type.getName() + "' is not a primitive";
        throw new IllegalArgumentException(string);
    }
}


We have made all arrangements to call our magic method with the help of Roberto Benitez. Now, we will try to call this method and see the magic behind it all.

Use Cases

By usingselectQuery, this annotation can provide whatever class name you want from the list. You just need to provide the query that needs to run against the DB.

Use case 1: I want all the details of the student: selectQuery(Student.class, "SELECT * FROM STUDENT") 

Use case 2: I want all of the details of the Department: selectQuery(Department.class, "SELECT * FROM DEPARTMENT")  

Use case 3: I want all of the students in the Department and their enrolled courses. Quite a bit overhead, right? Dont worry too much. The solution is as simple as those mentioned above. Just make the Model class with as many fields as you want, but make sure your query (bit joins) return all fields in the Model class.

Note: Please make sure the @columnName annotation value name of the fields for your Model class and column names of the DB result are the same. Keep whatever name you want for the fields.

PS: I am not concerned about the performance, as of now, because I use this as a Helper method, which I want to use frequently with less code.

Happy coding!

Annotation Database Java (programming language) Use case

Opinions expressed by DZone contributors are their own.

Related

  • Projections/DTOs in Spring Data R2DBC
  • Testcontainers With Kotlin and Spring Data R2DBC
  • JQueue: A Library to Implement the Outbox Pattern
  • API Streaming Response with Oracle and Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!