Skip to content

Instantly share code, notes, and snippets.

@FLamparski
Created January 13, 2017 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FLamparski/afe73ce2782656c76bf0632de972bfe4 to your computer and use it in GitHub Desktop.
Save FLamparski/afe73ce2782656c76bf0632de972bfe4 to your computer and use it in GitHub Desktop.
BadORM - how easy can it be to write an "ORM"?
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(FIELD)
public @interface Column {
String name();
boolean id() default false;
}
public class Lol {
public static void main(String[] args) {
Person person = new Person();
person.setFirstName("Lol");
person.setLastName("What");
person.setEmailAddress("lol@what.com");
person.save(); // INSERT INTO person SET [first_name = Lol, last_name = What, email_address = lol@what.com]
}
}
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class Model {
private static class ColumnValue {
final String name;
final Object value;
final boolean isId;
ColumnValue(String n, Object v, boolean id) {
name = n;
value = v;
isId = id;
}
public String toString() {
return name + " = " + value;
}
}
private Optional<ColumnValue> getColumn(Field field) {
Column annot = field.getAnnotation(Column.class);
field.setAccessible(true);
try {
Object value = field.get(this);
return Optional.of(new ColumnValue(annot.name(), value, annot.id()));
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
return Optional.empty();
}
}
public void save() {
Class<? extends Model> me = this.getClass();
Table tblAnnot = me.getAnnotation(Table.class);
String tableName = tblAnnot.name();
Field[] myFields = me.getDeclaredFields();
List<ColumnValue> columns = Arrays.stream(myFields)
.filter(field -> field.getAnnotation(Column.class) != null)
.map(this::getColumn)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
Optional<ColumnValue> idCol = columns.stream().filter(c -> c.isId).findFirst();
List<ColumnValue> cols = columns.stream().filter(c -> !c.isId).collect(Collectors.toList());
if (!idCol.isPresent() || idCol.get().value == null) {
System.out.println("INSERT INTO " + tableName + " SET " + cols);
} else {
System.out.println("UPDATE " + tableName + " SET " + cols + " WHERE " + idCol.get());
}
}
}
@Table(name = "person")
public class Person extends Model {
@Column(id = true, name = "id")
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email_address")
private String emailAddress;
private transient boolean dirty = false;
public final Integer getId() {
return id;
}
public final String getFirstName() {
return firstName;
}
public final void setFirstName(String firstName) {
this.firstName = firstName;
this.dirty = true;
}
public final String getLastName() {
return lastName;
}
public final void setLastName(String lastName) {
this.lastName = lastName;
this.dirty = true;
}
public final String getEmailAddress() {
return emailAddress;
}
public final void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
this.dirty = true;
}
public final boolean isDirty() {
return dirty;
}
}
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
public @interface Table {
String name();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment