안녕하세요..대단한 팁이 아닐수도 있고..
이미 아시는 내용일 수도 있겠습니다만..
제가 검색을 했을때 원하는 답을 찾질 못해서..
그래서 제가 발견한 방법을 공유해보고자 글을 남깁니다..


흔히 AdapterView 계열 위젯(ex: ListView, Spinner 등)들을 사용하실때 CursorAdapter를 사용하시는 경우는..

표현하고자 하는 데이터를 DB에서 쿼리해오는 경우입니다..

제가 웹프로그래머다보니..웹에서 콤보박스 형태로 표현이 되는 안드로이드의 Spinner에서..
사용자가 어떤 항목을 선택했을때 선택된 항목의 DB 테이블 키값을 어떻게 가져오는지..그 부분을 찾고 있었습니다..


예를 들어 회사이름들을 Spinner로 보여줘야 하는데..
회사를 DB 테이블로 관리한다면 이런식으로 할 수 있을겁니다..


company_id                           company_name
        1                                               회사1
        2                                               회사2
        3                                               회사3


요렇게하면 회사와 관련된 데이터를 저장할때 company_id 컬럼 값을 저장한뒤 join하면 회사명을 같이 보여줄수 있으니까요..
그래서 위젯에서 어떤 회사를 선택했을때 그 선택된 회사의 company_id 컬럼 값을 가져올수 있는 부분을 찾고 있었는데..


근데 그런 내용이 검색이 안되더군요..ㅠㅠ..
제가 못찾았일수도 있지만..


그래서 안드로이드 소스를 보면서 조금 파봤는데요..
AdapterView 클래스의 함수중에 다음과 같은 이름의 함수가 있습니다..


getItemIdAtPosition(position);


이름에서 보시다시피 클릭된 위치(position)값을 받아서 해당하는 아이템의 ID값을 주는 함수에요..
근데..이 ID를 DB 쿼리에서 조회할때 가져오는 key값으로 셋팅하게 하는 부분이 없었습니다..
그래서 관련 소스를 봤습니다..


public long getItemIdAtPosition(int position) {
        T adapter = getAdapter();
        return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position);
}


소스를 보시면 adapter를 받아서 adapter가 null이 아니고 position이 0 이상이면 getItemId(position)을 호출하고 있습니다
adapter는 CursorAdapter를 사용하고 있으니..CursorAdapter의 getItemId(position)을 보시면..


public long getItemId(int position) {
      if (mDataValid && mCursor != null) {
            if (mCursor.moveToPosition(position)) {
                   return mCursor.getLong(mRowIDColumn);
            } else {
                   return 0;
            }
      } else {
                  return 0;
      }
}


CursorAdapter에서 입력받은 DB 커서에서 CursorAdapter의 멤버변수인 mRowIDColumn값을 컬럼 인덱스로 하여
Long 타입으로 키값을 돌려주도록 되어 있습니다.
즉 mRowIDColumn을 우리가 지정할수 있으면 DB에서 조회된 Key 값을 사용할수 있지요..
근데 mRowIDColumn 값을 프로그래머가 인위적으로 셋팅하는부분을 소스에서는 발견하진 못했습니다..
그래서 mRowIDColumn 값을 어느 시점에서 셋팅하는지 찾아봤는데요..
CursorAdapter의 init 함수에 다음과 같은 내용이 있었습니다..


protected void init(Context context, Cursor c, boolean autoRequery) {
          boolean cursorPresent = c != null;
          mAutoRequery = autoRequery;
          mCursor = c;
          mDataValid = cursorPresent;
          mContext = context;
          mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
          mChangeObserver = new ChangeObserver();
          if (cursorPresent) {
                c.registerContentObserver(mChangeObserver);
                c.registerDataSetObserver(mDataSetObserver);
          }
}


mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
이 부분을 보시면 CursorAdapter에 셋팅된 커서가 null인지의 여부를 판단하는 변수인 cursorPresent 변수가 true이면
c.getColumnIndexOrThrow("_id")를 통해 커서에서 _id란 컬럼명의 컬럼 인덱스를 mRowIDColumn에 셋팅하고
그렇지 않으면 -1을 셋팅하는 거였습니다.
즉 우리가 쿼리를 만들때 key값 역할을 하는 컬럼의 컬럼명이 _id라면
그 key값을 가져올수 있는 거였습니다..


하지만 company_id가 아닌 단순히 _id라고 컬럼명을 지으면..
의미가 불분명해서 company_id 이렇게 짓는 편인데..
이 부분을 다음과 같이 하면 가능합니다..
쿼리를 작성하실때 의사 컬럼을 쓰시면 됩니다..이렇게요


select company_id as _id, company_name from company


요렇게 물리적으로는 이미 company_id란 명칭이지만 쿼리에서만 _id란 명칭으로 바꿔서 사용하시면..
company_id 컬럼값을 가져올수 있게 됩니다..
이렇게 key값을 가져오게 되면 테이블의 다른 값들과 조인해서 가져올수 있기땜에 작업이 한결 편해집니다..


이미 아시는 내용을 쓴거라면 죄송하구요..ㅠㅠ..


그럼 오늘도 좋은하루들 되세요..