기타치는 개발자

[Android]ORMLite 적용하기 본문

안드로이드

[Android]ORMLite 적용하기

던킨팬더 2016. 5. 27. 13:20

안드로이드는 기본적으로 SQLite를 지원하며 SQLiteOpenHelper 를 상속받아 구현하게됩니다. 

  

아래와같이 onCreate에서 SQLITEDatabase객체에 create table 쿼리를 작성하여 테이블을 생성하게됩니다. 이때 오타의 위험성도 있으며 각각의 필드를 직접 적어야된다는 불편함이 있습니다. 

또한 CRUD작업들을 할경우에도 커서에서 하나하나 컬럼명에 따라서 가져오는 부분을 구현해야 합니다 

1
2
3
cursor.getInt(mCursor.getColumnIndex("_id")),
 
cursor.getString(mCursor.getColumnIndex("name"))
cs

실제로 앱에서는 서버와는 다르게 정교한 데이터베이스 작업들이 많지가 않습니다. 간단한 정보를 저장 후 검색 및 CRUD작업이 필요합니다. 


그래서 ORMLite라는 라이브러리를 사용하여 간단한 DB작성하는 방법을 작성해보려합니다. 

실제로 ORMLite는 서버개발에 사용되는 Jackson라이브러리와 비슷합니다.  오히려 개인적으로는 더 유연하지 않나 싶습니다. 

두 라이브러리의 차이점이 궁금하신분은 아래 링크를 참조 하시면될것 같습니다.

http://www.baeldung.com/jackson-vs-gson


라이브러리 추가 

app.gradle 파일에 dependencies compile 'com.j256.ormlite:ormlite-android:4.48'

Table객체 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@DatabaseTable(tableName = "carinfo")
public class CarInfo {
    
    @DatabaseField(generatedId = true, allowGeneratedIdInsert = true)
    private int _id;
 
    @DatabaseField
    private String name;
 
    @DatabaseField
    private String publishDt;
 
    @DatabaseField
    private int price;
 
}
cs

 - @DatabaseTable 는 객체가 테이블임을 선언해준다  tableName 은 필수값은 아니다

- @DatabaseField 는 디비 컬럼 임을 선언해주고 defaultValue, generatedId,Id 등 기본적인 컬럼 설정은 정의되어있다

Helper작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class DataBaseHelper extends OrmLiteSqliteOpenHelper {
 
    private static final String DATABASE_NAME = "car.db";
    private static final int DATABASE_VERSION = 1;
 
    private Dao<CarInfo,Integer> mCarInfo;
 
    public DataBaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
 
    }
 
 
    @Override
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
 
        try {
            TableUtils.createTable(connectionSource, CarInfo.class);  //Table 생성
        } catch (SQLException e) {
            Log.e(OrmliteHelper.class.getName(), "Unable to create datbases", e);
        }
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        try {
            TableUtils.dropTable(connectionSource, CarInfo.classtrue);    //업데이트시 테이블 삭제
            onCreate(database, connectionSource);
        } catch (SQLException e) {
            Log.e(OrmliteHelper.class.getName(),
                    "Unable to upgrade database from version " + oldVersion + " to new " + newVersion, e);
        }
    }
 
   
    public Dao<CarInfo, Integer> getStandardInfosDao() throws SQLException {
        if (mCarInfo == null) {
            mCarInfo = getDao(CarInfo.class);
        }
        return mCarInfo;
    }
}
cs

기본 구조는 SQLiteOpenHelper와 동일하며 특이점은Dao라는게 보인다. 

일반 Curser 정도라고 생각하고 하면될 것 같다 실제 사용하는것은 아래에서 설명하겟습니다.



Select,Insert,Delete

1
2
3
4
5
6
7
8
9
10
11
12
//Select 
try {   
 
 Dao<CarInfo,Integer> carInfoIntegerDao=new DataBaseHelper(this).getStandardInfosDao();  
 
 QueryBuilder<CarInfo,Integer> qb=carInfoIntegerDao.queryBuilder();
 
 ArrayList<CarInfo> carInfos = (ArrayList<CarInfo>) carInfoIntegerDao.query(qb.prepare());
 
catch (SQLException e) {
    e.printStackTrace();
}
cs

ORMLite 장점은 컬럼별로 값을 직접 처리할 필요가없다 해당 객체로 생서되어 나오게됩니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
//insert
try {
    Dao<CarInfo,Integer> carInfoIntegerDao=new DataBaseHelper(this).getStandardInfosDao();
 
    CarInfo insertData=new CarInfo();
    insertData.setName("포르쉐");
    insertData.setPrice(120000000);
    insertData.setPublishDt(20160527);
    
    carInfoIntegerDao.create(insertData);
catch (SQLException e) {
    e.printStackTrace();
}
cs
객체를 다른 처리없이 create를 하게되면 Insert 작업이 되며 createOrUpdate를 호출하였을때는 기본키를 검색하여 생성 및 업데이트를 처리하게됩니다. 


1
2
3
4
5
6
7
8
9
10
//delete
try {
    Dao<CarInfo,Integer> carInfoIntegerDao=new DataBaseHelper(this).getStandardInfosDao();
    DeleteBuilder<CarInfo,Integer> deleteBuilder=carInfoIntegerDao.deleteBuilder();
    deleteBuilder.where().eq("name","포르쉐");
    deleteBuilder.delete();
 
catch (SQLException e) {
    e.printStackTrace();
}        
cs

1
2
3
4
5
6
7
8
9
10
11
//update
try {
    Dao<CarInfo,Integer> carInfoIntegerDao=new DataBaseHelper(this).getStandardInfosDao();
    UpdateBuilder<CarInfo,Integer> updateBuilder=carInfoIntegerDao.updateBuilder();
    updateBuilder.updateColumnValue("name","포르쉐짱짱맨");
    updateBuilder.where().eq("name","포르쉐");
    updateBuilder.update();
    
catch (SQLException e) {
    e.printStackTrace();
}
cs


각 작업에 대한 Where이 가능하며 다중 조건도 가능합니다. 아래와같은 조건이 있을경우

출시일이 20160527 이고(and) 이름이 포르쉐 인것과( or) 출시일이 20160525 이고(and) 이름이 쌍용 인것을 가져오고싶을때는 아래와같이한다.

1
2
3
4
5
Where where = builder.where();// 각각의 빌더 
 
where.or(where.eq("publishDt"20160527).and().eq("name","포르쉐"),
 
where.eq("publishDt"20160525).and().eq("name","쌍용"));
cs

이렇게  where.or() 안에 , 로 구분하여 조건절을 추가할수도 있다 .