상세 컨텐츠

본문 제목

안드로이드 개발 sqlite 파일 읽기 쓰기 connect 관련

스마트기기개발관련/안드로이드 개발

by AlrepondTech 2020. 9. 22. 03:27

본문

반응형

 

 

 

=======================

=======================

=======================

 

 

 

 

 

 

 

[안드로이드] 

sqlite 를 쓰려고 하는데 db파일은 어디다 놓아야 하나요? 

 

검색해 보니까 
/data/data/어쩌구/databases 폴더에 놓고 하라던데
아무리 찾아 봐도 그 폴더가 존재하지 않네요
자동으로 생기는 것인지 아니제 제가 직접 만들어 주어야 하는지요?

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

저는 별도의 db 가 있어서 그것을 쓰려고 하는데 어디다 놔야 할지 모르겠군요
/data/data/패키지명/databases 폴더가 없으면 제가 직접 만들고 거기에 db를 놓으면 될까요?

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

폴더는 만들지 않아도 되구여. 디비를 만들면 디폴트로 /data/data/패키지명/databases 밑에 디비가 위치하게 됩니다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

G.sqliteCon = this.openOrCreateDatabase("ddd",MODE_PRIVATE, null);
        G.sqliteCon.execSQL("create table if not exists test (title varchar(50))");
        G.sqliteCon.execSQL("insert into test(title) values ('as4556df')");
이렇게 하니까 정말 db기 있는 것처럼 저장도 되고 동작도 하고 조회도 됩니다.
그러데 제 이클립스화면에서 data/data폴더가 보이지 않습니다. 탐색기로 검색을 해도 안보이니
저의db를 어떻게 놓아야 할지모르겠어요 왜 저꺼에는 data/data 폴더가 없을까요?

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

이클립스 화면라란게 뭘말하는지 모르겠지만요.^^;
확인하시려면 adb shell로 들어가서 보세요.

> adb shell
# cd /data/data
# ls -l

여기까지 하면 다수의 패키지 폴더 들이 보일거구여. 거기서 안내님이 만든 패키지폴더로 들어가시면 databases라는 폴더가 있을겁니다. 그안에 디비파일이 있구요...

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

아참 저는 에뮬레이터로 하고 있는중입니다.>에뮬레이터도 마찬가지 입니다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

유레카!!
그러니까 ddms 로 하니까 다 있군요. 그걸 모르고 탐새끼로 찾느라고 ㅜㅜㅜ
어쩃든 감사합니다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

혹시 다른 프로젝트에서 만든 DB를 쓰신건가요?
어떻게 등록을 했는지 알수 있을까요?
저도 db를 하나 만들었는데 새로 만든 프로젝트에서 가져다 쓰려니 안되고 있습니다.
감사합니다.

>

ddms 에서 우측의화살표 버튼으로 파일을 추가 또는 제거할 수 있습니다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

=======================

=======================

=======================

 

 

 

출처: http://toris.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%97%90%EC%84%9C-SQLite%EC%82%AC%EC%9A%A9

 

안드로이드 앱을 개발하며 DB를 사용하게 되었는데 수많은 시행착오를 겪게 되었다, 
이글을 읽는 사람들은 적어도 나바다는 적은 고생을 하기를 바라며 ...

자. 그럼 안드로이드에서 SQLite를 사용하는 방법에대하여 알아보도록 하자.


