/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/

//
//	ステータスLOログデータアクセスクラス
//			変更履歴
//				2004.01.08	新規作成	二條智文
//
package jp.co.ntt.lms.lo;

// java AIP
import java.util.*;
import java.sql.*;
import java.sql.SQLException;

import org.apache.commons.lang.StringEscapeUtils;

// XMS API
import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.lo.LoLogRecord;

import jp.co.ntt.lms.xmo.Environment;

import jp.co.ntt.lms.xmo.util.*;

/**
 * ステータスLOログ　データアクセスクラスです。<BR>
 * @version 0.0.0.1 2004/01/08
 * @author T.Nijou
 */
public class LoLogDataAccess
{

	/** テーブル名を保持します */
	private static final String TABLE_NAME = "LOLog";

	/** LOテーブル名を保持します */
	private static final String RELATION_TABLE_NAME = "LO";

	/** テーブル定義 */
	private static final String FULLSCORE 			= "fullscore";			// 満点
	private static final String STUDY_START_DATE 	= "study_start_date";	// 学習開始日時
	private static final String RESIDANCETIME 		= "residanceTime";		// 累積滞在時間
	private static final String PASSDAY 			= "passday";			// 合格日
	private static final String STUDY_END_DATE 		= "study_end_date";		// 修了日
	private static final String HIGHTSCORE 			= "highScore";			// 最高点
	private static final String LOWSSCORE 			= "lowsScore";			// 最低点
	private static final String EXECISE_POINT 		= "execise_point";		// 得点
	private static final String USERID 				= "UserID";				// ユーザID
	private static final String LOID 				= "LOID";				// LOID
	private static final String CONDITION_KEY 		= "condition_key";		// ConditionKey
	private static final String ACCESS_CNT 			= "Access_cnt";			// アクセス回数
	private static final String LAST_ACCESS 		= "last_access";		// 最終アクセス日時

	/** LORelationテーブルのテーブル名とフィールド名を保持します */
	private static final String TABLE_LORELATION = "LORelation";
	private static final String CHILDID = "childID";					// childID
	private static final String PARENTID = "parentID";					// parentID

	private static final String TABLE_LO = "LO";

	/** LOテーブル定義 */
	private static final String REAL_LOID = "RealLOID";					// RealLOID

	// ステータス
	/** 合格ステータス */
	public static final char STATUS_PASSED = 'p';
	/** 修了ステータス */
	public static final char STATUS_COMPLETED = 'c';
	/** 不合格、未修了、未学習 */
	public static final char STATUS_FAILED = 'f';

	/**
	 * コンストラクタ
	 **/
	public LoLogDataAccess() {
	}

	/**
	 * ステータスLOログテーブルへ登録処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DB操作に失敗した場合
	 * @exception LOException LO独自例外
	 */
	public void insert( LoLogRecord[] objLoLog )
		throws LOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			// 登録処理を実行します(配列数文ループ)
			for( int i = 0; i < objLoLog.length; i++ ) {
				insertActionCheck( objLoLog[i], objDataAccess );
			}

			// コミット処理
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			e.printStackTrace();
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * ステータスLOログテーブルへ登録処理を行います
	 * @param objLoLog ログ情報データクラス
 	 * @param objDataAccess データアクセスクラス
	 * @exception SQLException DB操作に失敗した場合
	 * @exception LOException LO独自例外
	 */
	public void insert( LoLogRecord[] objLoLog, DataAccess objDataAccess)
		throws LOException
	{
		try {

			// 登録処理を実行します(配列数文ループ)
			for( int i = 0; i < objLoLog.length; i++ ) {
				insertActionCheck( objLoLog[i], objDataAccess );
			}

		}
		catch( SQLException e ) {
			e.printStackTrace();
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * ステータスLOログテーブルへ登録処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DB操作に失敗した場合
	 * @exception LOException LO独自例外
	 */
	public void insert( LoLogRecord objLoLog )
		throws LOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			// 登録処理を実行します(配列数文ループ)
			insertActionCheck( objLoLog, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			e.printStackTrace();
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * ステータスLOログテーブルへの登録処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DBエラー
	 */
	private void insertAction( LoLogRecord objLoLog, DataAccess objDataAccess )
		throws SQLException
	{
		try
		{
			// 登録SQL発行用のHashtable
			Hashtable htbData = new Hashtable();

			// DBに登録するデータをハッシュテーブルに格納します
			if(objLoLog.getFullScore() != null){
				if(!objLoLog.getFullScore().equals("")){
					htbData.put( FULLSCORE, objLoLog.getFullScore() );
				}
			}

			if(objLoLog.getStudyStartDate() != null){
				if(!objLoLog.getStudyStartDate().equals("")){
					htbData.put( STUDY_START_DATE, objLoLog.getStudyStartDate() );
				}
			}

			if(objLoLog.getResidanceTime() != null){
				if(!objLoLog.getResidanceTime().equals("")){
					htbData.put( RESIDANCETIME, objLoLog.getResidanceTime() );
				}
			}

			if(objLoLog.getPassday() != null){
				if(!objLoLog.getPassday().equals("")){
					htbData.put( PASSDAY, objLoLog.getPassday() );
				}
			}

			if(objLoLog.getStudyEndDate() != null){
				if(!objLoLog.getStudyEndDate().equals("")){
					htbData.put( STUDY_END_DATE, objLoLog.getStudyEndDate() );
				}
			}

			if(objLoLog.getAccessCnt() != null){
				if(!objLoLog.getAccessCnt().equals("")){
					htbData.put( ACCESS_CNT, objLoLog.getAccessCnt() );
				}
			}

			if(objLoLog.getLastAccess() != null ){
				if(!objLoLog.getLastAccess().equals("")){
					htbData.put( LAST_ACCESS, objLoLog.getLastAccess() );
				}
			}

			if(objLoLog.getHighScore() != null ){
				if(!objLoLog.getHighScore().equals("")){
					htbData.put( HIGHTSCORE, objLoLog.getHighScore() );
				}
			}

			if(objLoLog.getLowScore() != null ){
				if(!objLoLog.getLowScore().equals("")){
					htbData.put( LOWSSCORE, objLoLog.getLowScore() );
				}
			}

			if(objLoLog.getExecisePoint() != null ){
				if(!objLoLog.getExecisePoint().equals("")){
					htbData.put( EXECISE_POINT, objLoLog.getExecisePoint() );
				}
			}

			if(objLoLog.getUserID() != null ){
				if(!objLoLog.getUserID().equals("")){
					htbData.put( USERID, objLoLog.getUserID() );
				}
			}

			if(objLoLog.getLoID() != null ){
				if(!objLoLog.getLoID().equals("")){
					htbData.put( LOID, objLoLog.getLoID() );
				}
			}

			// 登録用SQLを生成します
			String strSQL = objDataAccess.getInsertSQL( htbData, TABLE_NAME );

			// 登録処理を実行
			objDataAccess.execute( strSQL );
		}
		catch ( SQLException se )
		{
			se.printStackTrace();
			DebugLog.write( this.getClass(), se, DebugLog.HIGHT );
			// データベースエラーを設定
			throw new SQLException( se.getMessage() );
		}
	}

	/**
	 * ステータスLOログテーブルへの登録処理を行います
	 * @param htbData ログ情報データ
	 * @exception SQLException DBエラー
	 */
	private void insertAction( Hashtable htbData, DataAccess objDataAccess )
		throws SQLException
	{

		// 登録用SQLを生成します
		String strSQL = objDataAccess.getInsertSQL( htbData, TABLE_NAME );

		// 登録処理を実行
		objDataAccess.execute( strSQL );
	}

	/**
	 * ステータスLOログテーブルへの登録処理を行います(重複チェック付き）
	 * @param htbData ログ情報データ
	 * @exception SQLException DBエラー
	 */
	private void insertActionCheck( Hashtable htbData, DataAccess objDataAccess )
		throws SQLException
	{
		// 同じユーザIDとLOIDが同一レコードが存在しない場合のみインサートする。
		if( getLoLog( (String)htbData.get( USERID ), (String)htbData.get( LOID ), objDataAccess ) == null ) {
			// 登録処理
			insertAction( htbData, objDataAccess );
		}
	}

	/**
	 * ステータスLOログテーブルへの登録処理を行います(重複チェック付き）
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DBエラー
	 */
	private void insertActionCheck( LoLogRecord objLoLog, DataAccess objDataAccess )
		throws SQLException
	{
		// 同じユーザIDとLOIDが同一レコードが存在しない場合のみインサートする。
		if( getLoLog( objLoLog.getUserID(), objLoLog.getLoID(), objDataAccess ) == null ) {
			// 登録処理
			insertAction( objLoLog, objDataAccess );
		}
	}
	/**
	 * ステータスLOログテーブルへ更新処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DB操作に失敗した場合
	 * @exception LOException LO独自例外
	 */
	public void update( Hashtable htbParam )
		throws LOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			// LOデータがnullのとき
			if( htbParam != null ) {
				updateAction( htbParam, objDataAccess );
			}

			// コミット処理
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			e.printStackTrace();
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * ステータスLOログテーブルへの更新処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DBエラー
	 */
	private void updateAction( Hashtable htParam, DataAccess objDataAccess )
		throws SQLException
	{
		// 更新処理用のデータをセットします
		Hashtable htbData = setData( htParam );

		//SQLを編集します
		String strExecisePoint = "";
		String strPassDay = "";
		String strEndDay = "";
		String strSQL = "";
		String strAccessCnt = "";
		String strLastAccess = "";
		StringBuffer sbSQL = new StringBuffer();
		//ステータス更新用
		if(htParam.get( "EDIT_SELF" )!=null){
			sbSQL.append("Update " + TABLE_NAME + " Set ");
			//得点
			strExecisePoint = (String)htParam.get( EXECISE_POINT );
			sbSQL.append(strExecisePoint);
			//合格日
			strPassDay = (String)htParam.get( PASSDAY );
			if(sbSQL!=null && strPassDay!=null){
				sbSQL.append(" , " + strPassDay);
			}
			//終了日
			strEndDay = (String)htParam.get( STUDY_END_DATE );
			if(sbSQL!=null && strEndDay!=null){
				sbSQL.append(" , " + strEndDay);
			}
			//アクセス回数
			strAccessCnt = (String)htParam.get( ACCESS_CNT );
			if(sbSQL!=null && strAccessCnt!=null){
				sbSQL.append(" , " + strAccessCnt);
			}
			//最終アクセス日時
			strLastAccess = (String)htParam.get( LAST_ACCESS );

			if(sbSQL!=null && strLastAccess!=null){
				sbSQL.append(" , " + strLastAccess);
			}
			strSQL = sbSQL.toString();
		}
		//その他
		else{
			strSQL = objDataAccess.getUpdateSQL(htbData, TABLE_NAME);
		}

		// 条件文の取得
		String strCondition = (String)htParam.get( CONDITION_KEY );
		if( strCondition != null ) {
			strSQL += strCondition;
		}

		// 更新処理を実行
		objDataAccess.execute( strSQL );
	}

	/**
	 * ステータスLOログテーブルへの更新処理を行います
	 * @param htbParam 更新情報
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 */
	public void updateAction(	Hashtable htbParam,
								String strUserID,
								String strLoID,
								DataAccess objDataAccess )
		throws SQLException
	{
		String strCondition = createCondition( strUserID, strLoID );
		String strSQL = objDataAccess.getUpdateSQL( htbParam, TABLE_NAME );
		strSQL += strCondition;

		// 更新処理を実行
		objDataAccess.execute( strSQL );

	}

	/**
	 * ステータスログを登録または更新します。<BR>
	 * @param objLoLog 更新内容
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @exception LOException LO独自例外
	 */
	public void insertUpdate(	LoLogRecord objLoLog,
								String strUserID,
								String strLoID )
		throws LOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			insertUpdate( objLoLog, strUserID, strLoID, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * ステータスログを登録または更新します。<BR>
	 * トランザクションは上位が行います。
	 * @param objLoLog 更新内容
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @exception SQLException DBエラー
	 */
	public void insertUpdate(	LoLogRecord objLoLog,
								String strUserID,
								String strLoID,
								DataAccess objDataAccess )
		throws SQLException
	{
		// 登録または更新用のHashtableを作成する
		Hashtable htbData = setData( objLoLog );

		// 登録更新を振り分けます
		if( getLoLog( strUserID, strLoID, objDataAccess ) == null ) {
			// 登録処理
			insertAction( htbData, objDataAccess );
		}
		else {
			updateAction( htbData, strUserID, strLoID, objDataAccess );
		}

	}

	/**
	 * ステータスLOログテーブルへ更新処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DB操作に失敗した場合
	 * @exception LOException LO独自例外
	 */
	public void delete( Hashtable htbParam )
		throws LOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			// 削除処理を実行します
			deleteAction( htbParam, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( LOException le ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw le;
		}
		catch( SQLException e ) {
			e.printStackTrace();
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * ステータスLOログテーブルへの削除処理を行います
	 * @param objLoLog ログ情報データクラス
	 * @exception SQLException DBエラー
	 * @exception LOException LO独自例外
	 */
	private void deleteAction( Hashtable htParam, DataAccess objDataAccess )
		throws SQLException, LOException
	{
		// SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "DELETE FROM " + TABLE_NAME );

		// 条件文の取得
		String strCondition = (String)htParam.get( CONDITION_KEY );
		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}
		// 削除処理を実行
		objDataAccess.execute( sbSQL.toString() );
	}

	/**
	 * ユーザIDとLOIDを指定してレコードを削除します。
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @exception SQLException
	 */
	public void delete( String strUserID, String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "DELETE FROM " + TABLE_NAME );
		sbSQL.append( " WHERE " + USERID + "='" + StringEscapeUtils.escapeSql(strUserID) + "' AND " );
		sbSQL.append( LOID + "='" + StringEscapeUtils.escapeSql(strLoID) + "'" );

		objDataAccess.execute( new String( sbSQL ) );
	}

	/**
	 * LOLogテーブルへ検索処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	public Vector select( Hashtable htbParam )
		throws LOException
	{
		// 戻り値
		Vector vecReturn = new Vector();
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			// LOデータがnullのとき
			if( htbParam != null ) {
				vecReturn = selectAction( htbParam, objDataAccess );
			}

			// コミット処理
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			e.printStackTrace();
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
		return vecReturn;
	}


	/**
	 * ユーザIDとLOIDを指定して、検索を行います
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @return LoLogRecord[] 検索結果 検索結果がない場合はnull
	 * @exception LOException LO独自例外
	 */
	public LoLogRecord getLoLog( String strUserID, String strLoID )
		throws LOException
	{
		if( strUserID == null && strLoID == null ) {
			return null;
		}

		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		LoLogRecord objRecord = null;
		try {
			// トランザクションを開始する
			objDataAccess.trans();
			// SQL組み立て
			StringBuffer sbSQL = new StringBuffer();
			sbSQL.append("SELECT * FROM ");
			sbSQL.append(TABLE_NAME);
			sbSQL.append(" WHERE ");
			sbSQL.append( USERID );
			sbSQL.append( "='" );
			sbSQL.append( StringEscapeUtils.escapeSql(strUserID) );
			sbSQL.append( "' AND " );
			sbSQL.append( LOID );
			sbSQL.append( "='" );
			sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
			sbSQL.append( "'" );
			// 検索処理を実行します
			ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());
			while(rs.next()) {
				objRecord = new LoLogRecord();
				objRecord.setFullScore( rs.getString( FULLSCORE ) );
				objRecord.setStudyStartDate( XMODate.parseTime(rs.getTimestamp( STUDY_START_DATE )) );
				objRecord.setResidanceTime( rs.getString( RESIDANCETIME ) );
				objRecord.setPassday( XMODate.parseTime(rs.getTimestamp( PASSDAY ) ));
				objRecord.setStudyEndDate( XMODate.parseTime(rs.getTimestamp( STUDY_END_DATE ) ));
				objRecord.setHighScore( rs.getString( HIGHTSCORE ) );
				objRecord.setLowScore( rs.getString( LOWSSCORE ) );
				objRecord.setExecisePoint( rs.getString( EXECISE_POINT ) );
				objRecord.setUserID( rs.getString( USERID ) );
				objRecord.setLoID( rs.getString( LOID ) );
				objRecord.setAccessCnt( rs.getString( ACCESS_CNT ) );
				objRecord.setLastAccess( XMODate.parseTime(rs.getTimestamp( LAST_ACCESS )) );
			}
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
		return objRecord;
	}

	/**
	 * ユーザIDとLOIDを指定して、検索を行います<BR>
	 * このメソッドを使用する際はトランザクションは上位で管理します。
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @return LoLogRecord[] 検索結果 検索結果がない場合はnull
	 * @excetption SQLException DBエラー
	 */
	public LoLogRecord getLoLog( String strUserID, String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		if( strUserID == null && strLoID == null ) {
			return null;
		}

		// SQL組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append("SELECT * FROM ");
		sbSQL.append(TABLE_NAME);
		try{
			//XMS.iniファイルロードクラスのインスタンス
			Environment objEnv=new Environment();
			//SQLServerの場合
			if(objEnv.getDBType().equals( objEnv.DB_SQLSERVER )){
				sbSQL.append(" WITH (TABLOCKX) ");
			}
			sbSQL.append(" WHERE ");
			sbSQL.append( USERID );
			sbSQL.append( "='" );
			sbSQL.append( StringEscapeUtils.escapeSql(strUserID) );
			sbSQL.append( "' AND " );
			sbSQL.append( LOID );
			sbSQL.append( "='" );
			sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
			sbSQL.append( "'" );
			//Oracle場合 OR PostgreSQL場合
			if(objEnv.getDBType().equals( objEnv.DB_ORACLE ) || objEnv.getDBType().equals( objEnv.DB_POSTGRE )){ 
				sbSQL.append( " FOR UPDATE" );
			}
			
		}
		catch(Exception ex)
		{

		}
		// 検索処理を実行します
		DebugLog.write( this.getClass(), sbSQL.toString(), DebugLog.ROW );
		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());
		LoLogRecord objData = null;

		while(rs.next()) {
			objData = new LoLogRecord();
			objData.setFullScore( rs.getString( FULLSCORE ) );
			objData.setStudyStartDate( XMODate.parseTime(rs.getTimestamp( STUDY_START_DATE )) );
			objData.setResidanceTime( rs.getString( RESIDANCETIME ) );
			objData.setPassday( XMODate.parseTime(rs.getTimestamp( PASSDAY ) ));
			objData.setStudyEndDate( XMODate.parseTime(rs.getTimestamp( STUDY_END_DATE ) ));
			objData.setHighScore( rs.getString( HIGHTSCORE ) );
			objData.setLowScore( rs.getString( LOWSSCORE ) );
			objData.setExecisePoint( rs.getString( EXECISE_POINT ) );
			objData.setUserID( rs.getString( USERID ) );
			objData.setLoID( rs.getString( LOID ) );
			objData.setAccessCnt( rs.getString( ACCESS_CNT ) );

			objData.setLastAccess( XMODate.parseTime(rs.getTimestamp( LAST_ACCESS )) );
		}
		return objData;
	}

	/**
	 * コピー元のLOIDを指定して、検索を行います
	 * 検索後に取得したLOIDをコピー先のLOIDに置換し、データをセットします。
	 * 検索結果は複数となるため、戻り値は配列のLoLogRecordとなります。
	 * このメソッドを使用する際はトランザクションは上位で管理します。
	 * @param strLoID コピー元のLOID
	 * @param strCopyLoID コピー先のLOID
	 * @param objDataAccess データアクセスオブジェクト
	 * @return LoLogRecord[] 検索結果 検索結果がない場合はnull
	 * @excetption SQLException DBエラー
	 */
	public LoLogRecord[] getCopyLoLog( String strLoID, String strCopyLoID, DataAccess objDataAccess )
		throws SQLException
	{
		if( strLoID == null && strCopyLoID == null ) {
			return null;
		}

		// SQL組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append("SELECT * FROM ");
		sbSQL.append(TABLE_NAME);
		try{
			//XMS.iniファイルロードクラスのインスタンス
			Environment objEnv=new Environment();
			//SQLServerの場合
			if(objEnv.getDBType().equals( objEnv.DB_SQLSERVER )){
				sbSQL.append(" WITH (TABLOCKX) ");
			}

			sbSQL.append(" WHERE ");
			sbSQL.append( LOID );
			sbSQL.append( "='" );
			sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
			sbSQL.append( "'" );

			//Oracle場合 OR PostgreSQL場合
			if(objEnv.getDBType().equals( objEnv.DB_ORACLE ) || objEnv.getDBType().equals( objEnv.DB_POSTGRE )){ 
				sbSQL.append( " FOR UPDATE" );
			}
		}
		catch(Exception ex)
		{

		}

		// 検索処理を実行します
		DebugLog.write( this.getClass(), sbSQL.toString(), DebugLog.ROW );
		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());
		LoLogRecord objData = null;
		Vector vecLoLogRecord = new Vector();
		while(rs.next()) {

			// LoLogデータ取得
			String strFullScore = rs.getString( FULLSCORE );
			String strStudyStartDate = XMODate.parseTime(rs.getTimestamp( STUDY_START_DATE ));
			String strResidenceTime = rs.getString( RESIDANCETIME );
			String strPassDay = XMODate.parseTime(rs.getTimestamp( PASSDAY ));
			String strStudyEndDate = XMODate.parseTime(rs.getTimestamp( STUDY_END_DATE ));
			String strHighScore = rs.getString( HIGHTSCORE );
			String strLowScore = rs.getString( LOWSSCORE );
			String strExecisePoint = rs.getString( EXECISE_POINT );
			String strUserID = rs.getString( USERID );
			//コピー先のLOIDに置換する
			String strLOID = strCopyLoID;
			String strAccessCnt = rs.getString( ACCESS_CNT );
			String strLastAccess = XMODate.parseTime(rs.getTimestamp( LAST_ACCESS ));
			// LoLogデータセット
			objData = new LoLogRecord();
			objData.setFullScore( strFullScore );
			objData.setStudyStartDate( strStudyStartDate );
			objData.setResidanceTime( strResidenceTime );
			objData.setPassday( strPassDay );
			objData.setStudyEndDate( strStudyEndDate );
			objData.setHighScore( strHighScore );
			objData.setLowScore( strLowScore );
			objData.setExecisePoint( strExecisePoint );
			objData.setUserID( strUserID );
			objData.setLoID( strLOID );
			objData.setAccessCnt( strAccessCnt );
			objData.setLastAccess( strLastAccess );

			//objDataをVectorにセット
			vecLoLogRecord.add(objData);
		}

		//vecLoLogRecordの中身を、LoLogRecord[]配列にコピーする。
		LoLogRecord[] objLoLogRecord = new LoLogRecord[vecLoLogRecord.size()];
		vecLoLogRecord.copyInto( objLoLogRecord );

		return objLoLogRecord;
	}

	/**
	 * 検索処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 検索情報
	 * @return Vector 検索結果
	 * @exception SQLException DBエラーが発生した場合
	 */
	private Vector selectAction( Hashtable htParam, DataAccess objDataAccess )
		throws SQLException
	{

		// SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT * FROM " + TABLE_NAME );
		// 条件文の取得
		String strCondition = (String)htParam.get( CONDITION_KEY );

		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}
		else {
			sbSQL.append( createCondition( htParam ) );
		}

		// クエリーを実行します
		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

		Vector vecReturn = new Vector();
		Vector vecRet = new Vector();
		while(rs.next()) {
			String strFullScore = rs.getString( FULLSCORE );
			String strStudyStartDate = XMODate.parseTime(rs.getTimestamp( STUDY_START_DATE ));
			String strResidenceTime = rs.getString( RESIDANCETIME );
			String strPassDay = XMODate.parseTime(rs.getTimestamp( PASSDAY ));
			String strStudyEndDate = XMODate.parseTime(rs.getTimestamp( STUDY_END_DATE ));
			String strHighScore = rs.getString( HIGHTSCORE );
			String strLowScore = rs.getString( LOWSSCORE );
			String strExecisePoint = rs.getString( EXECISE_POINT );
			String strUserID = rs.getString( USERID );
			String strLOID = rs.getString( LOID );
			String strAccessCnt = rs.getString( ACCESS_CNT );
			String strLastAccess = rs.getString( LAST_ACCESS );
			LoLogRecord objData = new LoLogRecord();
			objData.setFullScore( strFullScore );
			objData.setStudyStartDate( strStudyStartDate );
			objData.setResidanceTime( strResidenceTime );
			objData.setPassday( strPassDay );
			objData.setStudyEndDate( strStudyEndDate );
			objData.setHighScore( strHighScore );
			objData.setLowScore( strLowScore );
			objData.setExecisePoint( strExecisePoint );
			objData.setUserID( strUserID );
			objData.setLoID( strLOID );
			objData.setAccessCnt( strAccessCnt );
			objData.setLastAccess( strLastAccess );

			vecReturn.add( objData );
		}

		vecRet.add(vecReturn);

		return vecRet;

	}

	/**
	 * ステータスを返します。<BR>
	 * トランザクションの管理は上位で行ってください。
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @return boolean[] ステータス
	 * <PRE>
	 *      boolean[0] :: 合格日付に日付が入っているかどうか（入っている: true、入っていない or レコードがない: false)
	 *      boolean[1] :: 完了日付に日付が入っているかどうか（入っている: true、入っていない or レコードがない: false)
	 * </PRE>
	 * @exception SQLException DBエラー
	 */
	public boolean[] getStatus( String strUserID, String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		// 検索SQLの作成
		sbSQL.append( "SELECT " );
		sbSQL.append( STUDY_END_DATE );
		sbSQL.append( "," );
		sbSQL.append( PASSDAY );
		sbSQL.append( "," );
		sbSQL.append( STUDY_START_DATE );
		sbSQL.append( " FROM " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( " WHERE " );
		sbSQL.append( USERID );
		sbSQL.append( "='" );
		sbSQL.append( StringEscapeUtils.escapeSql(strUserID) );
		sbSQL.append( "' AND " );
		sbSQL.append( LOID );
		sbSQL.append( "='" );
		sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
		sbSQL.append( "'" );

		// 戻り値
		boolean[] blStatus = new boolean[3];
		blStatus[0] = false;
		blStatus[1] = false;
		blStatus[2] = false;

		// 検索処理
		ResultSet rs = objDataAccess.executeQuery( sbSQL.toString() );
		String strPassDay = null;
		String strStudyEndDate = null;
		String strStudyStartDate = null;
		if( rs.next() ) {
			strStudyEndDate = rs.getString( STUDY_END_DATE );
			strPassDay = rs.getString( PASSDAY );
			strStudyStartDate = rs.getString( STUDY_START_DATE );
		}

		// 合格日付が登録されていた場合はpassed
		if( strPassDay != null && !strPassDay.equals( "" ) ) {
			blStatus[0] = true;
		}

		// 修了日付が登録されていた場合はcompleted
		if( strStudyEndDate != null && !strStudyEndDate.equals( "" ) ) {
			blStatus[1] = true;
		}

		// 学習開始日付が登録されていた場合はcompleted
		if( strStudyStartDate != null && !strStudyStartDate.equals( "" ) ) {
			blStatus[2] = true;
		}

		return blStatus;

	}

	/**
	 * 合格しているかどうか返します。
	 * トランザクションの管理は上位で行ってください。
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @return boolean true: 合格している false: 合格していない
	 * @exception SQLException DBエラー
	 */
	public boolean isPassed( String strUserID, String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		// 検索SQLの作成
		sbSQL.append( "SELECT " );
		sbSQL.append( PASSDAY );
		sbSQL.append( " FROM " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( " WHERE " );
		sbSQL.append( USERID );
		sbSQL.append( "='" );
		sbSQL.append( StringEscapeUtils.escapeSql(strUserID) );
		sbSQL.append( "' AND " );
		sbSQL.append( LOID );
		sbSQL.append( "='" );
		sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
		sbSQL.append( "'" );

		// 検索処理
		ResultSet rs = objDataAccess.executeQuery( sbSQL.toString() );
		String strPassDay = "";
		if( rs.next() ) {
			strPassDay = rs.getString( PASSDAY );
		}
		else {
			// 検索条件が0件の場合は未学習
			return false;
		}

		// 修了日付が登録されていた場合はpassed
		if( strPassDay != null && !strPassDay.equals( "" ) ) {
			return true;
		}

		return false;

	}

	/**
	 * 完了しているかどうか返します。
	 * トランザクションの管理は上位で行ってください。
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @return boolean true: 完了している false: 完了していない
	 * @exception SQLException DBエラー
	 */
	public boolean isCompleted( String strUserID, String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		// 検索SQLの作成
		sbSQL.append( "SELECT " );
		sbSQL.append( STUDY_END_DATE );
		sbSQL.append( " FROM " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( " WHERE " );
		sbSQL.append( USERID );
		sbSQL.append( "='" );
		sbSQL.append( StringEscapeUtils.escapeSql(strUserID) );
		sbSQL.append( "' AND " );
		sbSQL.append( LOID );
		sbSQL.append( "='" );
		sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
		sbSQL.append( "'" );

		// 検索処理
		ResultSet rs = objDataAccess.executeQuery( sbSQL.toString() );
		String strStudyEndDate = "";
		if( rs.next() ) {
			strStudyEndDate = rs.getString( STUDY_END_DATE );
		}
		else {
			// 検索条件が0件の場合は未学習
			return false;
		}

		// 修了日付が登録されていた場合はcompleted
		if( strStudyEndDate != null && !strStudyEndDate.equals( "" ) ) {
			return true;
		}

		return false;

	}

	/**
	 * パラメータで渡ってきたLOIDに対応するRealLOIDのログを持っているUserIDをLOLogテーブルから
	 * 抽出し、そのリストをString配列で返却します。
	 * トランザクションの管理は上位で行ってください。
	 * @param strLoID LOID
	 * @param objDataAccess データベースアクセスオブジェクト
	 * @return String[] UserIDリスト(取得不可の場合は空のString配列を返却)
	 * @exception SQLException DBエラー
	 */
	public String[] getUserList( String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		// 子LOのユーザリスト取得SQLの作成
		sbSQL.append( "SELECT DISTINCT " );
		sbSQL.append( TABLE_NAME + "." + USERID );
		sbSQL.append( " FROM " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( " INNER JOIN ");
		sbSQL.append( TABLE_LO );
		sbSQL.append( " ON " );
		sbSQL.append( TABLE_NAME + "." + LOID );
		sbSQL.append( " = " );
		sbSQL.append( TABLE_LO + "." + REAL_LOID );
		sbSQL.append( " INNER JOIN " );
		sbSQL.append( TABLE_LORELATION );
		sbSQL.append( " ON " );
		sbSQL.append( TABLE_LO + "." + LOID);
		sbSQL.append( " = " );
		sbSQL.append( TABLE_LORELATION + "." + CHILDID );
		sbSQL.append( " WHERE " );
		sbSQL.append( TABLE_LORELATION + "." + PARENTID + " = '" + StringEscapeUtils.escapeSql(strLoID) + "'" );
		sbSQL.append( " OR " );
		sbSQL.append( TABLE_LORELATION + "." + CHILDID + " = '" + StringEscapeUtils.escapeSql(strLoID) + "'"  );

		// ユーザリストの取得
		ResultSet rs = objDataAccess.executeQuery( sbSQL.toString() );

		Vector vecUserList = new Vector();
		while( rs.next() ) {
			vecUserList.add(rs.getString( USERID ));
		}

		// 自身のログのユーザリストを取得


		String[] strUserList = new String[vecUserList.size()];

		vecUserList.copyInto(strUserList);

		//ユーザリストの返却
		return strUserList;

	}

	/**
	 * パラメータで渡ってきたUserID,LOIDをKeyにして、得点、最高得点、最低得点、満点、累積学習時間
	 * 学習開始日時(一番古い日時)のそれぞれの合計を抽出する
	 * トランザクションの管理は上位で行ってください。
	 * @param strLoID	LOID
	 * @param strUserID UserID
	 * @param objDataAccess データベースアクセスオブジェクト
	 * @return LoLogRecord ステータスLOログオブジェクトを返却
	 * @exception SQLException DBエラー
	 */
	public LoLogRecord getTotal( String strUserID, String strLoID, DataAccess objDataAccess )
		throws SQLException
	{

		StringBuffer sbSQL = new StringBuffer();
		// 各フィールドの合計値取得SQLの作成
		sbSQL.append( "SELECT " );
		sbSQL.append( "SUM(" );
		sbSQL.append( EXECISE_POINT );
		sbSQL.append( ") As SUMexecise_point, " );
		sbSQL.append( "SUM(" );
		sbSQL.append( HIGHTSCORE );
		sbSQL.append( ") As SUMhighScore, " );
		sbSQL.append( "SUM(" );
		sbSQL.append( LOWSSCORE );
		sbSQL.append( ") As SUMlowsScore, " );
		sbSQL.append( "SUM(" );
		sbSQL.append( FULLSCORE );
		sbSQL.append( ") As SUMfullscore, " );
		try{
			//XMS.iniファイルロードクラスのインスタンス
			Environment objEnv=new Environment();
			//SQLServerの場合
			if(objEnv.getDBType().equals( objEnv.DB_SQLSERVER )){
				sbSQL.append( "ISNULL(SUM(" );
			//Oracleの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
				sbSQL.append( "NVL(SUM(" );
			//PostgreSQLの場合	
			}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
				sbSQL.append( "COALESCE(SUM(" );
			}
			sbSQL.append( RESIDANCETIME );
			sbSQL.append( "), 0) AS  SUMresidanceTime, " );
			sbSQL.append( "MIN(" );
			sbSQL.append( STUDY_START_DATE );
			sbSQL.append( ") As MINstudy_start_date, " );
			//SQLServerの場合
			if(objEnv.getDBType().equals( objEnv.DB_SQLSERVER )){
				sbSQL.append( "ISNULL(SUM(" );
			}
			//Oracleの場合
			else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
				sbSQL.append( "NVL(SUM(" );			
			//PostgreSQLの場合	
			}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
				sbSQL.append( "COALESCE(SUM(" );
			}
		}
		catch(Exception ex)
		{

		}
		sbSQL.append( ACCESS_CNT );
		sbSQL.append( "), 0)  AS SUMAccessCnt, " );
		sbSQL.append( "MAX(" );
		sbSQL.append( LAST_ACCESS );
		sbSQL.append( ") As MAXLastAccess," );

// 2005.03.10 LOステータスロールアップ処理変更 NTTレゾナント(Y.URATA) ADD start
		sbSQL.append( "MAX(" );
		sbSQL.append( PASSDAY );
		sbSQL.append( ") As MAXPassday, " );
		sbSQL.append( "MAX(" );
		sbSQL.append( STUDY_END_DATE );
		sbSQL.append( ") As MAXstudy_end_date" );
// 2005.03.10 ADD end

		sbSQL.append( " FROM " );
		sbSQL.append( TABLE_NAME );

		sbSQL.append( " INNER JOIN ");
		sbSQL.append( RELATION_TABLE_NAME );
		sbSQL.append( " ON " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( "." );
		sbSQL.append( LOID );
		sbSQL.append( " = " );
		sbSQL.append( RELATION_TABLE_NAME );
		sbSQL.append( "." );
		sbSQL.append( REAL_LOID );
		sbSQL.append( " INNER JOIN ");
		sbSQL.append( TABLE_LORELATION );
		sbSQL.append( " ON " );
		sbSQL.append( RELATION_TABLE_NAME );
		sbSQL.append( "." );
		sbSQL.append( LOID );
		sbSQL.append( " = " );
		sbSQL.append( TABLE_LORELATION );
		sbSQL.append( "." );
		sbSQL.append( CHILDID );

		sbSQL.append( " Where " );
		sbSQL.append( TABLE_LORELATION );
		sbSQL.append( ".");
		sbSQL.append( PARENTID );
		sbSQL.append( " = '" );
		sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
		sbSQL.append( "'" );
		sbSQL.append( " And " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( "." );
		sbSQL.append( USERID );
		sbSQL.append( " = '" );
		sbSQL.append( StringEscapeUtils.escapeSql(strUserID) );
		sbSQL.append( "'" );
		// 各フィールドの合計値の取得
		DebugLog.write( this.getClass(), sbSQL.toString(), DebugLog.ROW );
		ResultSet rs = objDataAccess.executeQuery( sbSQL.toString() );

		// ステータスLOログクラス
		LoLogRecord objLoLogRecord = new LoLogRecord();
		objLoLogRecord.initialize();

		if( rs.next() ) {

			// 人ID設定
			objLoLogRecord.setUserID(strUserID);

			// LOID設定
			objLoLogRecord.setLoID(strLoID);

			// 得点設定
			objLoLogRecord.setExecisePoint(rs.getString( "SUMexecise_point" ));
			if( objLoLogRecord.getExecisePoint() == null ) {
				objLoLogRecord.setExecisePoint("");
			}

			// 最高点設定
			objLoLogRecord.setHighScore(rs.getString( "SUMhighScore" ));
			if( objLoLogRecord.getHighScore() == null ) {
				objLoLogRecord.setHighScore("");
			}

			// 最低点設定
			objLoLogRecord.setLowScore(rs.getString( "SUMlowsScore" ));
			if( objLoLogRecord.getLowScore() == null ) {
				objLoLogRecord.setLowScore("");
			}

			// 満点設定
			objLoLogRecord.setFullScore(rs.getString( "SUMfullscore" ));
			if( objLoLogRecord.getFullScore() == null ) {
				objLoLogRecord.setFullScore("");
			}

			// 開始日設定
			objLoLogRecord.setStudyStartDate(XMODate.parseTime(rs.getTimestamp( "MINstudy_start_date" )));

			// 累計滞在時間設定
			objLoLogRecord.setResidanceTime(rs.getString( "SUMresidanceTime" ));

			// アクセス回数設定
			objLoLogRecord.setAccessCnt(rs.getString( "SUMAccessCnt" ));
			if( objLoLogRecord.getAccessCnt() == null ) {
				objLoLogRecord.setAccessCnt("");
			}

			// 最終アクセス日設定
			objLoLogRecord.setLastAccess(XMODate.parseTime(rs.getTimestamp( "MAXLastAccess" )));
			if( objLoLogRecord.getLastAccess() == null ) {
				objLoLogRecord.setLastAccess("");
			}

// 2005.03.10 LOステータスロールアップ処理変更 NTTレゾナント(Y.URATA) ADD start
			// 合格日設定
			objLoLogRecord.setPassday(XMODate.parseTime(rs.getTimestamp( "MAXPassday" )));
			if( objLoLogRecord.getPassday() == null ) {
				objLoLogRecord.setPassday("");
			}
			
			// 完了日設定
			objLoLogRecord.setStudyEndDate(XMODate.parseTime(rs.getTimestamp( "MAXstudy_end_date" )));
			if( objLoLogRecord.getStudyEndDate() == null ) {
				objLoLogRecord.setStudyEndDate("");
			}				
// 2005.03.10 ADD end
		}

		// ステータスLOログオブジェクトを返却
		return objLoLogRecord;

	}

	/**
	 * LOLogテーブル 学習回数取得処理
	 * @param strUserID 検索条件
	 * @param strLOID 検索条件
	 * @param objDataAccess
	 */
	public int getStudyCount( String strUserID, String strLOID, DataAccess objDataAccess)
		throws SQLException
	{
		int intSutudyCnt = 0;

		// 検索SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append("SELECT ");
		sbSQL.append(ACCESS_CNT);
		sbSQL.append(" FROM ");
		sbSQL.append(TABLE_NAME);
		sbSQL.append(" WHERE ");
		sbSQL.append(LOID);
		sbSQL.append(" = '");
		sbSQL.append(StringEscapeUtils.escapeSql(strLOID));
		sbSQL.append("' AND ");
		sbSQL.append(USERID);
		sbSQL.append(" = '");
		sbSQL.append(StringEscapeUtils.escapeSql(strUserID));
		sbSQL.append("'");

		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

		while( rs.next() ) {
			// 教材URLを取得
			intSutudyCnt = rs.getInt( ACCESS_CNT );
		}

		return intSutudyCnt;
	}
	/**
	 * LOLogテーブル 最終アクセス日時取得処理
	 * @param strUserID 検索条件
	 * @param strLOID 検索条件
	 * @param objDataAccess
	 */

	public Timestamp getLastAccess( String strUserID, String strLOID, DataAccess objDataAccess)
		throws SQLException

	{

		Timestamp tsLastAccess = null;

		// 検索SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append("SELECT ");
		sbSQL.append(LAST_ACCESS);
		sbSQL.append(" FROM ");
		sbSQL.append(TABLE_NAME);
		sbSQL.append(" WHERE ");
		sbSQL.append(LOID);
		sbSQL.append(" = '");
		sbSQL.append(StringEscapeUtils.escapeSql(strLOID));
		sbSQL.append("' AND ");
		sbSQL.append(USERID);
		sbSQL.append(" = '");
		sbSQL.append(StringEscapeUtils.escapeSql(strUserID));
		sbSQL.append("'");

		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

		while( rs.next() ) {
			// 最終アクセス日を取得

			tsLastAccess =  rs.getTimestamp( LAST_ACCESS );

		}

		return tsLastAccess;
	}
	/**
	 * 登録、更新処理時のデータを組み立てます
	 * @param htData
	 * @return Hashtable
	 */
	private Hashtable setData( Hashtable htbParam ) {
		Hashtable htbData = new Hashtable();
		putData( htbData, htbParam, FULLSCORE );
		putData( htbData, htbParam, STUDY_START_DATE );
		putData( htbData, htbParam, RESIDANCETIME );
		putData( htbData, htbParam, PASSDAY );
		putData( htbData, htbParam, STUDY_END_DATE );
		putData( htbData, htbParam, HIGHTSCORE );
		putData( htbData, htbParam, LOWSSCORE );
		putData( htbData, htbParam, EXECISE_POINT );
		putData( htbData, htbParam, USERID );
		putData( htbData, htbParam, LOID );
		putData( htbData, htbParam, ACCESS_CNT );
		putData( htbData, htbParam, LAST_ACCESS );

		return htbData;
	}

	/**
	 * 登録、更新処理時のデータをLoLogRecordから作成します
	 * @param objLoLogRecord
	 */
	private Hashtable setData( LoLogRecord objRecord ) {
		Hashtable htbData = new Hashtable();
		putData( htbData, FULLSCORE, objRecord.getFullScore() );
		putData( htbData, STUDY_START_DATE, objRecord.getStudyStartDate() );
		putData( htbData, RESIDANCETIME, objRecord.getResidanceTime() );
		putData( htbData, PASSDAY, objRecord.getPassday() );
		putData( htbData, STUDY_END_DATE, objRecord.getStudyEndDate() );
		putData( htbData, HIGHTSCORE, objRecord.getHighScore() );
		putData( htbData, LOWSSCORE, objRecord.getLowScore() );
		putData( htbData, EXECISE_POINT, objRecord.getExecisePoint() );
		putData( htbData, USERID, objRecord.getUserID() );
		putData( htbData, LOID, objRecord.getLoID() );
		putData( htbData, ACCESS_CNT, objRecord.getAccessCnt() );

		putData( htbData, LAST_ACCESS, objRecord.getLastAccess() );

		return htbData;
	}

	/**
	 * 安全にHashtableに追加するメソッドです
	 */
	private void putData( Hashtable htbData, Hashtable htbParam, String strKey ) {
		String strValue = (String)htbParam.get( strKey );

		if( strValue != null ) {
			htbData.put( strKey, strValue );
		}
	}

	/**
	 * 安全にHashtableに追加するメソッドです
	 */
	private void putData( Hashtable htbData, String strKey, String strValue ) {
		if( strKey == null || strValue == null ) {
			return;
		}
		htbData.put( strKey, strValue );
	}

	/**
	 * HashtableからユーザIDとLOIDを取得して条件文を作成します
	 */
	private String createCondition( Hashtable htbData ) {
		String strUserID = (String)htbData.get( USERID );
		String strLoID = (String)htbData.get( LOID );
		return createCondition( strUserID, strLoID );
	}

	/**
	 * ユーザIDとLOIDから条件文を作成します
	 */
	private String createCondition( String strUserID, String strLoID ) {

		String strUserIDCon = null;
		String strLoIDCon = null;
		StringBuffer sbCondition = new StringBuffer();
		if( strUserID != null ) {
			strUserIDCon = USERID + " ='" + StringEscapeUtils.escapeSql(strUserID) + "'";
		}
		if( strLoID != null ) {
			strLoIDCon = LOID + " ='" + StringEscapeUtils.escapeSql(strLoID) + "'";
		}

		if( strUserIDCon != null || strLoIDCon != null ) {
			sbCondition.append( " WHERE " );
			if( strUserIDCon != null ) {
				sbCondition.append( strUserIDCon );
				if( strLoIDCon != null ) {
					sbCondition.append( " AND " );
				}
			}
			if( strLoIDCon != null ) {
				sbCondition.append( strLoIDCon );
			}
		}

		return sbCondition.toString();
	}

	/**
	 * LOIDからRealLOIDを取得します。
	 * 取得に失敗した場合はnullを返します。
	 */
	public String getRealLOID( String strLoID, DataAccess objDataAccess )
		throws SQLException
	{
		String strRealLOID = null;

		// SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT " );
		sbSQL.append( REAL_LOID );
		sbSQL.append( " FROM " );
		sbSQL.append( RELATION_TABLE_NAME );
		sbSQL.append( " WHERE " );
		sbSQL.append( LOID);
		sbSQL.append( " = '");
		sbSQL.append( StringEscapeUtils.escapeSql(strLoID) );
		sbSQL.append( "'" );

		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

		while(rs.next()) {
			strRealLOID = ChangeEncode.setChar( rs.getString( REAL_LOID ) );
		}

		return strRealLOID;
	}
}