Bài 14-Cách kết nối và truy suất dữ liệu MongoDB trong Android Kotlin

bài 13 các bạn đã biết cách tham chiếu thư viện cho MongoDB trong Android rồi, Bài này Tui sẽ hướng dẫn các bạn cách thức kết nối từ Android Kotlin tới MongoDB cũng như cách truy suất dữ liệu một cách trực tiếp như thế nào! Đặc biệt Tui sẽ dùng Android Studio mới nhất, SDK mới nhất, Kotlin mới nhất, MongoDB mới nhất tính tới thời điểm 12/06/2018

Kết thúc bài này bạn phải làm được giao diện như kết quả dưới đây:

Màn hình chính các các nút: Xem Product, Thêm Product, sửa Product, Xóa Product và Thoát phần mềm. Trong bài này Ta chỉ viết một chức năng đó là Xem Product. Khi bấm vào nút Xem Product thì hiển thị màn hình bên phải là Danh Sách Product được truy suất từ MongoDB. Chú ý Project đã được tạo Ở bài 13 nên các bạn mở lại nó nha

Bây giờ ta tiến hành làm chi tiết từng chức năng, thứ nhất là thiết kết màn hình chính gồm 5 Button như trên (Là màn hình MainActivity), ta mở XML layout lên để thiết kết, xem coding XML của MainActivity:

[code language=”XML”]

[/code]

Ta có thể kéo thả trực tiếp vào mục Component Tree trong phần Design:

Chú ý đặt tên Control(View) như Tui đã làm ở trên.

Tiếp tục, để tạo màn hình Xem danh Sách Product truy suất từ MongoDB ta làm như sau (Bấm chuột phải vào package/ chọn New/ chọn Activity/ Chọn Empty Activity như hình dưới):

Lúc này Nó xuất hiện một cửa sổ Configure Acitvity:

Ta đổi  Activity name thành XemProductActivity:

Cấu hình mọi thứ như trên rồi bấm Finish để tạo Activity Xem danh sách Sản phẩm, quan sát sẽ thấy XemProductActivity như trong hình:

Vì màn hình này chỉ dùng để hiện thị danh sách Sản phẩm nên ta chỉ cần đưa 1 ListView hoặc View gì cũng được miễn là nó hiển thị được danh sách (như RecyclerView chẳng hạn)..

XML của màn hình XemProduct:

[code language=”xml”]

[/code]

Xem phần Design:

Ta sẽ viết thêm 1 lớp model Product để mô hình hóa dữ liệu từ MongoDB về Kotlin class (tương tự như C# mà ta đã được học)

Ta bấm chuột phải vào java package / Chọn New / Chọn Package như hình dưới:

Lúc này màn hình tạo Package hiển thị ra:

Ta đặt: com.communityuni.model (dĩ nhiên tên gì kệ xác bạn, thường để trong model để nó đồng cấp với các package khác). Đây là cách mà bạn bố trí cho nó phù hợp. Lúc tạo Project chỗ company domain thế nào thì ở đây nhất quán như vậy

OK, nhấn OK nha you, kết quả:

Vậy  rõ ràng bạn thấy model nó đồng cấp với bên trên rồi, nó phân loại các lớp như vậy để ta dễ xử lý thôi, bây giờ tạo 1 lớp tên là Product ở trong model như sau: Bấm chuột phải vào model/ chọn new / chọn Kotlin File/class:

Lúc này màn hình yêu cầu tạo model class được xuất hiện:

Name: Đặt tên là Product

Kind: chọn Class

Bấm OK để tạo

Sau đó bổ sung coding cho Product như sau:

[code language=”java”]
package com.communityuni.model

class Product {
lateinit var _id:Any
lateinit var Ma:String
lateinit var Ten:String
var DonGia:Double=0.0
constructor(ma:String,ten:String,donGia:Double)
{
Ma=ma
Ten=ten
DonGia=donGia
}
override fun toString(): String {
return Ma+”\n”+Ten+”\n”+DonGia+”VNĐ”
}
}
[/code]

Lưu ý, chi tiết cách lập trình hướng đối tượng trong Kotlin có thể xem ở đây (xem bài 22, 23, 24, 25, 26, 27, 28) hoặc các bạn có thể đăng ký học Kotlin qua Video tại đây.

OK, bây giờ ta quay lại lớp: MainActivity.kt để lập trình, coding:

[code language=”java”]
package com.communityuni.androidkotlintomongodb

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun xemProduct(view: View)
{
var intent= Intent(this,XemProductActivity::class.java)
startActivity(intent)
}
}
[/code]