DB생성예제

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class MainActivity extends SherlockActivity {
    private SQLiteDatabase db;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        //db생성 혹은 열기
        db = openOrCreateDatabase("plan",MODE_PRIVATE, null);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

여기서 주목할 것 은 openOrCreateDatabase("생성할 데이터베이스 이름","모드",null) 메서드이다.
영어를 그대로 해석해보면 "열기 혹은 생성" 인데 데이터베이스가 없을경우 생성, 있으면 여는 메서드다.
이 메서드의 인수는 3개로 첫번째인수는 생성하거나 열 데이터베이스의 이름을 뜻하고.

두번째 인수는 데이터베이스의 모드를 뜻하는데 
MODE_PRIVATE 는 해당어플리케이션만 사용 할 수 있다는 뜻이다.
즉 다른 어플리케이션에서도 이 데이터베이스에대한 접근을 허용하겠냐는 이야기다.

3번째 인수는 null로 해놓았는데 필자도 잘모른다. 다만 사용상의 문제는 없다.

 

테이블 생성 예제

//테이블 생성 혹은 열기
//db.execSQL("DROP TABLE plans");
String sql = "CREATE TABLE IF NOT EXISTS "+"plans"+" ("
        +"_id integer PRIMARY KEY autoincrement, "
        +"_date integer NOT NULL, "
        +"_list text NOT NULL, "
        +"_weather integer, "
        +"UNIQUE(_date));";
db.execSQL(sql);

여기서 볼 수 있듯이 "execSQL" 메소드를 이용하여 질의문을 실행 시킬 수 있습니다.
다만 
execSQL는 생성,삭제등 결과값이 필요 없는 경우에만 사용하며 특정 테이블을 조회한다 따위의 반환값이 필요한 작업의 경우
rawQuery 메소드를 이용해야한다.

위의 예제에서는 
execSQL() 메서드를 이용해 테이블을 생성하는 질의문을 써놓았다.
사용된 질의문을 분석해보면 이렇다. 

CREATE TABLE IF NOT EXISTS -> 테이블을 생성한다 만약 존재하지 않을 경우
해당하는 이름의 테이블이 존재하지 않는 경우에만 테이블을 생성한다는 구문이다.
plans ->생성할 테이블의 이름이다. 여기서는 plans 라고 되어있지만 원하는 이름으로 바꾸어 쓰면된다.

integer -> 정수값이라는 의미 Type text -> 문자열 값이라는 의미 Type PRIMARY ->유일키 라는 것(중복이 허용되지 않는 값) 테이블당 1개의 유일키를 가질 수 있다. UNIQUE() -> 중복이 허용되지 않게 한다는 것 에서 PRIMARY키와 비슷하지만 이것은 여러개의 필드를 지정 할 수있다. 아까 말했듯이. PRIMARY키는 하나의 필드만 지정할 수 있다.

rawQuery와 Cuser를 이용한 데이터베이스 조회예제

Cursor cursor = db.rawQuery("SELECT * FROM plans ORDER BY _date DESC LIMIT 0, 31", null);
    while(cursor.moveToNext()){
          String date = cursor.getString(1);
          String worklist = cursor.getString(2);
          Log.i("날짜 :",date);
    }
    cursor.close();

 

간단간단하게 예제 3개로 설명을 마친다.
기회가 있을 경우 조금더 이해가 쉽게 세부적으로 들어가보려한다만..

아마 귀찮아서 안할 것...

 

 

 

=======================

=======================

=======================

 

 

 

 

반응형

 

728x90

 

 

 

출처: http://crlog.com/49

안드로이드와 SQLite 관련해서 데이터베이스를 만들고 연결하는 팁들은 검색을 해 보면 금방 찾을 수 있었습니다. 제가 생각한 것은 미리 배포버전 자체내 데이터베이스에 데이터를 만들어 놓고  어플만 다운 받으면 데이터를 가져오는 연결을 하지 않아도 데이터를 이용하고 싶은 생각이 들었습니다.

자료를 찾다보니 안드로이드 개발 프로젝트 폴더 중에 assets가 있는데요. 여기에 SQLite 데이터베이스 파일을 저장해두고 이를 어플이 처음 실행 할 때 스마트폰 기기로 저장을 하는 방법을 사용하더군요. 바로 이거다 했지요!.

개발에 필요한 핵심 요소들을 이렇게 정했습니다.
1. assets 폴더에 sqlite 데이터베이스를 만들어 놓자.
2. 스마트폰의 지정한 위치에 데이터베이스가 없으면 복사를 하자.
3. 파일이 있으면 이를 데이터베이스로 연결하여 사용하자. 끝. ^^

가장 먼저 구한 방법이 데이터베이스를 복사하는 소스였습니다.

	private void copyDatabase() throws IOException {
		InputStream myInput = crContext.getAssets().open(DB_NAME);
		 
		String outFileName = DB_PATH + DB_NAME;
		OutputStream myOutput = new FileOutputStream(outFileName);
		 
		byte[] buffer = new byte[1024];
		int length;
		while ((length = myInput.read(buffer))>0){
			myOutput.write(buffer, 0, length);
		}
		myOutput.flush();
		myOutput.close();
		myInput.close();
	}

복사하는 메소드는 딱 봐도 군더더기 없이 깔끔해 보입니다. ^^

다음은 assets 폴더에 데이터베이스를 만드는 일 입니다. 처음 생각에는 가장 쉬울 줄 알았는데,  막상 하려고 해보니 몇 가지 문제점이 있었습니다. 그 하나는 sqlite 데이터베이스를 어떻게 만드는가 하는 거죠. 원본 데이터는 데이터베이스 서버에 저장이 되어 있는 상태이고 이를 간단하게 Export 해서 SQLite에 Import를 하려고 한 것 인데요. 그 데이터들이 SQLite에 잘 저장되지 않습니다. 

문제는 한글 입니다. !!!

CSV로 저장하는 과정에서 UTF-8으로 저장을 해야하는데, 계속해서 한글이 깨진 상태로 저장이 됩니다. 별별 방법을 동원해 가면서 하루를 스트레스로 보내야만 했습니다.  ^^

 


결국 SQLite Databse Browser 로는 할 수가 없다는 결론을 내렸습니다. 한글에 대한 방법이 없을 뿐아니라, 자주 멈추거나 슬그머니 종료가 되기까지 합니다. 그러다가 SQLite Manager 라는 툴을 발견했습니다. 부분 무료 이기 때문에 결제를 하라는 메시지가 빈번하게 나타나긴 하지만, 중요한 것은 한글을 처리 할 수 있다는 것 이지요. ^^

 


아무튼 겨우 MySQL에서 뽑아온 CSV 파일을 SQLite Manager 로 Import 했습니다.  

데이터베이스를 만들고 스마트폰에 복사를 하는 모듈을 먼저 만들었습니다. 위에 소스 copyDatabase() 하나면 충분합니다.
이제 파일을 연결해서 이를 데이터베이스로 사용하는 일만 남았습니다. 여기에서의 가장 문제점은 데이터베이스 연결이 안된다는 겁니다. !!

다시 원점으로 돌아가서 무엇이 잘못된 것인가를 찾아내는데 다시 하루를 보냈습니다.
문제는 또 한글이었습니다.!!  

 public void openDataBase() throws SQLException{
		 String myPath = DB_PATH + DB_NAME;
		 sqlite = SQLiteDatabase.openDatabase(myPath, null,  SQLiteDatabase.NO_LOCALIZED_COLLATORS);
         }


SQLite에서 다국어 처리를 하려면 SQLiteDatabase.NO_LOCALIZED_COLLATORS를 사용해야 된다고 하네요. ^^

public class DBAdapter {
	
	private final Context context;
	private DatabaseHelper DBHelper;
	private SQLiteDatabase db;
	
	public DBAdapter(Context ctx)
	{
		this.context = ctx;
		DBHelper = new DatabaseHelper(this.context);
		
		try {
			DBHelper.createDatabase();
			DBHelper.openDataBase();
		} catch (IOException e) {
			Log.d("DBAdapter", e.toString());
		} catch (SQLException e) {
			Log.d("DBAdapter", e.toString());
		}
	}
	
	private static class DatabaseHelper extends SQLiteOpenHelper
	{
		private SQLiteDatabase	sqlite;
		private final Context crContext;
		
		DatabaseHelper(Context context)
		{
			super(context, DB_NAME, null, 3);
	        	this.crContext = context;
		}
		
		public void createDatabase() throws IOException {
			if (!checkDatabase()){
				this.getReadableDatabase();
				try {
					copyDatabase();
				} catch (IOException e) {
					throw new Error("Error copying database");
				}
			}
		}
		
		public boolean checkDatabase() {
			SQLiteDatabase checkDB = null;
			try{
	    		String myPath = DB_PATH + DB_NAME;
	    		checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
	    		
	    	} catch (SQLiteException e) {
	    		Log.d("checkDatabase", e.toString());
	    	}
	 
	    	if(checkDB != null){
	    		checkDB.close();
	    	}
	    	return checkDB != null ? true : false;
		}
		
		private void copyDatabase() throws IOException {
	    	InputStream myInput = crContext.getAssets().open(DB_NAME);
	 
	    	String outFileName = DB_PATH + DB_NAME;
	    	OutputStream myOutput = new FileOutputStream(outFileName);
	 
	    	byte[] buffer = new byte[1024];
	    	int length;
	    	while ((length = myInput.read(buffer))>0){
	    		myOutput.write(buffer, 0, length);
	    	}
	    	myOutput.flush();
	    	myOutput.close();
	    	myInput.close();
	    }
	 		
		 public void openDataBase() throws SQLException{
			 String myPath = DB_PATH + DB_NAME;
			 sqlite = SQLiteDatabase.openDatabase(myPath, null,  SQLiteDatabase.NO_LOCALIZED_COLLATORS);
		 }
		 @Override
		 public synchronized void close() {
	    	    if(sqlite != null)
	    	    	sqlite.close();
	    	    super.close();
		 }
		 
		 @Override
		 public void onCreate(SQLiteDatabase db) {
		 }
		 
		 @Override
		 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		 }		 
	}
	
	public DBAdapter open() throws SQLException
	{
		db = DBHelper.getWritableDatabase();
		return this;
	}
	
	public void close()
	{
		DBHelper.close();
	}
}

 

 

=======================

=======================

=======================

 

 

 

 

반응형


관련글 더보기

댓글 영역