왜 이런 해괴한 방법을 썼냐면..
전공 팀플로 "MySQL과 프론트를 어떻게든 연결해서 인스타 or 트위터를 만들어라!"라는 주제가 떨어졌기 때문이다.
팀원 중에서 서버 배포를 해본 사람은 아무도 없었다. 수업 시간에 IntelliJ에서 JDBC 드라이버를 이용해 MySQL 데이터를 불러오는 방법을 배웠어서, 나는 이런 생각에 도출하게 되었다.
'IntelliJ에서도 되는데, 그럼 Android Studio에서도 할 수 있는 방법이 있지 않을까?'
어쨌든 둘 다 JetBrains에 속하기 때문에 방법이 있을 거라고 생각했다.
물론, 실제 프로젝트라면 당연히 권장되지 않는 방법이다. 내가 동아리 선배들한테도 여쭤봤을 때 "대체 왜 그런 방법을 쓰는거지?"하면서 나를 바라봐서, 설명하는 데도 한참이었다.
내가 해당 방법을 찾은 이유를 정리하자면 다음과 같다.
- 실제 배포할 프로젝트가 아닌, 그냥 어떻게든 하기만 하면 되는 전공 팀플이어서
- 서버를 배포를 해 본 사람이 아무도 없어서
또 누군가는 RoomDB가 있는데 굳이 이런 방법을 써야하냐고 물어볼 수 있을 것이다. (나도 할 수만 있다면 룸디비를 매우매우매우 쓰고 싶었다.) 내가 룸디비를 사용할 수 없었던 이유는 다음과 같다.
- MySQL을 사용했어야 함. 쿼리문 작성이 조건이었음.
- 팔로잉, 팔로우 기능을 구현했어야 했음. 따라서 기기 하나에서만 유효한 RoomDB는 적합하지 않음
어쨌든 간에 JDBC driver를 사용하는 방식은 프론트가 개고생하는 방법이라고 생각하면 된다.
이건 할 말이 많아서.. 뒤에서 더 다뤄보도록 하겠다.
아무튼 직접 해보니 권장되지 않는 방법이라는 건 정말 잘 느꼈다.
우선, 안드로이드 스튜디오에서 JDBC driver를 이용해서 MySQL 연결하려면 먼저 해줘야하는 작업이 많다.
최신 버전은 Android Studio에서 사용할 수 없어서 낮은 버전을 사용해야 한다.
내가 설치한 버전은 5.7.44
이다.
나는 이 과정이 가장 힘들었다. 계속 Android Studio에서 MySQL 데이터베이스 연결에 실패했다고 해서, 뭐가 문제인가 했더니 MySQL 버전 문제였기 때문이다. 하지만 기존에 이미 8.1.0
버전이 설치되어 있었기 때문에 그게 꼬여서인지 계속 실행이 제대로 되지 않았고, 결국 8.1.0
버전은 지운 채로 5.7.44
버전을 새로 설치했다. MySQL 설치는 5.x
버전까지면 괜찮은 듯하다. 5.1.49
를 사용한 블로그도 몇 개 보았다.
들어보니 MySQL의 5.x와 8.x 버전이 사용하는 드라이버가 달라서 그런 것 같다.
build.gradle(:app)에 다음 의존성을 추가해준다.
// MySQL 의존성 추가
implementation 'mysql:mysql-connector-java:5.1.49'
// coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
안드로이드 스튜디오에서 JDBC driver를 사용하려면 mysql connector는 필수로 필요하고, ❗️DB에 접근하는 작업은 모두 스레드에서 진행해주어야 하기 때문에❗️ 코루틴 의존성도 추가해준다.
DB 커넥션, 조회 같은 작업들은 ❗️반드시❗️ 스레드를 만들어서 진행해야 한다.
메인 스레드는 안된다! 혹시라도 나처럼 코드를 제대로 쓴 거 같은데 스레드 이슈로 삽질하는 사람이 없길 바라며 한번 더 강조해 본다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// DB 데이터 조회 테스트
dbTest()
}
private fun dbTest() {
val thread = Thread{
var con: Connection? = null
try {
Class.forName("com.mysql.jdbc.Driver")
val url = "jdbc:mysql://(DB_hostname):(DB_port)/(DB_name)"
val user = "(DB_username)"
val passwd = "(DB_password)"
con = DriverManager.getConnection(url, user, passwd)
Log.d("Database", con.toString())
} catch (e: ClassNotFoundException) {
e.printStackTrace()
} catch (e: SQLException) {
e.printStackTrace()
}
// database operation
var stmt: Statement? = null
var rs: ResultSet? = null
try {
if (con != null) {
stmt = con.createStatement()
// 실행할 쿼리 작성
val sql = "select * from user"
rs = stmt.executeQuery(sql)
while (rs.next()) {
var name = rs.getString(1)
if (rs.wasNull()) name = "null"
var course_id = rs.getString(2)
if (rs.wasNull()) course_id = "null"
println(name + "\t" + course_id)
}
}
} catch (e1: SQLException) {
e1.printStackTrace()
}
try {
if (stmt != null && !stmt.isClosed()) stmt.close()
} catch (e1: SQLException) {
e1.printStackTrace()
}
}
thread.start()
try {
thread.join()
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
이런 식으로 하면 DB의 정보를 잘 불러올 수 있다!
다음 편에서는 폴더 구조화
에 대해 적도록 하겠다. 내가 안드로이드 스튜디오에서 JDBC를 사용하기 위해서 파일과 코드를 어떻게 작성했나, 를 다루는 시간이 되겠다.
[JDBC를 이용해 Android와 MySQL를 연동한 인스타 클론코딩 Github]
🔗 https://github.com/nahy-512/Database_TeamD