マッピング対象のフィールド名に細工する方法
デフォルトのオートマッピングでは、get/setNameというセッター・ゲッターメソッドに対してNAMEというフィールドがマッピングされる。データベースフィールド名としては、単純なNAMEなどという名称よりも、USR_NAME等の何かしらのプリフィックスを持つものとしたい。理由としては、
- 単純な名称であると、データベースの予約語と競合してしまう場合がある。
- SQLはJavaの文字列として記述されてしまうので、フィールド変更の際に検索しやすいように、単純な名称は避けたい。
例えば、テーブル自体は
create table user(f_id identity, usr_name char(80), usr_phone char(80), primary key(f_id))
などと生成し、それに対するクラスを
public static class User { public int getId() { return id; } public void setId(int value) { id = value; } public String getName() { return name; } public void setName(String value) { name = value; } public String getPhone() { return phone; } public void setPhone(String value) { phone = value; } }
などとしたい。つまり、セッター・ゲッターは単純な名前のままにしておきたい。
実現方法
以下のようにしてみたが、これは実験的なものであり必ずしもうまくいくとは限らない。
AClassExtra.java
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AClassExtra { String fieldPrefix(); }
ModObjectMapper.java
import java.lang.reflect.*; import java.sql.*; import java.util.*; import com.jenkov.db.impl.mapping.*; import com.jenkov.db.itf.*; import com.jenkov.db.itf.mapping.*; public class ModObjectMapper extends ObjectMapper { private String fieldPrefix; public ModObjectMapper() { super(new ObjectMappingFactory()); nameGuesser = new DbNameGuesser() { @Override @SuppressWarnings("unchecked") public Collection<String> getPossibleColumnNames(Method member) { Collection<String> c = (Collection<String>)super.getPossibleColumnNames(member); if (fieldPrefix == null) return c; List<String> list = new ArrayList<String>(c); for (Object o: c) { list.add(fieldPrefix + o); } return list; } }; } @Override public IObjectMapping getObjectMapping(Object objectMappingKey, IPersistenceConfiguration configuration, Connection connection) throws PersistenceException { fieldPrefix = null; if (objectMappingKey instanceof Class) { Class<?> clazz = (Class<?>)objectMappingKey; AClassExtra aClassExtra = (AClassExtra)clazz.getAnnotation(AClassExtra.class); if (aClassExtra != null) { fieldPrefix = aClassExtra.fieldPrefix(); } } return super.getObjectMapping(objectMappingKey, configuration, connection); } }
TestZero.java
public class TestZero { public static PersistenceManager perman = new PersistenceManager(); public static void main(String[]args) throws Exception { perman.getConfiguration().setObjectMapper(new ModObjectMapper()); // DBドライバをロード Class.forName("org.hsqldb.jdbcDriver"); // データベースを作成 { DatabaseInitializer databaseInitializer = perman.getConfiguration().getDatabaseInitializer(); databaseInitializer.add(1, "create table user(f_id identity, usr_name char(80), usr_phone char(80), primary key(f_id))"); Connection conn = getConnection(); // setAutoCommit(true)の状態 perman.initializeDatabase(conn); conn.close(); } // レコードを挿入 { Connection conn = getConnection(); conn.setAutoCommit(false); IDaos daos = perman.createDaos(conn); User user = new User(); user.name = "鈴木"; user.phone = "aaaa"; daos.getObjectDao().insert(user); daos.getObjectDao().insert(user); conn.commit(); conn.close(); } // レコードを検索 { Connection conn = getConnection(); IDaos daos = perman.createDaos(conn); User user = (User)daos.getObjectDao().read(User.class, "select * from user where f_id=0"); daos.getObjectDao().update(user); conn.close(); } } /** Userの定義 */ @AClassMapping(tableName="user") @AClassExtra(fieldPrefix="USR_") public static class User { int id; String name; String phone; @AGetterMapping(databaseGenerated = true, columnName="F_ID") public int getId() { return id; } @ASetterMapping(columnName="F_ID") public void setId(int value) { id = value; } public String getName() { return name; } public void setName(String value) { name = value; } public String getPhone() { return phone; } public void setPhone(String value) { phone = value; } @Override public String toString() { return "id:" + id + ", name:" + name + ", phone:" + phone; } } /** コネクションの取得 */ private static Connection getConnection() throws SQLException { return DriverManager.getConnection( "jdbc:hsqldb:file:testdb", "sa", "" ); } }