Last active
June 27, 2018 17:02
-
-
Save tlehman/bf60381413151871775c44cd8a9f934a to your computer and use it in GitHub Desktop.
Build a SQL string from a Java object using reflection, and handling nulls gracefully
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lombok.Builder; | |
import lombok.Value; | |
@Builder | |
@Value | |
public class Address { | |
private String street1; | |
private String street2; | |
private String city; | |
private String cityCode; | |
private String district; | |
private String stateCode; | |
private String postalCode; | |
private String countryCode; | |
private String countryName; | |
private String regionName; | |
} | |
// Compile using: | |
// javac -cp lombok.jar Address.java |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
import java.util.LinkedList; | |
import java.util.Optional; | |
import java.util.Objects; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
import java.lang.reflect.Method; | |
import java.lang.reflect.Field; | |
import java.lang.reflect.InvocationTargetException; | |
public class Main { | |
public static void main(String[] args) { | |
Address address = Address.builder() | |
.street1("123 Wayland Ave") | |
.city("Gotham") | |
.postalCode("80113") | |
.countryName("The Sovereign Autonomous Region of Cascadia") | |
.build(); | |
System.out.println(buildUpsertStatement(address)); | |
} | |
private static String buildUpsertStatement(Object object) { | |
Field[] fields = object.getClass().getDeclaredFields(); | |
List<String> pairs = new LinkedList<>(); | |
try { | |
for(Field field: fields) { | |
String methodName = String.format("get%s%s", | |
field.getName().substring(0,1).toUpperCase(), | |
field.getName().substring(1)); | |
Method method = object.getClass().getMethod(methodName); | |
String value = (String)method.invoke(object); | |
if(value != null) { | |
pairs.add(String.format("%s = '%s'", snake_caseify(field.getName()), value)); | |
} | |
} | |
} catch (SecurityException e) { | |
} catch (NoSuchMethodException e) { | |
} catch (IllegalArgumentException e) { | |
} catch (IllegalAccessException e) { | |
} catch (InvocationTargetException e) { | |
} | |
return pairs.stream().collect(Collectors.joining(", ")); | |
} | |
private static String snake_caseify(String camelCase) { | |
StringBuilder sb = new StringBuilder(); | |
int offset = (int)'a' - (int)'A'; | |
for(Character c: camelCase.toCharArray()) { | |
// if c is upper case | |
if((int)c >= (int)'A' && c <= (int)'Z') { | |
sb.append('_'); | |
sb.append((char)((int)c + offset)); | |
} else { | |
sb.append(c); | |
} | |
} | |
return sb.toString(); | |
} | |
} |
$ javac Main.java && java Main
street1 = '123 Wayland Ave', city = 'Gotham', postal_code = '80113', country_name = 'The Sovereign Autonomous Region of Cascadia'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you compile Address.java, then compile Main.java, the JVM classloader will load Address.class from the same directory. Note: make sure lombok.jar is in the same directory before compiling Address.