#% DAOJavaソースファイル作成用の雛型ファイル
#% 2009/04/27 By S.Ito

#% === DAO =====================================================================
#! dao package
package #package#;

#! header postgreSQL
import org.postgresql.util.PGobject;
import java.util.HashSet;

#! header
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

/**
 * #nameJp# データベースアクセスクラス
 *
 * @author
 *
 */
@SuppressWarnings("serial")
public class #mstName#Dao extends DaoBase implements RecordSearch, RecordAction, Serializable {

	// ユニークインデックス又は主キーエラー時のSQLステート値
	protected static final String UNIQUE_INDEX_OR_PRIMARY_KEY_VIOLATION = "#uniqueErrorCode#";

#! sql insert
	// 挿入用SQL
	protected static final String insertSql = "insert into #mstName#(" //
#! sql insert fields
			+ "#fields#" //
#! sql insert values
			+ ") values(#values#)";
#! sql update

	// 更新用SQL
	protected static final String updateSql = "update #mstName# set " //
#! sql update fields
			+ "#fields#" //
#! sql update where
			+ " where #where#";
#! sql delete

	// 削除用SQL
	protected static final String deleteSql = "delete from #mstName#" //
#! sql delete where
			+ " where #where#";
#! sql get

	// 取得用SQL
	protected static final String getSql = "select " //
#! sql get fields
			+ "#fields#" //
#! sql get from
			+ " from #mstName#" //
#! sql get where
			+ " where #where#";
#! sql search

	// 検索用SQL
	protected static final String searchSql = "select " //
#! sql search fields
			+ "#fields#" //
#! sql search from
			+ " from  #mstName#";
#! sql search order

	// 検索並び順用SQL
	protected static final String searchOrderSql = "order by #fields#";

#! sql search list
	// 検索用のリスト
	private List<#mstName#> searchList;

#! sql search postgreSQL
	// ビットフィールドの名前セット
	private static HashSet<String> searchBitMap;

	static{
		searchBitMap = new  HashSet<String>();
#! sql search postgreSQL field
		searchBitMap.add("#fieldNmae#");
#! sql search postgreSQL end
	}

