본문 바로가기
Android

[Android] MsSQL Server 연동하기

by bryan.oh 2019. 5. 9.
반응형

Microsoft SQL Server 와 Android 연동

jtds

 

일단 jtds 라이브러리를 다운받아야 합니다.

1.2.7 버전이 잘 됩니다. (1.3.x 이후는 뭔가 안된다는걸 봐서..)

jtds-1.2.7.jar
0.29MB

 

Android Studio 의 좌측상단을 Project 로 바꾼 후 libs 폴더에 위의 jtds-1.2.7.jar 를 복사합니다.

 

 

# build.gradle 의 dependencies

dependencies
{
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:23.1.1'
implementation project(':jtds-1.2.7') // Add this line to your dependencies
}

을 추가합니다.

 

# AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

추가.

 

테스트 엑티비티 (복붙한다고 바로 되지 않습니다. SQL에 필요한것만 import 해놨습니다.)

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DbTestActivity extends AppCompatActivity {
    private Connection conn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_db_test);
		if( tryConnect(true) ){
			insertTest();
		}
	}
	private boolean tryConnect(boolean showMessage) {
        try {
            if (conn != null && !conn.isClosed())
                return true;
			// TODO 어디선가 정보를 입력받아옴.
   			String dbIp = "192...";	// 뒤에 :1443 은 입력하지 않는다.
		    String dbName = "master";
   			String dbUser = "user1";
   			String dbUserPass = "pwd12341234";
            ConnectionClass connClass = new ConnectionClass();
            conn = connClass.getConnection(dbUser, dbUserPass, dbName, dbIp);
            if (conn == null) {
                if (showMessage)
					showToast(connClass.getLastErrMsg());
                return false;
            } else {
                if (conn.isClosed()) {
                    if (showMessage)
                        showToast(this, "DataBase 연결 실패.");
                    return false;
                } else {
                    if (showMessage)
                        showToast(this, "DataBase 연결에 성공했습니다.");
                    return true;
                }
            }
        } catch (SQLException e) {
            if (showMessage)
                showToast(this, e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
	private void insertTest(){
		String regDate = android.text.format.DateFormat.format("yyyy-MM-dd HH:mm:ss", new java.util.Date()).toString();
        String query = String.format("INSERT INTO tb_test (user_name, user_age, user_gender, reg_date) VALUES ('%s','%s','%s','%s')"
                      , "홍길동", "85", "M", regDate);
        Pair<String, Integer> result = executeQuery(query);
	}
    private Pair<String, Integer> executeQuery(String query){
        try {
            if( tryConnect(true) ){
                // delete test
                PreparedStatement preStmt = conn.prepareStatement(query);
                int delCnt = preStmt.executeUpdate();
                return Pair.create("", delCnt);
            }else
                return Pair.create("DB에 연결할 수 없습니다.", 0);
        } catch (SQLException e) {
            e.printStackTrace();
            return Pair.create("실패 : " + e.getMessage(), 0);
        }
    }
	private void showToast(String text){
		Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
	}

 

# ConnectionClass.java (복붙해서 그대로 사용)

import android.annotation.SuppressLint;
import android.os.StrictMode;
import android.util.Log;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionClass {
    private Connection connection = null;
    private String ConnectionURL = null;
    private String errMsg = "";

    @SuppressLint("NewApi")
    public Connection getConnection(String user, String password, String database, String server)
    {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        try
        {
            DriverManager.registerDriver((Driver)Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance());
            ConnectionURL = "jdbc:jtds:sqlserver://" + server + "/" + database + ";user=" + user+ ";password=" + password + ";";
            connection = DriverManager.getConnection(ConnectionURL);
            Log.d("#DB", "after connection");
        }
        catch (SQLException se)
        {
            Log.e("error here 1 : ", se.getMessage());
            errMsg = se.getMessage();
        }
        catch (ClassNotFoundException e)
        {
            Log.e("error here 2 : ", e.getMessage());
            errMsg = e.getMessage();
        }
        catch (Exception e)
        {
            Log.e("error here 3 : ", e.getMessage());
            errMsg = e.getMessage();
        }
        return connection;
    }

    public String getLastErrMsg(){
        return errMsg;
    }
}

 

 

# proguard 설정

-dontwarn net.sourceforge.jtds.**

 

 

 

Ms SQL Server 가 있다면 테이블을 생성하여 아래와 같이 테스트 해봤습니다.

 

MsSQL 결과.

 

 

 

# BUT

이렇게 Android 에서 직접 MSSQL 에 direct 로 붙는 방법은 추천하지 않는다고 합니다. 

왜?

보안상, 안드로이드 소스에 DB connection 정보가 있어서 그렇다는데,

방법은

1. connection 정보를 native 에 숨기고

2. SQL 계정을 딱 필요한 권한만 부여해서 주면

괜찮지 않을까 합니다.

 

그리고 또, 핸드폰의 커넥션이 불안정해서 끊어질 수 있다고도 하는데,

1. 쿼리 날릴때 마다 connection 을 체크하고 끊어졌으면 다시 connect 하도록 하면되고 (겁나빠름)

2. transaction 이용해서 commit 과 rollback 을 쓰고 (auto commit no no~), 중간에 끊어지는것에 대한 처리를 할 수 있을것 같은데요. 

 

암튼, 상황에 따라 보안상 문제를 잘 해결해서 쓰면 되겠죠~

 

 

728x90
반응형

댓글