Coding ở trên dùng để mở màn hình XemProductActivity. Đây là cách xử lý sự kiện loại onclick XML, các bạn có thể xem lại 6 loại xử lý sự kiện trong Android ở đây và tự chuyển qua kotlin một cách dễ dàng.

Bây giờ ta mở coding của lớp XemProductActivity.kt:

Trong màn hình này có 2 tác vụ chính: Thứ nhất là làm thế nào để kết nối từ Android lên MongoDB, Thứ 2 là làm thể nào để truy suất dữ liệu trong bảng Product để hiển thị lên giao diện ListView.

Để Kết nối tới Server (Cluster) MongoDB ta làm như sau:

[code language=”java”]
var connectionString = MongoClientURI(“mongodb://172.16.96.173:27017”)
var mongoClient = MongoClient(connectionString)
[/code]

Các bạn lưu ý ở trên phải dùng địa chỉ IP nha, không có dùng localhost được vì từ Mobile nó sẽ tìm ra Server nào có IP tương ứng (nếu để localhost nó tưởng là kết nối với chính Mobile,  vì Mobile cũng là 1 hệ điều hành nó có localhost, có nghĩa là nếu để localhost là bị hiểu nhầm). Và có 1 lưu ý quan trọng là địa chỉ IP này phải được khai báo và start service trong file mongod.cfg. Bạn tự kiểm tra lúc đó máy tính (laptop) hay server nào đó của bạn đang dùng IP là gì thì phải Start Service lại (bắt buộc nếu không kể cả MongoDB compass với Android mobile cũng không thể nào kết nối được với MongoDB server). Ở bài 2 Tui đã trình bày rất kỹ cách thức cấu hình để start service. Các bạn xem lại bài này để bổ sung(hay thay đổi IP cho nó phù hợp để Start service, nếu IP cung cấp sai hay tự nhiên bị đổi thì cũng không thể nào chạy được). Cơ sở dữ liệu dùng cho bài này cũng được nói ở bài 3.

Giả sử như bạn đã làm rất tốt bài 2 rồi, tuy nhiên lỡ Laptop của mình bị đổi IP hay Server bị đổi (laptop thì thường xuyên rồi, thì lúc này không cỡ nào mà chạy được Service MongoDB), do đó bạn chỉ kiểm tra lại IP máy mình có bị đổi không rồi bổ sung vào mongod.cfg:

đấy, hình ở trên Tui chụp lại nội dung file cấu hình mongod.cfg và nó cũng được cung cấp trong bài 2 . Mục bindIP được cápa thì tất cả IP trong đó bắt buộc phải tồn tại và kết nối được, nếu IP nào tự nhiên mất thì cũng phải xóa nó đi để thay thế IP mới (Ví dụ hôm nay bạn học ở nhà IP là X chạy OK, hôm sau ra quán Cafe bị đổi thành IP khác thì cũng phải mở file này lên sửa lại IP được cấp trong quán Cà phê).

Nếu thực sự bạn bị đổi IP và phải sửa lại thì bắt buộc phải chạy lại 2 lệnh: stop và start dịch vụ của MongoDB server như hình dưới đây:

Như vậy là ngon lành cành đào nha, tình huống nào ta cũng biết cách xử lý (nếu không biết là ăn hành ngay, không hiểu vì sao ở nhà đang chạy ngon lành, qua nhà bồ nhí làm lại không chạy, bể hụi liền).

OK, như vậy ở trên ta đã biết coding kết nối tới Cluster/Server. Sau đó ta lấy nó để kết nối tới tên Cơ sở dữ liệu như mong muốn:

[code language=”java”]
var database = mongoClient.getDatabase(“QuanLySanPham”)
[/code]

Để đọc dữ liệu trong bảng nào đó ta làm như sau (giả sử bảng Product):

[code language=”java”]
val collection = database.getCollection(“Product”)
[/code]

Sau đó để đọc dữ liệu trong bảng Product ta coding như sau:

[code language=”java”]
var cursor = collection.find().iterator()
var dsProduct = ArrayList()
try {
while (cursor.hasNext()) {
val data = cursor.next().toJson()
val jsonObject = JSONObject(data)
val ma = jsonObject.getString(“Ma”)
val ten = jsonObject.getString(“Ten”)
val gia = jsonObject.getDouble(“DonGia”)
var product=Product(ma,ten,gia)
dsProduct.add(product)
}
} finally {
cursor.close()
}
[/code]

Ta lưu ý, với Android cho dù là Java hay Kotlin thì cũng phải viết đa tiến trình khi có kết nối Internet và phải cấp quyền trong AndroidManifest:

[code language=”xml”]

[/code]

Và đây là coding chi tiết cho màn hình Xem Danh sách product (XemProductActivity):

[code language=”java”]
package com.communityuni.androidkotlintomongodb

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
import com.communityuni.model.Product
import com.mongodb.MongoClient
import com.mongodb.MongoClientURI
import org.json.JSONObject

class XemProductActivity : AppCompatActivity() {
lateinit var lvProduct:ListView
lateinit var adapter:ArrayAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_xem_product)
addControls()
viewListProduct()
}

