Created
March 21, 2018 06:18
-
-
Save Brutt/eb051356917294f9caa76cab8a059132 to your computer and use it in GitHub Desktop.
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.lang.annotation.ElementType; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.lang.annotation.Target; | |
@Retention(RetentionPolicy.RUNTIME) | |
@Target(ElementType.FIELD) | |
public @interface Column { | |
String name(); | |
int primary() default 0; | |
int updatable() default 0; | |
} |
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.lang.reflect.Field; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
public class Dao { | |
private static String getTableName(Class clazz){ | |
if (!clazz.isAnnotationPresent(Table.class)) { | |
throw new IllegalArgumentException("Annotation @Table is not present"); | |
} | |
Table annotation = (Table) clazz.getAnnotation(Table.class); | |
return annotation.name().isEmpty() ? clazz.getName() : annotation.name(); | |
} | |
static String save(Object obj) throws Exception { | |
StringBuilder query = new StringBuilder("INSERT INTO "); | |
Class clazz = obj.getClass(); | |
// add table name to query | |
String tableName = getTableName(clazz); | |
query.append(tableName); | |
query.append(" ("); | |
// collect column names and values of corresponding fields | |
List<String> columnNames = new ArrayList<>(); | |
List<Object> valuesToInsert = new ArrayList<>(); | |
for (Field field : clazz.getDeclaredFields()) { | |
Column columnAnnotation = field.getAnnotation(Column.class); | |
if (columnAnnotation != null) { | |
// get column name | |
String columnName = columnAnnotation.name().isEmpty() ? | |
field.getName() : columnAnnotation.name(); | |
columnNames.add(columnName); | |
// get value for this column | |
field.setAccessible(true); | |
Object columnValue = field.get(obj); | |
valuesToInsert.add(columnValue); | |
field.setAccessible(false); | |
} | |
} | |
// just for info (DON'T USE SUCH TECHNIQUE FOR DEBUG PURPOSES!!!) | |
printColumnNamesAndValues(columnNames, valuesToInsert); | |
// generate rest of query | |
appendColumnNames(query, columnNames); | |
query.append(")"); | |
appendColumnValues(query, valuesToInsert); | |
return query.toString(); | |
} | |
private static void printColumnNamesAndValues(List<String> columnNames, List<Object> valuesToInsert) { | |
System.out.println("Column names and values list:"); | |
Iterator<String> namesIterator = columnNames.iterator(); | |
Iterator<Object> valuesIterator = valuesToInsert.iterator(); | |
while (namesIterator.hasNext()) { | |
System.out.println(namesIterator.next() + " -> " + valuesIterator.next()); | |
} | |
} | |
private static void appendColumnNames(StringBuilder query, List<String> columnNames) { | |
for (String columnName : columnNames) { | |
query.append(columnName); | |
query.append(", "); | |
} | |
// remove last ", " | |
query.setLength(query.length() - 2); | |
} | |
private static void appendColumnValues(StringBuilder query, List<?> columnValues) { | |
query.append(" VALUES ("); | |
for (Object columnValue : columnValues) { | |
query.append(columnValue); | |
query.append(", "); | |
} | |
// remove last ", " | |
query.setLength(query.length() - 2); | |
query.append(");"); | |
} | |
// TODO: Generate SQL to get all instances of clazz from DB | |
public static String getAll(Class clazz) { | |
StringBuilder query = new StringBuilder("SELECT "); | |
String tableName = getTableName(clazz); | |
// collect column names and values of corresponding fields | |
List<String> columnNames = new ArrayList<>(); | |
List<Object> valuesToInsert = new ArrayList<>(); | |
for (Field field : clazz.getDeclaredFields()) { | |
Column columnAnnotation = field.getAnnotation(Column.class); | |
if (columnAnnotation != null) { | |
// get column name | |
String columnName = columnAnnotation.name().isEmpty() ? | |
field.getName() : columnAnnotation.name(); | |
columnNames.add(columnName); | |
} | |
} | |
// generate rest of query | |
appendColumnNames(query, columnNames); | |
query.append(" FROM "); | |
query.append(tableName); | |
query.append(";"); | |
// just for info (DON'T USE SUCH TECHNIQUE FOR DEBUG PURPOSES!!!) | |
//printColumnNamesAndValues(columnNames, valuesToInsert); | |
return query.toString(); | |
} | |
// TODO: Generate SQL which can remove Object of clazz by it's id | |
// Hint: you will probably need to indicate somehow that current @Column is primary key in table | |
public static String deleteById(Object id, Class clazz) { | |
StringBuilder query = new StringBuilder("DELETE FROM "); | |
String tableName = getTableName(clazz); | |
query.append(tableName); | |
query.append(" WHERE "); | |
for (Field field : clazz.getDeclaredFields()) { | |
Column columnAnnotation = field.getAnnotation(Column.class); | |
if ((columnAnnotation != null) && (columnAnnotation.primary() == 1)) { | |
query.append(columnAnnotation.name()); | |
query.append(" = ").append(id).append(";"); | |
break; | |
} | |
} | |
return query.toString(); | |
} | |
// TODO: Generate SQL which can Update Object representation in DB | |
public static String updateSalaryForIdByRate(Class clazz, int id, int rate) { | |
StringBuilder query = new StringBuilder("UPDATE "); | |
String tableName = getTableName(clazz); | |
query.append(tableName); | |
query.append(" SET "); | |
String strId = ""; | |
String strSalary = ""; | |
for (Field field : clazz.getDeclaredFields()) { | |
Column columnAnnotation = field.getAnnotation(Column.class); | |
if (columnAnnotation != null) { | |
if (columnAnnotation.primary() == 1) { | |
strId = columnAnnotation.name(); | |
} | |
if (columnAnnotation.updatable() == 1) { | |
strSalary = columnAnnotation.name(); | |
} | |
} | |
} | |
query.append(strSalary).append(" = ").append(strSalary).append(" * ").append(rate).append(" WHERE ").append(strId).append(" = ").append(id).append(";"); | |
return query.toString(); | |
} | |
} |
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 org.junit.Test; | |
import static org.junit.Assert.assertEquals; | |
public class DaoTest { | |
@Test | |
public void testSave() throws Exception { | |
User user = new User(1, "Tolik", 100.0d); | |
String expectedQuery = "INSERT INTO dan_user (id, name, sal) VALUES (1, Tolik, 100.0);"; | |
String actualQuery = Dao.save(user); | |
assertEquals(expectedQuery, actualQuery); | |
} | |
@Test | |
public void testGetAll() throws Exception { | |
String expectedQuery = "SELECT id, name, sal FROM dan_user;"; | |
String actualQuery = Dao.getAll(User.class); | |
assertEquals(expectedQuery, actualQuery); | |
} | |
@Test | |
public void testDeleteById() throws Exception { | |
String expectedQuery = "DELETE FROM dan_user WHERE id = 1;"; | |
String actualQuery = Dao.deleteById(1, User.class); | |
assertEquals(expectedQuery, actualQuery); | |
} | |
@Test | |
public void testUpdate() throws Exception { | |
String expectedQuery = "UPDATE dan_user SET sal = sal * 2 WHERE id = 1;"; | |
String actualQuery = Dao.updateSalaryForIdByRate(User.class, 1, 2); | |
assertEquals(expectedQuery, actualQuery); | |
} | |
} |
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
@Table(name="dan_user") | |
public class User { | |
@Column(name="id", primary = 1) | |
private int id; | |
@Column(name="name") | |
private String name; | |
@Column(name="sal", updatable = 1) | |
private double salary; | |
public User(int id, String name, double salary) { | |
this.id = id; | |
this.name = name; | |
this.salary = salary; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment