diff options
17 files changed, 321 insertions, 224 deletions
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java index a2bb5a6..9cb85e9 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java @@ -33,10 +33,10 @@ import java.util.TreeMap; import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.Utils.writeFile; -import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; -import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; +import static io.trygvis.persistence.FieldMirror.GetterType; +import static io.trygvis.persistence.FieldMirror.SetterType; import static io.trygvis.persistence.TypeHandler.StringEnumTypeHandler; import static java.lang.Character.isUpperCase; import static java.lang.String.format; @@ -91,8 +91,8 @@ public class EntityHandler extends AbstractHandler { name = value; } } - sqlUnit.setName(name); sqlUnit.setPackageName(packageElement.getQualifiedName().toString()); + sqlUnit.setName(name); } public void recordEntity(TypeElement element) throws Exception { @@ -229,7 +229,8 @@ public class EntityHandler extends AbstractHandler { ExecutableElement getter, ExecutableElement setter) { // TODO: check the setter for annotations too // TODO: check for transient and @Transient - FieldMirror.AccessorType accessorType; + final SetterType setterType; + final GetterType getterType; TypeRef type; Element element; String javaName; @@ -240,7 +241,13 @@ public class EntityHandler extends AbstractHandler { if (var.getModifiers().contains(Modifier.STATIC)) { return null; } - accessorType = FIELD; + boolean isFinal = var.getModifiers().contains(Modifier.FINAL); + if (isFinal) { + setterType = SetterType.CONSTRUCTOR; + } else { + setterType = setter != null ? SetterType.METHOD : SetterType.FIELD; + } + getterType = GetterType.FIELD; type = new TypeRef(var.asType()); element = types.asElement(var.asType()); javaName = var.getSimpleName().toString(); @@ -253,9 +260,9 @@ public class EntityHandler extends AbstractHandler { if (setter == null) { // Skipping fields is closer to what hibernate does. return null; -// throw new CompilerException(getter, "Missing setter for getter: " + getter.getSimpleName()); } - accessorType = METHOD; + setterType = SetterType.METHOD; + getterType = GetterType.METHOD; type = new TypeRef(getter.getReturnType()); element = types.asElement(getter.getReturnType()); id = isId(getter); @@ -291,11 +298,11 @@ public class EntityHandler extends AbstractHandler { System.out.println("typeHandler.typeName() = " + typeHandler.typeName()); // TODO: check for configuration conflict notNull = !typeHandler.nullable; - field = new FieldMirror(PRIMITIVE, accessorType, type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(PRIMITIVE, setterType, getterType, type, javaName, sqlName, id, notNull, unique); } else if (generatorConfiguration.hasTypeHandler(type)) { throw new CompilerException(var, "Missing type handler for type: " + type.fqName); } else { - field = new FieldMirror(REFERENCE, accessorType, type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(REFERENCE, setterType, getterType, type, javaName, sqlName, id, notNull, unique); } return field; } @@ -309,6 +316,7 @@ public class EntityHandler extends AbstractHandler { for (EntityMirror entity : sqlUnit.getEntities().values()) { DaoGenerator daoGenerator = new DaoGenerator(generatorConfiguration, sqlUnit, entity); writeFile(processingEnv, daoGenerator.generate(), sqlUnit.element(entity)); + writeFile(processingEnv, daoGenerator.generateRow(), sqlUnit.element(entity)); } } catch (CompilerException | InternalErrorException e) { // Ignore any exceptions if we had an error from before diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java index 1272759..24cacf4 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java @@ -28,8 +28,6 @@ import java.util.HashSet; import java.util.Set; import static io.trygvis.container.compiler.Utils.writeFile; -import static io.trygvis.persistence.generators.EntityManagerFactoryGenerator.generateEntityManagerFactory; -import static io.trygvis.persistence.generators.EntityManagerGenerator.generateEntityManager; import static io.trygvis.persistence.generators.SequencesGenerator.generateSequences; import static io.trygvis.persistence.generators.SqlSessionGenerator.generateSqlSession; import static io.trygvis.persistence.generators.SqlSessionFactoryGenerator.generateSqlSessionFactory; @@ -146,8 +144,8 @@ public class MyProcessor implements Processor { entityHandler.phase3(hadErrors); writeFile(processingEnv, generateSequences(unit), null); - writeFile(processingEnv, generateEntityManagerFactory(unit), null); - writeFile(processingEnv, generateEntityManager(unit), null); +// writeFile(processingEnv, generateEntityManagerFactory(unit), null); +// writeFile(processingEnv, generateEntityManager(unit), null); writeFile(processingEnv, generateSqlSession(unit), null); writeFile(processingEnv, generateSqlSessionFactory(unit), null); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java index e41fbb8..717715e 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java @@ -15,6 +15,7 @@ public class SqlUnitModel { private Map<SequenceMirror, Element> sequenceElements = new TreeMap<>(); private String packageName; private String name; + public TypeRef sessionType; public String getPackageName() { if (packageName == null) { @@ -34,6 +35,7 @@ public class SqlUnitModel { public void setName(String name) { this.name = name; + sessionType = new TypeRef(packageName + "." + name + "SqlSession"); } // ----------------------------------------------------------------------- diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java index 5d69fc0..3478581 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java @@ -24,6 +24,10 @@ import static org.apache.commons.lang.StringUtils.stripEnd; public class Utils { public static final String EOL = System.getProperty("line.separator"); + public static String toFieldName(TypeRef type) { + return toFieldName(type.className); + } + public static String toFieldName(String s) { if (s.length() < 1) { return s.toLowerCase(); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java index f63c4b2..85523dc 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java @@ -1,23 +1,17 @@ package io.trygvis.persistence; -import io.trygvis.container.compiler.NotImplementedException; -import io.trygvis.container.compiler.SqlUnitModel; import io.trygvis.container.compiler.model.TypeRef; import java.util.ArrayList; import java.util.List; -import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; -import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static java.lang.String.format; -import static org.apache.commons.lang.StringUtils.join; - public class EntityMirror implements Comparable<EntityMirror> { public final GeneratorConfiguration generatorConfiguration; public final List<FieldMirror> fields = new ArrayList<>(); public final List<FieldMirror> idFields = new ArrayList<>(); public final TypeRef type; public final String tableName; + public final TypeRef rowType; public final TypeRef daoType; public final TypeRef utilsType; public TypeRef idType; @@ -27,6 +21,7 @@ public class EntityMirror implements Comparable<EntityMirror> { this.type = type; this.tableName = tableName; + this.rowType = new TypeRef(type.plainName + "Row"); this.daoType = new TypeRef(type.plainName + "Dao").args(type.args); this.utilsType = new TypeRef(type.plainName + "Dao.Utils").args(type.args); } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java index 5a2d221..dd759ef 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java @@ -4,14 +4,14 @@ import io.trygvis.container.compiler.model.TypeRef; import static io.trygvis.container.compiler.Utils.toGetterName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; -import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; /** * TODO: a single field might have to be mapped to multiple sql columns. */ public class FieldMirror { public final FieldType fieldType; - public final AccessorType accessorType; + public final SetterType setterType; + public final GetterType getterType; public final TypeRef type; public final String javaName; public final String sqlName; @@ -24,15 +24,22 @@ public class FieldMirror { REFERENCE, } - public enum AccessorType { + public enum SetterType { + CONSTRUCTOR, FIELD, METHOD, } - public FieldMirror(FieldType fieldType, AccessorType accessorType, TypeRef type, String javaName, String sqlName, - boolean id, boolean notNull, boolean unique) { + public enum GetterType { + FIELD, + METHOD, + } + + public FieldMirror(FieldType fieldType, SetterType setterType, GetterType getterType, TypeRef type, String javaName, + String sqlName, boolean id, boolean notNull, boolean unique) { this.fieldType = fieldType; - this.accessorType = accessorType; + this.setterType = setterType; + this.getterType = getterType; this.type = type; this.javaName = javaName; this.sqlName = sqlName; @@ -50,7 +57,7 @@ public class FieldMirror { } private String fieldAccessor(String o) { - if (accessorType == FIELD) { + if (getterType == GetterType.FIELD) { return o + "." + javaName; } return o + "." + toGetterName(javaName) + "()"; @@ -60,7 +67,8 @@ public class FieldMirror { public String toString() { return "FieldMirror{" + "fieldType=" + fieldType + - ", accessorType=" + accessorType + + ", setterType=" + setterType + + ", getterType=" + getterType + ", type=" + type + ", javaName='" + javaName + '\'' + ", sqlName='" + sqlName + '\'' + diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java index d9ac482..c4367fd 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java @@ -5,6 +5,7 @@ import io.trygvis.container.compiler.SqlUnitModel; import io.trygvis.container.compiler.model.ClassG; import io.trygvis.container.compiler.model.Constructor; import io.trygvis.container.compiler.model.FieldRef; +import io.trygvis.container.compiler.model.Imports; import io.trygvis.container.compiler.model.MethodRef; import io.trygvis.container.compiler.model.Parameters; import io.trygvis.container.compiler.model.TypeRef; @@ -16,16 +17,16 @@ import io.trygvis.persistence.sql.SqlDao; import io.trygvis.persistence.sql.SqlEntityMeta; import java.io.IOException; -import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import static io.trygvis.container.compiler.Utils.toJavaString; +import static io.trygvis.container.compiler.Utils.*; import static io.trygvis.container.compiler.model.TypeRef.VOID; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; +import static io.trygvis.persistence.FieldMirror.SetterType; import static java.lang.String.format; import static java.lang.reflect.Modifier.PUBLIC; import static org.apache.commons.lang.StringUtils.join; @@ -44,15 +45,15 @@ public class DaoGenerator { public ClassG generate() throws IOException { ClassG g = new ClassG(PUBLIC, entity.daoType). - extendsType(new TypeRef(SqlDao.class).args(entity.idType, entity.type)); + extendsType(new TypeRef(SqlDao.class).args(entity.idType, entity.type, unit.sessionType, entity.rowType)); Parameters p = new Parameters(); - Parameters.ParameterRef c = p.addParameter(new TypeRef(Connection.class), "c"); - g.add(new Constructor(p, "super(" + c.name + ");")); + Parameters.ParameterRef session = p.addParameter(unit.sessionType, "session"); + g.add(new Constructor(p, "super(" + session.name + ");")); TypeRef stringType = g.imports.add(String.class); TypeRef sqlEntityDescType = g.imports.add(SqlEntityMeta.class); TypeRef sqlException = g.imports.add(SQLException.class); - TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type); +// TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type); FieldRef createTableSql = g.addPublicStaticFinalField(stringType, "createTableSql"). value(toJavaString(createTableSql())); @@ -72,22 +73,17 @@ public class DaoGenerator { ")"; g.addPublicStaticFinalField(sqlEntityDescType, "desc").value(desc); DaoUtilsGenerator daoUtil = new DaoUtilsGenerator(unit, generatorConfiguration, entity); - g.addInnerClass(daoUtil.queryType(g.imports)); +// g.addInnerClass(daoUtil.queryType(g.imports)); g.addInnerClass(daoUtil.utils()); - { - p = new Parameters(); - Parameters.ParameterRef rs = p.addParameter(new TypeRef(ResultSet.class), "rs"); - g.add(new MethodRef(PUBLIC, entity.type, "fromResultSet", p, - "return Utils.fromResultSet" + entity.type.className + "(" + rs.name + ");"). - exception(sqlException)); - } + g.add(newRow(g.imports)); + g.add(newEntity(g.imports)); { p = new Parameters(); Parameters.ParameterRef entity = p.addParameter(this.entity.type, "entity"); g.add(new MethodRef(PUBLIC, VOID, "insert", p, - "Utils.insert" + this.entity.type.className + "(super.c, " + entity.name + ");"). + "Utils.insert" + this.entity.type.className + "(super.session.c, " + entity.name + ");"). exception(sqlException)); } @@ -95,23 +91,17 @@ public class DaoGenerator { p = new Parameters(); Parameters.ParameterRef id = p.addParameter(entity.idType, "id"); g.add(new MethodRef(PUBLIC, entity.type, "selectById", p, - "return Utils.select" + entity.type.className + "ById(super.c, " + id.name + ");"). + "return Utils.select" + entity.type.className + "ById(super.session.c, " + id.name + ");"). exception(sqlException)); } - { - p = new Parameters(); - Parameters.ParameterRef where = p.addParameter(stringType, "where"); - g.add(new MethodRef(PUBLIC, listOfEntityType, "selectWhere", p, - "return Utils.select" + entity.type.className + "Where(super.c, " + where.name + ");"). - exception(sqlException)); - } + g.add(selectWhere(g.imports)); { p = new Parameters(); Parameters.ParameterRef entity = p.addParameter(this.entity.type, "entity"); g.add(new MethodRef(PUBLIC, VOID, "delete", p, - "Utils.delete" + this.entity.type.className + "(super.c, " + entity.name + ");"). + "Utils.delete" + this.entity.type.className + "(super.session.c, " + entity.name + ");"). exception(sqlException)); } @@ -119,7 +109,7 @@ public class DaoGenerator { p = new Parameters(); Parameters.ParameterRef id = p.addParameter(entity.idType, "id"); g.add(new MethodRef(PUBLIC, VOID, "deleteById", p, - "Utils.delete" + entity.type.className + "ById(super.c, " + id.name + ");"). + "Utils.delete" + entity.type.className + "ById(super.session.c, " + id.name + ");"). exception(sqlException)); } @@ -127,13 +117,35 @@ public class DaoGenerator { p = new Parameters(); Parameters.ParameterRef entity = p.addParameter(this.entity.type, "entity"); g.add(new MethodRef(PUBLIC, VOID, "update", p, - "Utils.update" + this.entity.type.className + "(super.c, " + entity.name + ");"). + "Utils.update" + this.entity.type.className + "(super.session.c, " + entity.name + ");"). exception(sqlException)); } return g; } + public ClassG generateRow() { + ClassG g = new ClassG(PUBLIC, entity.rowType); + + Parameters parameters = new Parameters(); + List<String> body = new ArrayList<>(); + for (FieldMirror field : entity.fields) { + TypeRef type; + if (field.fieldType == PRIMITIVE) { + type = field.type; + } else { + EntityMirror entity = unit.getEntities().get(field.type); + type = entity.getIdField().type; + } + + FieldRef f = g.addPublicFinalField(type, field.javaName); + Parameters.ParameterRef p = parameters.addParameter(type, field.javaName); + body.add("this." + f.name + " = " + p.name + ";"); + } + g.add(new Constructor(parameters, body)); + return g; + } + public String createTableSql() { List<String> columns = new ArrayList<>(); for (FieldMirror field : entity.fields) { @@ -203,6 +215,98 @@ public class DaoGenerator { return "DELETE FROM " + entity.tableName + " WHERE " + join(ss, " AND ") + ";"; } + public MethodRef selectWhere(Imports imports) { + TypeRef sqlExceptionType = imports.add(SQLException.class); + Parameters p = new Parameters(); + Parameters.ParameterRef where = p.addParameter(imports.add(String.class), "where"); + List<String> body = new ArrayList<>(); + body.add("String sql = \"SELECT \" + desc.defaultFields + \" FROM " + entity.tableName + " WHERE \" + " + where.name + " + \";\";"); + body.add("return runQuery(sql);"); + + TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type); + return new MethodRef(PUBLIC, listOfEntityType, "selectWhere", p, body). + exception(sqlExceptionType); + } + + public MethodRef newRow(Imports g) { + TypeRef rsType = g.add(ResultSet.class); + Parameters p = new Parameters(); + Parameters.ParameterRef rs = p.addParameter(rsType, "rs"); + + List<String> body = new ArrayList<>(); + List<String> fields = new ArrayList<>(); + for (int i = 0; i < entity.fields.size(); i++) { + FieldMirror field = entity.fields.get(i); + + String getter; + TypeRef type; + if (field.fieldType == PRIMITIVE) { + TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); + type = field.type; + getter = typeHandler.getter(rs.name, i + 1); + } else { + EntityMirror referencedEntity = unit.getEntities().get(field.type); + type = referencedEntity.getIdField().type; + TypeHandler typeHandler = generatorConfiguration.typeHandler(type); + getter = typeHandler.getter(rs.name, i + 1); + } + String x = type.plainName + " " + field.javaName; + body.add(x + " = " + getter + ";"); + fields.add(field.javaName); + } + + body.add("return new " + entity.rowType.plainName + "(" + join(fields, ", ") + ");"); + + return new MethodRef(PUBLIC, entity.rowType, "newRow", p, body). + exception(g.add(SQLException.class)); + } + + public MethodRef newEntity(Imports g) { + Parameters p = new Parameters(); + Parameters.ParameterRef row = p.addParameter(this.entity.rowType, "row"); + + List<String> body = new ArrayList<>(); + List<String> cArgs = new ArrayList<>(); + List<String> method = new ArrayList<>(); + for (int i = 0; i < this.entity.fields.size(); i++) { + FieldMirror field = this.entity.fields.get(i); + + String value; + if(field.fieldType == PRIMITIVE) { + value = row.name + "." + field.javaName; + } + else { + EntityMirror referencedEntity = unit.getEntities().get(field.type); +// String x = field.type.plainName + " " + field.javaName + " = " + + value = "session." + toFieldName(referencedEntity.type) + ".selectById(" + row.name + "." + field.javaName + ")"; +// body.add(x); + } + + if (field.setterType == SetterType.CONSTRUCTOR) { + cArgs.add(value); + } else if (field.setterType == SetterType.METHOD) { + method.add("_entity." + toSetterName(field.javaName) + "(" + value + ");"); + } else if (field.setterType == SetterType.FIELD) { + method.add("_entity." + field.javaName + " = " + value + ";"); + } + } + + body.add(entity.type.plainName + " _entity = new " + entity.type.plainName + "(" + join(cArgs, ", ") + ");"); + + /* + Contact contact = new Contact(row.name, row.gender); + contact.company = session.company.selectById(row.company); + return contact; + */ + + body.addAll(method); + + body.add("return _entity;"); + + return new MethodRef(PUBLIC, this.entity.type, "newEntity", p, body). + exception(g.add(SQLException.class)); + } + public String defaultFields() { List<String> names = new ArrayList<>(); for (FieldMirror field : entity.fields) { diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java index 115223a..2848c8e 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java @@ -12,24 +12,17 @@ import io.trygvis.persistence.FieldMirror; import io.trygvis.persistence.GeneratorConfiguration; import io.trygvis.persistence.TypeHandler; import io.trygvis.persistence.sql.AbstractTypedQuery; -import io.trygvis.persistence.sql.FromResultSet; -import javax.persistence.TypedQuery; import java.sql.Connection; import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.List; import static io.trygvis.container.compiler.Utils.toGetterName; -import static io.trygvis.container.compiler.Utils.toSetterName; -import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; -import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; -import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static io.trygvis.persistence.generators.GeneratorUtils.staticVersion; +import static io.trygvis.persistence.FieldMirror.GetterType; import static java.lang.reflect.Modifier.PUBLIC; import static java.lang.reflect.Modifier.STATIC; import static java.util.Collections.singletonList; @@ -51,14 +44,14 @@ public class DaoUtilsGenerator { ClassG g = new ClassG(PUBLIC | STATIC, entity.utilsType); g.add(insertInto(g.imports)); g.add(selectById(g.imports)); - g.add(selectWhere(g.imports)); +// g.add(selectWhere(g.imports)); g.add(update(g.imports)); g.add(delete(g.imports)); g.add(deleteById(g.imports)); - g.add(query(g.imports)); - MethodRef fromResultSet = fromResultSet(g.imports); - g.add(fromResultSet); - g.add(staticVersion(new TypeRef(FromResultSet.class).args(entity.type), "fromResultSet", fromResultSet, g.type)); +// g.add(query(g.imports)); +// MethodRef fromResultSet = fromResultSet(g.imports); +// g.add(fromResultSet); +// g.add(staticVersion(new TypeRef(FromResultSet.class).args(entity.type), "fromResultSet", fromResultSet, g.type)); return g; } @@ -123,20 +116,6 @@ public class DaoUtilsGenerator { "throw new UnsupportedOperationException(\"Not implemented\");"); } - public MethodRef selectWhere(Imports imports) { - TypeRef sqlExceptionType = imports.add(SQLException.class); - Parameters p = new Parameters(); - Parameters.ParameterRef c = p.addParameter(imports.add(Connection.class), "c"); - Parameters.ParameterRef where = p.addParameter(imports.add(String.class), "where"); - List<String> body = new ArrayList<>(); - body.add("String sql = \"SELECT \" + desc.defaultFields + \" FROM " + entity.tableName + " WHERE \" + " + where.name + " + \";\";"); - body.add("return runQuery(" + c.name + ", sql, " + entity.utilsType + ".fromResultSet" + entity.type.className + ");"); - - TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type); - return new MethodRef(PUBLIC | STATIC, listOfEntityType, "select" + entity.type.className + "Where", p, body). - exception(sqlExceptionType); - } - public MethodRef update(Imports imports) { Parameters p = new Parameters(); p.addParameter(imports.add(Connection.class), "c"); @@ -155,7 +134,7 @@ public class DaoUtilsGenerator { List<String> arguments = new ArrayList<>(); arguments.add(con.name); for (FieldMirror field : entity.idFields) { - if (field.accessorType == FIELD) { + if (field.getterType == GetterType.FIELD) { arguments.add(o.name + "." + field.javaName); } else { arguments.add(o.name + "." + toGetterName(field.javaName) + "()"); @@ -200,66 +179,49 @@ public class DaoUtilsGenerator { ClassG g = new ClassG(PUBLIC | STATIC, entityTypedQuery). extendsType(sqlQueryType). add(constructor); - p = new Parameters(); - Parameters.ParameterRef rs = p.addParameter(new TypeRef(ResultSet.class), "rs"); - MethodRef fromResultSet = new MethodRef(PUBLIC, entity.type, "fromResultSet", p, - "return " + entity.utilsType.className + ".fromResultSet" + entity.type.className + "(" + rs.name + ");"). - exception(sqlExceptionType); - g.add(fromResultSet); return g; } - public MethodRef query(Imports imports) { - TypeRef conType = imports.add(Connection.class); - TypeRef typedQueryType = imports.add(TypedQuery.class).args(entity.type); - TypeRef entityTypedQuery = new TypeRef(entity.type.className + "TypedQuery"); - - Parameters p = new Parameters(); - Parameters.ParameterRef c = p.addParameter(conType, "c"); - return new MethodRef(PUBLIC | STATIC, typedQueryType, "query" + entity.type.className, p, - "return new " + entityTypedQuery + "(" + c.name + ");"); - } - - public MethodRef fromResultSet(Imports g) { - TypeRef rsType = g.add(ResultSet.class); - Parameters p = new Parameters(); - Parameters.ParameterRef rs = p.addParameter(rsType, "rs"); - - List<String> body = new ArrayList<>(); - List<String> names = new ArrayList<>(); - for (int i = 0; i < entity.fields.size(); i++) { - FieldMirror field = entity.fields.get(i); - if (field.accessorType != FIELD) { - continue; - } - if (field.fieldType == PRIMITIVE) { - TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); - body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";"); - } else if (field.fieldType == REFERENCE) { - body.add(field.type + " " + field.javaName + " = null;"); - } - names.add(field.javaName); - } - - body.add(entity.type + " returnValue = new " + entity.type + "(" + join(names, ", ") + ");"); - - for (int i = 0; i < entity.fields.size(); i++) { - FieldMirror field = entity.fields.get(i); - if (field.accessorType != METHOD) { - continue; - } - if (field.fieldType == PRIMITIVE) { - TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); - body.add("returnValue." + toSetterName(field.javaName) + "(" + typeHandler.getter(rs.name, i + 1) + ");"); - } else if (field.fieldType == REFERENCE) { - body.add("returnValue." + toSetterName(field.javaName) + "(" + null + ");"); - } - names.add(field.javaName); - } - - body.add("return returnValue;"); - - return new MethodRef(PUBLIC | STATIC, entity.type, "fromResultSet" + entity.type.className, p, body). - exception(g.add(SQLException.class)); - } +// public MethodRef fromResultSet(Imports g) { +// TypeRef rsType = g.add(ResultSet.class); +// Parameters p = new Parameters(); +// Parameters.ParameterRef rs = p.addParameter(rsType, "rs"); +// +// List<String> body = new ArrayList<>(); +// List<String> names = new ArrayList<>(); +// for (int i = 0; i < entity.fields.size(); i++) { +// FieldMirror field = entity.fields.get(i); +// if (field.accessorType != FIELD) { +// continue; +// } +// if (field.fieldType == PRIMITIVE) { +// TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); +// body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";"); +// } else if (field.fieldType == REFERENCE) { +// body.add(field.type + " " + field.javaName + " = null;"); +// } +// names.add(field.javaName); +// } +// +// body.add(entity.type + " returnValue = new " + entity.type + "(" + join(names, ", ") + ");"); +// +// for (int i = 0; i < entity.fields.size(); i++) { +// FieldMirror field = entity.fields.get(i); +// if (field.accessorType != METHOD) { +// continue; +// } +// if (field.fieldType == PRIMITIVE) { +// TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); +// body.add("returnValue." + toSetterName(field.javaName) + "(" + typeHandler.getter(rs.name, i + 1) + ");"); +// } else if (field.fieldType == REFERENCE) { +// body.add("returnValue." + toSetterName(field.javaName) + "(" + null + ");"); +// } +// names.add(field.javaName); +// } +// +// body.add("return returnValue;"); +// +// return new MethodRef(PUBLIC | STATIC, entity.type, "fromResultSet" + entity.type.className, p, body). +// exception(g.add(SQLException.class)); +// } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/EntityManagerGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/EntityManagerGenerator.java index f621343..4a6df0f 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/EntityManagerGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/EntityManagerGenerator.java @@ -60,14 +60,14 @@ public class EntityManagerGenerator { } public static MethodRef getSqlDao(SqlUnitModel unit, Imports imports, Map<EntityMirror, FieldRef> daoFields) { - TypeRef sqlDatoType = imports.add(new TypeRef(SqlDao.class)).args("Id", "T"); + TypeRef sqlDatoType = imports.add(new TypeRef(SqlDao.class)).args("Id", "T", unit.sessionType.className); Parameters p = new Parameters(); TypeRef klassType = new TypeRef(Class.class).args("T"); ParameterRef klass = p.addParameter(klassType, "klass"); List<String> body = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { body.add("if (klass == " + entity.type.plainName + ".class) {"); - body.add(" return (SqlDao<Id, T>) " + daoFields.get(entity).name + ";"); + body.add(" return (SqlDao<Id, T, " + unit.sessionType.className + ">) " + daoFields.get(entity).name + ";"); body.add("}"); } body.add("throw new RuntimeException(\"Type is not a part of this persistence unit: \" + klass);"); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java index 7a46018..ddb4d99 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java @@ -20,18 +20,15 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static io.trygvis.container.compiler.Utils.toClassName; import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; import static java.lang.reflect.Modifier.PUBLIC; public class SqlSessionGenerator { public static ClassG generateSqlSession(SqlUnitModel unit) throws IOException { - String prefix = unit.getPackageName() + "." + toClassName(unit.getName()); - TypeRef emType = new TypeRef(prefix + "SqlSession"); TypeRef sqlSession = new TypeRef(SqlSession.class); - ClassG g = new ClassG(PUBLIC, emType). + ClassG g = new ClassG(PUBLIC, unit.sessionType). extendsType(sqlSession); Map<EntityMirror, FieldRef> daoFields = new HashMap<>(); @@ -54,20 +51,21 @@ public class SqlSessionGenerator { for (EntityMirror entity : unit.getEntities().values()) { FieldRef f = daoFields.get(entity); - body.add("this." + f.name + " = new " + entity.daoType.plainName + "(" + c.name + ");"); + body.add("this." + f.name + " = new " + entity.daoType.plainName + "(this);"); } return new Constructor(p, body); } public static MethodRef getSqlDao(SqlUnitModel unit, Imports imports, Map<EntityMirror, FieldRef> daoFields) { - TypeRef sqlDatoType = imports.add(new TypeRef(SqlDao.class)).args("Id", "T"); + TypeRef sqlDatoType = imports.add(new TypeRef(SqlDao.class)). + args("Id", "T", unit.sessionType.className, "?"); Parameters p = new Parameters(); - TypeRef klassType = new TypeRef(Class.class).args("T"); - ParameterRef klass = p.addParameter(klassType, "klass"); + p.addParameter(new TypeRef(Class.class).args("T"), "klass"); List<String> body = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { + String sqlDao = "SqlDao<Id, T, " + unit.sessionType.className + ", " + entity.rowType.className + ">"; body.add("if (klass == " + entity.type.plainName + ".class) {"); - body.add(" return (SqlDao<Id, T>) " + daoFields.get(entity).name + ";"); + body.add(" return (" + sqlDao + ") " + daoFields.get(entity).name + ";"); body.add("}"); } body.add("throw new RuntimeException(\"Type is not a part of this persistence unit: \" + klass);"); diff --git a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java index c513157..dc69a03 100644 --- a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java +++ b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java @@ -13,10 +13,10 @@ import java.io.CharArrayWriter; import java.io.PrintWriter; import static io.trygvis.container.compiler.Utils.EOL; -import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD; -import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; +import static io.trygvis.persistence.FieldMirror.GetterType; +import static io.trygvis.persistence.FieldMirror.SetterType; import static java.lang.String.format; import static org.testng.Assert.assertEquals; @@ -25,13 +25,20 @@ public class EntityMirrorTest { GeneratorConfiguration generatorConfiguration = new GeneratorConfiguration(); static TypeRef entityType = new TypeRef("Wat"); - static FieldMirror idLong = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(Long.class), "id", "id", true, false, true); - static FieldMirror idString = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(String.class), "id", "id", true, false, true); - static FieldMirror idMethod = new FieldMirror(PRIMITIVE, METHOD, new TypeRef(Long.class), "id", "id", true, false, true); - static FieldMirror name = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(String.class), "name", "name", false, false, false); - static FieldMirror age = new FieldMirror(PRIMITIVE, FIELD, new TypeRef(Integer.class), "age", "age", false, true, false); - static FieldMirror year = new FieldMirror(PRIMITIVE, METHOD, new TypeRef(Integer.class), "year", "year", false, true, false); - static FieldMirror ref = new FieldMirror(REFERENCE, FIELD, entityType, "parent", "parent", false, false, false); + static FieldMirror idLong = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + new TypeRef(Long.class), "id", "id", true, false, true); + static FieldMirror idString = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + new TypeRef(String.class), "id", "id", true, false, true); + static FieldMirror idMethod = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.METHOD, + new TypeRef(Long.class), "id", "id", true, false, true); + static FieldMirror name = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + new TypeRef(String.class), "name", "name", false, false, false); + static FieldMirror age = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + new TypeRef(Integer.class), "age", "age", false, true, false); + static FieldMirror year = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.METHOD, + new TypeRef(Integer.class), "year", "year", false, true, false); + static FieldMirror ref = new FieldMirror(REFERENCE, SetterType.CONSTRUCTOR, GetterType.FIELD, + entityType, "parent", "parent", false, false, false); @DataProvider(name = "insertIntoSql", parallel = true) public static Object[][] insertIntoProvider() { @@ -180,33 +187,33 @@ public class EntityMirrorTest { return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).deleteById(new Imports()); } - @Test - public void testFromResultSet() { - eq(fromResultSet(age), - "java.lang.Integer age = rs.getInt(1);", - "Wat returnValue = new Wat(age);", - "return returnValue;"); - - eq(fromResultSet(age, year), - "java.lang.Integer age = rs.getInt(1);", - "Wat returnValue = new Wat(age);", - "returnValue.setYear(rs.getInt(2));", - "return returnValue;"); - - eq(fromResultSet(age, year, name), - "java.lang.Integer age = rs.getInt(1);", - "java.lang.String name = rs.getString(3);", - "Wat returnValue = new Wat(age, name);", - "returnValue.setYear(rs.getInt(2));", - "return returnValue;"); - } - - private MethodRef fromResultSet(FieldMirror... fields) { - EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table"); - myTable.add(fields); - SqlUnitModel unit = new SqlUnitModel().add(myTable); - return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).fromResultSet(new Imports()); - } +// @Test +// public void testFromResultSet() { +// eq(fromResultSet(age), +// "java.lang.Integer age = rs.getInt(1);", +// "Wat returnValue = new Wat(age);", +// "return returnValue;"); +// +// eq(fromResultSet(age, year), +// "java.lang.Integer age = rs.getInt(1);", +// "Wat returnValue = new Wat(age);", +// "returnValue.setYear(rs.getInt(2));", +// "return returnValue;"); +// +// eq(fromResultSet(age, year, name), +// "java.lang.Integer age = rs.getInt(1);", +// "java.lang.String name = rs.getString(3);", +// "Wat returnValue = new Wat(age, name);", +// "returnValue.setYear(rs.getInt(2));", +// "return returnValue;"); +// } + +// private MethodRef fromResultSet(FieldMirror... fields) { +// EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table"); +// myTable.add(fields); +// SqlUnitModel unit = new SqlUnitModel().add(myTable); +// return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).fromResultSet(new Imports()); +// } private void eq(MethodRef m, String... expected) { CharArrayWriter actual = new CharArrayWriter(); diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java b/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java index 86e8641..b272649 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java @@ -1,15 +1,9 @@ package io.trygvis.container.myapp; -import io.trygvis.persistence.sql.SqlExecutor; - import java.io.BufferedReader; import java.io.EOFException; import java.io.InputStreamReader; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import static io.trygvis.container.myapp.Contact.Gender.FEMALE; @@ -215,7 +209,8 @@ public class AddressBookDirect { } Company company = null; - Contact o = new Contact(name, g, company); + Contact o = new Contact(name, g); + o.company = session.company.selectById(1l); session.contact.insert(o); } diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AddressBookJpa.java b/myapp/src/main/java/io/trygvis/container/myapp/AddressBookJpa.java index 3981805..75e923a 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBookJpa.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBookJpa.java @@ -18,7 +18,7 @@ import static io.trygvis.container.myapp.Contact.Gender.FEMALE; import static io.trygvis.container.myapp.Contact.Gender.MALE; public class AddressBookJpa { - +/* private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); private EntityManager entityManager; @@ -239,4 +239,5 @@ public class AddressBookJpa { } System.out.println(); } +*/ } diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Contact.java b/myapp/src/main/java/io/trygvis/container/myapp/Contact.java index 5ce87c7..1ef5adb 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/Contact.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/Contact.java @@ -16,11 +16,10 @@ public class Contact extends AbstractEntity { public final Gender gender; - public final Company company; + public Company company; - public Contact(String name, Gender gender, Company company) { + public Contact(String name, Gender gender) { this.name = name; this.gender = gender; - this.company = company; } } diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java index 2c82474..c253229 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java @@ -7,12 +7,12 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -public abstract class SqlDao<Id, T> implements FromResultSet<T> { +public abstract class SqlDao<Id, T, S extends SqlSession, Row> { - protected final Connection c; + protected final S session; - protected SqlDao(Connection c) { - this.c = c; + protected SqlDao(S session) { + this.session = session; } public abstract void insert(T o) throws SQLException; @@ -31,16 +31,30 @@ public abstract class SqlDao<Id, T> implements FromResultSet<T> { // Protected // ----------------------------------------------------------------------- - protected static <T> List<T> runQuery(Connection c, String sql, FromResultSet<T> f) throws SQLException { - try (PreparedStatement stmt = c.prepareStatement(sql)) { - ResultSet rs = stmt.executeQuery(); + protected abstract Row newRow(ResultSet rs) throws SQLException; - List<T> list = new ArrayList<>(); - while (rs.next()) { - list.add(f.fromResultSet(rs)); - } + protected abstract T newEntity(Row row) throws SQLException; + + protected List<T> runQuery(final String sql) throws SQLException { + return session.query(new SqlExecutor.QueryCommand<T>() { + @Override + public List<T> run(Connection c) throws SQLException { + try (PreparedStatement stmt = c.prepareStatement(sql)) { + ResultSet rs = stmt.executeQuery(); + + List<Row> rows = new ArrayList<>(); + while (rs.next()) { + rows.add(newRow(rs)); + } - return list; - } + List<T> entities = new ArrayList<T>(rows.size()); + for (Row row : rows) { + entities.add(newEntity(row)); + } + + return entities; + } + } + }); } } diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityManager.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityManager.java index acd4d35..2a44d82 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityManager.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityManager.java @@ -24,7 +24,7 @@ public abstract class SqlEntityManager implements EntityManager { private Map<String, Object> properties = new HashMap<>(); - public abstract <Id, T> SqlDao<Id, T> getDao(Class<T> klass); + public abstract <Id, T> SqlDao<Id, T, ?, ?> getDao(Class<T> klass); // ----------------------------------------------------------------------- // @@ -83,7 +83,7 @@ public abstract class SqlEntityManager implements EntityManager { try { @SuppressWarnings("unchecked") Class<T> klass = (Class<T>) entity.getClass(); - SqlDao<Object, T> dao = getDao(klass); + SqlDao<Object, T, ?, ?> dao = getDao(klass); T t = dao.selectById(entity); if (t == null) { dao.insert(entity); @@ -115,7 +115,7 @@ public abstract class SqlEntityManager implements EntityManager { @Override public <T> T find(Class<T> entityClass, Object primaryKey) { try { - SqlDao<Object, T> dao = getDao(entityClass); + SqlDao<Object, T, ?, ?> dao = getDao(entityClass); return dao.selectById(primaryKey); } catch (SQLException e) { throw new PersistenceException(e); @@ -232,12 +232,13 @@ public abstract class SqlEntityManager implements EntityManager { @Override public <T> TypedQuery<T> createQuery(String sqlString, Class<T> resultClass) { - // What happens if the transaction is aborted and this query is executes? Can a Query outlive it's connection? - // Or even EntityManager? Should probably store a reference to the current connection and check that the - // current one is the same when executing. - - SqlDao<?, T> dao = this.<Object, T>getDao(resultClass); - return new SqlQuery<>(dao, new SqlExecutorDelegate(), sqlString, true); + throw new UnsupportedOperationException(); +// // What happens if the transaction is aborted and this query is executes? Can a Query outlive it's connection? +// // Or even EntityManager? Should probably store a reference to the current connection and check that the +// // current one is the same when executing. +// +// SqlDao<?, T> dao = this.<Object, T>getDao(resultClass); +// return new SqlQuery<>(dao, new SqlExecutorDelegate(), sqlString, true); } @Override @@ -257,8 +258,9 @@ public abstract class SqlEntityManager implements EntityManager { @Override public Query createNativeQuery(String sql, Class resultClass) { - SqlDao<?, ?> dao = getDao(resultClass); - return new SqlQuery<>(dao, new SqlExecutorDelegate(), sql, true); + throw new UnsupportedOperationException(); +// SqlDao<?, ?> dao = getDao(resultClass); +// return new SqlQuery<>(dao, new SqlExecutorDelegate(), sql, true); } private class SqlExecutorDelegate implements SqlExecutor { diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java index 3caa621..b5e58eb 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java @@ -6,7 +6,7 @@ import java.sql.Statement; import java.util.List; public class SqlSession { - private final Connection c; + public final Connection c; public SqlSession(Connection c) { this.c = c; |