private fun viewListProduct() {
var task= ProductTask()
task.execute()
}
private fun addControls() {
lvProduct=findViewById(R.id.lvProduct)
adapter =ArrayAdapter(this,android.R.layout.simple_list_item_1)
lvProduct.adapter=adapter
}
inner class ProductTask : AsyncTask() {
override fun onPreExecute() {
super.onPreExecute()
adapter.clear()
}
override fun doInBackground(vararg p0: Any?): List {
var connectionString = MongoClientURI(“mongodb://172.16.96.173:27017”)
var mongoClient = MongoClient(connectionString)
var database = mongoClient.getDatabase(“QuanLySanPham”)
val collection = database.getCollection(“Product”)

var cursor = collection.find().iterator()
var dsProduct = ArrayList()
try {
while (cursor.hasNext()) {
val data = cursor.next().toJson()
val jsonObject = JSONObject(data)
val ma = jsonObject.getString(“Ma”)
val ten = jsonObject.getString(“Ten”)
val gia = jsonObject.getDouble(“DonGia”)
var product=Product(ma,ten,gia)
dsProduct.add(product)
}
} finally {
cursor.close()
}
return dsProduct
}
override fun onPostExecute(result: List?) {
super.onPostExecute(result)
adapter.addAll(result)
}
}
}
[/code]

Như vậy Tui đã hoàn tất bài hướng dẫn chi tiết về cách kết nối và truy vấn dữ liệu trong MongoDB.Chạy chương trình lên ta có được kết quả như mong muốn.

Các bạn có thể tải source code đầy đủ ở đây: Source code kết nối và truy suất dữ liệu MongoDB trong Android Kotlin.

Và các Em chú ý là Project này sẽ được dùng cho bài sau nữa nha, nên bắt buộc phải hiểu và làm được bài này cho tốt.

Bài học Sau Tui sẽ hướng dẫn các bạn các kỹ thuật tương tác dữ liệu (thêm, sửa, xóa) trực tiếp từ Android Kotlin tới MongoDB, các bạn chú ý theo dõi.

Các khóa học online khác, bạn có thể tham khảo tại đây:

https://unica.vn/?aff=11929

Chúc các bạn thành công!