#! insert
	/**
	 * #nameJp#に1レコード挿入する
	 *
	 * @param rec
	 *           #nameJp#レコード
	 * @return 挿入件数（ユニークインデックス又は主キーエラー時は0）
	 * @throws SQLException
	 */
	public int insert(#mstName# rec) throws SQLException {

		Connection con = null;

		try {

			con = getConnection();
			con.setAutoCommit(false);

			PreparedStatement stmt = null;
			try {

#% シーケンス前処理
#! pre seq h2 identity
#% 		nothing!!
#! pre seq Integer
				if (rec.#getMethod#() == null) {
					rec.#setMethod#((int)getSequence(con, "#seqName#", #oracleSequence#));
				}

#! pre seq Long
				if (rec.#getMethod#() == null) {
					rec.#setMethod#(getSequence(con, "#seqName#", #oracleSequence#));
				}

#! pre seq BigDecimal
				if (rec.#getMethod#() == null) {
					rec.#setMethod#(new BigDecimal(getSequence(con, "#seqName#", #oracleSequence#)));
				}

#! insert start
				stmt = con.prepareStatement(insertSql);
				int parameterIndex = 1;

#! insert String
				if (rec.#getMethod#() != null) {
					stmt.setString(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.CHAR);
				}

#! insert String postgreSQL bit
				if (rec.#getMethod#() != null) {
					stmt.setObject(parameterIndex++, changeBitObject(rec.#getMethod#(), #modeFlag#, #length#));
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.OTHER);
				}

#! insert Integer
				if (rec.#getMethod#() != null) {
					stmt.setInt(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! insert Long
				if (rec.#getMethod#() != null) {
					stmt.setLong(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! insert BigDecimal
				if (rec.#getMethod#() != null) {
					stmt.setBigDecimal(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! insert Boolean h2
				if (rec.#getMethod#() != null) {
					stmt.setBoolean(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.BOOLEAN);
				}

#! insert Boolean oracle
				if (rec.#getMethod#() != null) {
					stmt.setInt(parameterIndex++, rec.#getMethod#() ? 1 : 0);
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! insert Date
				if (rec.#getMethod#() != null) {
					stmt.setDate(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.DATE);
				}

#! insert Time
				if (rec.#getMethod#() != null) {
					stmt.setTime(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.TIME);
				}

#! insert Timestamp
				if (rec.#getMethod#() != null) {
					stmt.setTimestamp(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.TIMESTAMP);
				}

#! insert byte[]
				if (rec.#getMethod#() != null) {
					stmt.setBytes(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.BINARY);
				}

#! insert footer
				int rtn = stmt.executeUpdate();

#% シーケンス後処理
#! pre identity Integer
				rec.#setMethod#((int)getIdentity(con));

#! pre identity Long
				rec.#setMethod#(getIdentity(con));

#! pre identity BigDecimal
				rec.#setMethod#(new BigDecimal(getIdentity(con)));

#! insert footer 2
				con.commit();

				return rtn;

			} catch (SQLException e) {
				// ユニークインデックス又は主キーエラーのときは0件挿入とする
				if (UNIQUE_INDEX_OR_PRIMARY_KEY_VIOLATION.equals(e.getSQLState())) {
					return 0;
				}
				throw e;
			} finally {
				if (stmt != null) {
					stmt.close();
				}
			}

		} finally {

			if(con != null){
				con.rollback();
			}

			closeConnection();
		}
	}


#! update

	/**
	 * #nameJp#を更新する
	 *
	 * @param rec
	 *            #nameJp#レコード
	 * @return 更新件数
	 * @throws SQLException
	 */
	public int update(#mstName# rec) throws SQLException {

		try {
			Connection con = getConnection();

			PreparedStatement stmt = null;
			try {
				stmt = con.prepareStatement(updateSql);

				int parameterIndex = 1;

#! update String
				if (rec.#getMethod#() != null) {
					stmt.setString(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.CHAR);
				}

#! update String postgreSQL bit
				if (rec.#getMethod#() != null) {
					stmt.setObject(parameterIndex++, changeBitObject(rec.#getMethod#(), #modeFlag#, #length#));
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.OTHER);
				}

#! update Integer
				if (rec.#getMethod#() != null) {
					stmt.setInt(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! update Long
				if (rec.#getMethod#() != null) {
					stmt.setLong(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! update BigDecimal
				if (rec.#getMethod#() != null) {
					stmt.setBigDecimal(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! update Boolean h2
				if (rec.#getMethod#() != null) {
					stmt.setBoolean(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.BOOLEAN);
				}

#! update Boolean oracle
				if (rec.#getMethod#() != null) {
					stmt.setInt(parameterIndex++, rec.#getMethod#() ? 1 : 0);
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.NUMERIC);
				}

#! update Date
				if (rec.#getMethod#() != null) {
					stmt.setDate(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.DATE);
				}

#! update Time
				if (rec.#getMethod#() != null) {
					stmt.setTime(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.TIME);
				}

#! update Timestamp
				if (rec.#getMethod#() != null) {
					stmt.setTimestamp(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.TIMESTAMP);
				}

#! update byte[]
				if (rec.#getMethod#() != null) {
					stmt.setBytes(parameterIndex++, rec.#getMethod#());
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.BINARY);
				}

#! update key
				// 主キー
#! update key set
				stmt.setObject(parameterIndex++, rec.#getMethod#());
#! update key set postgreSQL bit
				if (rec.#getMethod#() != null) {
					stmt.setObject(parameterIndex++, changeBitObject(rec.#getMethod#(), #modeFlag#, #length#));
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.OTHER);
				}
#! update footer

				return stmt.executeUpdate();

			} finally {
				if (stmt != null) {
					stmt.close();
				}
			}

		} finally {
			closeConnection();
		}
	}

#! delete

	/**
	 * #nameJp#マスタを削除する
	 *
	 * @param rec
	 *            #nameJp#マスタレコード
	 * @return 削除件数
	 * @throws SQLException
	 */
	public int delete(#mstName# rec) throws SQLException {

		try {
			Connection con = getConnection();

			PreparedStatement stmt = null;
			try {
				stmt = con.prepareStatement(deleteSql);

				int parameterIndex = 1;

#! delete key
				// 主キー
#! delete key set
				stmt.setObject(parameterIndex++, rec.#getMethod#());
#! delete key set postgreSQL bit
				if (rec.#getMethod#() != null) {
					stmt.setObject(parameterIndex++, changeBitObject(rec.#getMethod#(), #modeFlag#, #length#));
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.OTHER);
				}
#! delete footer

				return stmt.executeUpdate();

			} finally {
				if (stmt != null) {
					stmt.close();
				}
			}

		} finally {
			closeConnection();
		}
	}

#! get

	/**
	 * #nameJp#取得
	 *
	 * @return 検索された#nameJp#のレコードリスト
	 * @throws SQLException
	 */
	public #mstName# get(#mstName# keyRecord) throws SQLException {

		#mstName# rec = null;

		try {
			Connection con = getConnection();

			PreparedStatement stmt = null;
			try {
				stmt = con.prepareStatement(getSql);

				int parameterIndex = 1;

#! get key
				// 主キー
#! get key set
				stmt.setObject(parameterIndex++, keyRecord.#getMethod#());
#! get key set postgreSQL bit
				if (rec.#getMethod#() != null) {
					stmt.setObject(parameterIndex++, changeBitObject(rec.#getMethod#(), #modeFlag#, #length#));
				} else {
					stmt.setNull(parameterIndex++, java.sql.Types.OTHER);
				}
#! get ResultSet

				ResultSet res = null;

				try {
					res = stmt.executeQuery();

					if (res.next()) {
						rec = new #mstName#();

#! get ResultSet String
						rec.#setMethod#(res.getString("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Int
						rec.#setMethod#(res.getInt("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Long
						rec.#setMethod#(res.getLong("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet BigDecimal
						rec.#setMethod#(res.getBigDecimal("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Boolean h2
						rec.#setMethod#(res.getBoolean("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Boolean oracle
						rec.#setMethod#(res.getInt("#name#") == 1);
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Date
						rec.#setMethod#(res.getDate("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Time
						rec.#setMethod#(res.getTime("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet Timestamp
						rec.#setMethod#(res.getTimestamp("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get ResultSet byte[]
						rec.#setMethod#(res.getBytes("#name#"));
						if (res.wasNull()) {
							rec.#setMethod#(null);
						}

#! get footer
					}

				} finally {
					if (res != null) {
						res.close();
					}
				}
			} finally {
				if (stmt != null) {
					stmt.close();
				}
			}

		} finally {
			closeConnection();
		}

		return rec;
	}

#! search

	/**
	 * #nameJp#検索
	 *
	 * @return 検索された#nameJp#のレコードリスト
	 * @throws SQLException
	 */
	public List<#mstName#> search() throws Exception {

		searchList = new LinkedList<#mstName#>();

		search(this);

		List<#mstName#> list = searchList;
		searchList = null;

		return list;
	}

	@Override
	public void initAction() throws Exception{
		//	何もしない
	}

	@Override
	public void action(Object record) throws Exception {
		searchList.add((#mstName#) record);
	}

	@Override
	public void closeAction() throws Exception {
		//	何もしない
	}

	/**
	 * #nameJp#検索
	 *
	 * @throws SQLException
	 */
	public void search(RecordAction searchAction) throws Exception {
		try {
			searchAction.initAction();

			try {
				Connection con = getConnection();

				PreparedStatement stmt = null;
				try {
					stmt = con.prepareStatement(searchSql + makeSearchWhere() + " " + searchOrderSql);
					setSearchWhere(stmt);

					ResultSet res = null;

					try {
						res = stmt.executeQuery();

						while (res.next()) {

							#mstName# rec = new #mstName#();

#! search ResultSet String
							rec.#setMethod#(res.getString("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Int
							rec.#setMethod#(res.getInt("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Long
							rec.#setMethod#(res.getLong("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet BigDecimal
							rec.#setMethod#(res.getBigDecimal("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Boolean h2
							rec.#setMethod#(res.getBoolean("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Boolean oracle
							rec.#setMethod#(res.getInt("#name#") == 1);
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Date
							rec.#setMethod#(res.getDate("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Time
							rec.#setMethod#(res.getTime("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet Timestamp
							rec.#setMethod#(res.getTimestamp("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search ResultSet byte[]
							rec.#setMethod#(res.getBytes("#name#"));
							if (res.wasNull()) {
								rec.#setMethod#(null);
							}

#! search footer
							// レコード毎の処理を呼び出す
							searchAction.action(rec);
						}

					} finally {
						if (res != null) {
							res.close();
						}
					}
				} finally {
					if (stmt != null) {
						stmt.close();
					}
				}

			} finally {
				closeConnection();
			}
		} finally {
			searchAction.closeAction();
		}
	}

#! footer postgreSQL
	/**
	 * 検索用SQLのWHERE区の1項目にパラメータ値を設定する
	 *
	 * @param stmt
	 * @param parameterIndex
	 * @param searcKeyValue
	 * @throws SQLException
	 */
	@Override
	protected void setSearchWhere(PreparedStatement stmt, int parameterIndex, SearcKeyValue searcKeyValue) throws SQLException {

		if (!searchBitMap.contains(searcKeyValue.keyName)) {
			super.setSearchWhere(stmt, parameterIndex, searcKeyValue);
			return;
		}

		SearcKeyValue bitKeyValue = new SearcKeyValue(searcKeyValue.keyName, searcKeyValue.searchMode, changeBitObject(
				(String) searcKeyValue.value, false, ((String) searcKeyValue.value).length()));
		super.setSearchWhere(stmt, parameterIndex, bitKeyValue);
	}

	/**
	 * postgreSQL・bit、varbitフィールドの変換
	 *
	 * @param value
	 *            ビット値（1,0の連続文字列）
	 * @param modeFlag
	 *            true=固定、false=可変
	 * @param length
	 *            最大フィールド長
	 * @return 変換されたオブジェクト
	 * @throws SQLException
	 */
	protected static PGobject changeBitObject(String value, boolean modeFlag, int length) throws SQLException {

		if (value == null) {
			value = "";
		}

		StringBuilder sb = new StringBuilder();
		int valueLength = value.length();

		for (int i = 0; i < length; i++) {
			if (i < valueLength) {
				char c = value.charAt(i);
				if (c == '1') {
					sb.append(c);
				} else {
					sb.append('0');
				}
			} else {
				if (modeFlag) {
					sb.append('0');
				} else {
					break;
				}
			}
		}

		PGobject object = new PGobject();
		object.setType("bit");
		object.setValue(sb.toString());

		return object;
	}

#! footer
}

#% === DAO Base =====================================================================
#! daoBase package
package #package#;

#! daoBase main
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

/**
 * DAOの基底となるクラス
 *
 * @author
 *
 */
public abstract class DaoBase {

	// 検索用モード：等しい（完全一致）
	public static final int equal = 1;

	// 検索用モード：前方一致（文字型のみ有効）
	public static final int like = 2;

	// プロパティファイル名
	private static final String propertyFileName = "/db.xml";

	// プロパティエラーフラグ
	private static boolean propertyError = false;

	// プロパティから得られたJDBCドライバー名
	private static String driverNname;

	// プロパティから得られたコネクション名
	private static String connectionString;

	// プロパティから得られたデータベース接続用ID
	private static String longinId;

	// プロパティから得られたデータベース接続用パスワード
	private static String longinPassword;

	private List<SearcKeyValue> searchKeyValueList = new LinkedList<SearcKeyValue>();

	static {

		// プロパティ値の取得
		Properties properties = new Properties();
		InputStream stream = null;
		try {
			try {
				stream = DaoBase.class.getResourceAsStream(propertyFileName);
				properties.loadFromXML(stream);
			} finally {
				if (stream != null) {
					stream.close();
				}
			}
			driverNname = (String) properties.get("driver.name");
			connectionString = (String) properties.get("connection.string");
			longinId = (String) properties.get("login.id");
			longinPassword = (String) properties.get("login.password");
		} catch (IOException e) {
			propertyError = true;
		}
	}

	/**
	 * コネクション
	 */
	private Connection con;

	/**
	 * コネクションをクローズせずに保持しておくことを許可するフラグ
	 */
	private boolean keepConnection;

	/**
	 * コンストラクタ
	 */
	public DaoBase() {
		con = null;
		keepConnection = false;
	}

	/**
	 * データベースコネクションの取得
	 *
	 * @return
	 * @throws SQLException
	 */
	public Connection getConnection() throws SQLException {

		// コネクションキープ時でコネクションが既に存在したら、そのコネクションを返す
		if (keepConnection && con != null) {
			return con;
		}

		// もし、既にコネクションが存在したら一度クローズする
		if (con != null && !con.isClosed()) {
			con.close();
			con = null;
		}

		// コネクションの取得
		if (propertyError) {
			throw new RuntimeException("プロパティファイルの読込に失敗しました");
		}

		try {
			Class.forName(driverNname);
		} catch (ClassNotFoundException e) {
			throw new SQLException("JDBCが使用できません", e);
		}
		con = DriverManager.getConnection(connectionString, longinId, longinPassword);
		return con;
	}

	/**
	 * コネクションをクローズする<br>
	 * ただし、コネクションキープ時はクローズしない
	 *
	 * @throws SQLException
	 */
	public void closeConnection() throws SQLException {
		if (keepConnection) {
			return;
		}

		if (con != null && !con.isClosed()) {
			con.close();
		}
		con = null;
	}

	/**
	 * コネクションを設定する
	 *
	 * @param con
	 *            コネクション
	 */
	public void setConnection(Connection con) {
		this.con = con;
	}

	/**
	 * コネクションをキープの設定を行う
	 *
	 * @param keepConnection
	 *            true=コネクションをキープする
	 */
	public void setKeepConnection(boolean keepConnection) {
		this.keepConnection = keepConnection;
	}

	/**
	 * コネクションをキープの確認を行う
	 *
	 * @return true=コネクションをキープ
	 */
	public boolean isKeepConnection() {
		return keepConnection;
	}

	/**
	 * 検索用パラメータをクリアする
	 */
	public void clearSearchParameter() {
		searchKeyValueList.clear();
	}

	/**
	 * 検索用パラメータを追加する
	 *
	 * @param keyNmae
	 * @param mode
	 * @param value
	 */
	public void addSearchParameter(String keyNmae, int mode, Object value) {
		if (mode != equal && mode != like) {
			return;
		}

		if (value == null) {
			return;
		}

		if ((value instanceof String) && ((String) value).trim().length() <= 0) {
			return;
		}

		searchKeyValueList.add(new SearcKeyValue(keyNmae, mode, value));
	}

	/**
	 * 検索用SQLのWHERE区を作成する
	 *
	 * @return
	 */
	protected String makeSearchWhere() {

		StringBuilder sb = new StringBuilder();

		for (SearcKeyValue searcKeyValue : searchKeyValueList) {

			if (sb.length() > 0) {
				sb.append(" and ");
			}
			sb.append(searcKeyValue.keyName);
			if (searcKeyValue.value instanceof String) {
				if (searcKeyValue.searchMode == equal) {
					sb.append("=?");
				} else {
					sb.append(" like ");
					sb.append("?");
				}
			} else {
				sb.append("=?");
			}
		}

		if (sb.length() <= 0) {
			return "";
		}

		return " where " + sb.toString();
	}

	/**
	 * 検索用SQLのWHERE区にパラメータ値を設定する
	 *
	 * @return
	 */
	protected void setSearchWhere(PreparedStatement stmt) throws SQLException {

		int parameterIndex = 1;

		for (SearcKeyValue searcKeyValue : searchKeyValueList) {
			setSearchWhere(stmt, parameterIndex, searcKeyValue);
			parameterIndex++;
		}
	}

	/**
	 * 検索用SQLのWHERE区の1項目にパラメータ値を設定する
	 *
	 * @param stmt
	 * @param parameterIndex
	 * @param searcKeyValue
	 * @throws SQLException
	 */
	protected void setSearchWhere(PreparedStatement stmt, int parameterIndex, SearcKeyValue searcKeyValue) throws SQLException {
		if (searcKeyValue.value instanceof String) {
			if (searcKeyValue.searchMode == equal) {
				stmt.setObject(parameterIndex, searcKeyValue.value);
			} else {
				stmt.setObject(parameterIndex, ((String) searcKeyValue.value) + "%");
			}
		} else {
			stmt.setObject(parameterIndex, searcKeyValue.value);
		}
	}

	/**
	 * 検索用データクラス
	 */
	class SearcKeyValue {
		public String keyName;
		public int searchMode;
		public Object value;

		/**
		 * コンストラクタ
		 *
		 * @param keyName
		 * @param searchMode
		 * @param value
		 */
		public SearcKeyValue(String keyName, int searchMode, Object value) {
			this.keyName = keyName;
			this.searchMode = searchMode;
			this.value = value;
		}
	}

	/**
	 * シーケンスを取得する
	 *
	 * @param sequenceName
	 *            シーケンス名
	 * @param oracleSequence
	 *            ORACLEのシーケンス時はtrue
	 * @return シーケンス値
	 * @throws SQLException
	 */
	public long getSequence(Connection con, String sequenceName, boolean oracleSequence) throws SQLException {

		PreparedStatement stmt = null;
		try{
			if (oracleSequence) {
				stmt = con.prepareStatement("select " + sequenceName +".nextval from dual");
			} else {
				stmt = con.prepareStatement("select nextval('" + sequenceName +"')");
			}
			ResultSet res = null;
			try {
				res = stmt.executeQuery();

				if (res.next()) {
					long ret = res.getLong(1);
					if (!res.wasNull()){
						return ret;
					}
				}
				throw new SQLException("シーケンスの取得に失敗しました " + sequenceName);
			} finally {
				if ( res != null){
					res.close();
				}
			}
		} finally {
			if (stmt != null) {
				stmt.close();
			}
		}
	}

	/**
	 * Identityを取得する
	 *
	 * @return Identity値
	 * @throws SQLException
	 */
	public long getIdentity(Connection con) throws SQLException {

		PreparedStatement stmt = null;
		try{
			stmt = con.prepareStatement("select identity()");
			ResultSet res = null;
			try {
				res = stmt.executeQuery();

				if (res.next()) {
					long ret = res.getLong(1);
					if (!res.wasNull()){
						return ret;
					}
				}
				throw new SQLException("identityの取得に失敗しました");
			} finally {
				if ( res != null){
					res.close();
				}
			}
		} finally {
			if (stmt != null) {
				stmt.close();
			}
		}
	}



}
#!

#% === DAO Search Action =====================================================================
#! daoSearchAction package
package #package#;

#! daoSearchAction main
/**
 * レコード毎の処理インターフェース
 *
 * @author
 *
 */
public interface RecordAction {

	/**
	 * 初期化
	 *
	 * @throws Exception
	 */
	public void initAction() throws Exception;

	/**
	 * レコード毎に呼び出される処理
	 *
	 * @param record
	 *            処理を行うレコード
	 */
	public void action(Object record) throws Exception;

	/**
	 * 終了
	 *
	 * @throws Exception
	 */
	public void closeAction() throws Exception;
}
#!

#% === DAO Search Action =====================================================================
#! recordSearch package
package #package#;

#! recordSearch main
/**
 * レコード検索インターフェース
 *
 * @author
 *
 */
public interface RecordSearch {

	/**
	 * 以下の順番で処理を行う<br>
	 * 1.レコード毎の処理インターフェースオブジェクト#initActionを呼び出す<br>
	 * 2.レコードを検索し検索されたレコード毎にレコード毎の処理インターフェースオブジェクト#actionを呼び出す<br>
	 * 3.処理が終了したらレコード毎の処理インターフェースオブジェクト#initActionを呼び出す
	 *
	 * @param searchAction
	 *            レコード毎の処理インターフェースオブジェクト
	 * @throws Exception
	 */
	public void search(RecordAction searchAction) throws Exception;

}
#!
