অ্যান্ড্রয়েড রুম - অটো-জেনারেট সহ নতুন sertedোকানো সারিটির আইডি পান


138

এভাবেই আমি রুম অধ্যবসায় গ্রন্থাগারটি ব্যবহার করে ডাটাবেসে ডেটা serোকাচ্ছি:

সত্তা:

@Entity
class User {
    @PrimaryKey(autoGenerate = true)
    public int id;
    //...
}

ডেটা অ্যাক্সেস অবজেক্ট:

@Dao
public interface UserDao{
    @Insert(onConflict = IGNORE)
    void insertUser(User user);
    //...
}

পৃথক বাছাই করা কোয়েরি না লিখে উপরের পদ্ধতিতে নিজেই সন্নিবেশটি শেষ হয়ে গেলে কি ব্যবহারকারীর আইডি ফিরিয়ে দেওয়া সম্ভব?


1
আপনি কি অপারেশনের ফলাফল হিসাবে ব্যবহার করার পরিবর্তে intবা longপরিবর্তে চেষ্টা করেছেন ? void@Insert
ম্যাটপ্যাগ

এখনো না. আমি একটা শট দেব!
সর্পিলদেব

আমি একটি উত্তরও যুক্ত করেছি কারণ ডকুমেন্টেশনে রেফারেন্সটি খুঁজে পেয়েছি এবং এটি কাজ করবে বলে আমি যথেষ্ট আত্মবিশ্বাসী;)
ম্যাটপ্যাগ

3
এটি একটি দিয়ে করা হবে না aSyncTask? আপনি কীভাবে আপনার সংগ্রহস্থল কার্য থেকে মানটি ফিরিয়ে দিচ্ছেন?
নিমিটজ 14

উত্তর:


191

এখানে ডকুমেন্টেশন উপর ভিত্তি করে (কোড স্নিপেটের নীচে)

টীকা সহ টীকাযুক্ত একটি পদ্ধতি @Insertফিরে আসতে পারে:

  • long একক সন্নিবেশ অপারেশন জন্য
  • long[]অথবা Long[]বা List<Long>একাধিক sertোকানো অপারেশনগুলির জন্য
  • void যদি আপনি idোকানো আইডি (গুলি) সম্পর্কে চিন্তা না করেন

4
কেন ডকুমেন্টেশনে এটি আইডি টাইপটির জন্য ইনট বলে তবে বেশি ফেরত দেয়? ধরে নিচ্ছে আইডি কখনই লম্বা হওয়ার মতো বড় হবে না? সুতরাং সারি আইডি এবং স্বয়ংক্রিয় উত্পন্ন আইডি আক্ষরিক একই জিনিস?
মাইকেল ভেস্কোভো

11
এসকিউএলাইটে আপনার কাছে থাকা সবচেয়ে বড় প্রাথমিক কী আইডিটি একটি bit৪ বিট স্বাক্ষরিত পূর্ণসংখ্যা, তাই সর্বাধিক মান 9,223,372,036,854,775,807 (কেবল ইতিবাচক কারণ এটি একটি আইডি)। জাভাতে কোন ইন্টি 32 বিট স্বাক্ষরিত সংখ্যা এবং সর্বাধিক ধনাত্মক মান 2,147,483,647, তাই সমস্ত আইডির প্রতিনিধিত্ব করতে সক্ষম হয় না। আপনাকে একটি জাভা দীর্ঘ ব্যবহার করতে হবে যার সমস্ত আইডির প্রতিনিধিত্ব করতে এর সর্বাধিক মান 9,223,372,036,854,775,807। ডকুমেন্টেশন কেবল উদাহরণস্বরূপ, তবে এপিআই এটি বিবেচনায় রেখে ডিজাইন করা হয়েছিল (এজন্য এটি দীর্ঘ এবং
আন্তঃ

2
ঠিক আছে তাই এটি সত্যিই একটি দীর্ঘ হওয়া উচিত। তবে সম্ভবত বেশিরভাগ ক্ষেত্রে একটি স্ক্লাইট ডিবিতে 9 বিলিয়ন সারি থাকবে না তাই তারা ব্যবহারকারীর উদাহরণ হিসাবে অন্তর্ ব্যবহার করে যেহেতু এতে কম স্মৃতি লাগে (বা এটি একটি ভুল)। এটাই আমি এ থেকে নিই। কেন এটি দীর্ঘায়িত হয় সে সম্পর্কে ব্যাখ্যার জন্য ধন্যবাদ।
মাইকেল ভেস্কোভো

3
আপনি ঠিক বলেছেন, তবে ঘরটির এপিআইগুলি সবচেয়ে খারাপ পরিস্থিতির মধ্যেও কাজ করা উচিত এবং অবশ্যই এসকিউাইটের স্পেসিফিকেশন অনুসরণ করা উচিত। এই নির্দিষ্ট ক্ষেত্রে দীর্ঘ সময় ধরে ব্যবহার করা ব্যবহারিকভাবে একই জিনিস, অতিরিক্ত মেমরির খরচ নগণ্য
ম্যাটপ্যাগ

1
@ ম্যাটপ্যাগ আপনার মূল লিঙ্কটিতে আর এই আচরণের একটি নিশ্চিতকরণ অন্তর্ভুক্ত করা হয়নি (এবং দুঃখের বিষয়, কক্ষের সন্নিবেশ টীকা দেওয়ার জন্য এপিআই রেফারেন্সও নেই )। অনুসন্ধানের একটি বিট আমি পাওয়া এই এবং আপনার উত্তর লিংক আপডেট করা হয়েছে। আশা করা যায় এটি শেষের চেয়ে খানিকটা ভাল অব্যাহত রয়েছে কারণ এটি তথ্যটি বেশ তাৎপর্যপূর্ণ bit
কোডক্লাউন 42

27

@Insertফাংশন আসতে পারেন void, long, long[]বা List<Long>। এটি চেষ্টা করুন।

 @Insert(onConflict = OnConflictStrategy.REPLACE)
  long insert(User user);

 // Insert multiple items
 @Insert(onConflict = OnConflictStrategy.REPLACE)
  long[] insert(User... user);

5
return Single.fromCallable(() -> dbService.YourDao().insert(mObject));
মেরিট

8

কোনও রেকর্ডের জন্য সন্নিবেশের ফেরতের মান 1 হবে যদি আপনার বিবৃতি সফলভাবে হয়।

আপনি যদি অবজেক্টের তালিকা সন্নিবেশ করতে চান তবে আপনি এতে যেতে পারেন:

@Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] addAll(List<Object> list);

এবং এটি আরএক্স 2 দিয়ে কার্যকর করুন:

Observable.fromCallable(new Callable<Object>() {
        @Override
        public Object call() throws Exception {
            return yourDao.addAll(list<Object>);
        }
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
        @Override
        public void accept(@NonNull Object o) throws Exception {
           // the o will be Long[].size => numbers of inserted records.

        }
    });

1
"যদি আপনার বিবৃতিটি সফলভাবে হয় তবে একটি রেকর্ডের জন্য সন্নিবেশের ফেরতের মান 1 হবে" -> এই ডকুমেন্টেশন অনুসারে: developer.android.com/training/data-stores/room/accessing-data "যদি @ সন্নিবেশ পদ্ধতিটি প্রাপ্ত হয় তবে 1 প্যারামিটার, এটি একটি দীর্ঘ ফিরিয়ে দিতে পারে, যা সন্নিবেশ করা আইটেমটির জন্য নতুন সারি আইড the প্যারামিটারটি যদি অ্যারে বা সংগ্রহ হয় তবে এটির পরিবর্তে দীর্ঘ [] বা তালিকা << দীর্ঘ> ফিরে আসা উচিত । "
কোডক্লাউন 42

4

নিম্নলিখিত স্নিপলেট দ্বারা সারি আইডি পান। এটি ফিউচারের সাথে এক্সিকিউটর সার্ভিসে কলযোগ্য ব্যবহার করে।

 private UserDao userDao;
 private ExecutorService executorService;

 public long insertUploadStatus(User user) {
    Callable<Long> insertCallable = () -> userDao.insert(user);
    long rowId = 0;

    Future<Long> future = executorService.submit(insertCallable);
     try {
         rowId = future.get();
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return rowId;
 }

রেফ: জবাব এক্সিকিউটর পরিষেবা টিউটোরিয়াল কলযোগ্য আরও তথ্যের জন্য।


3

আপনার Longদাওতে , সন্নিবেশ ক্যোয়ারী অর্থাত্ সারি প্রবেশ করানো হয়।

 @Insert(onConflict = OnConflictStrategy.REPLACE)
 fun insert(recipes: CookingRecipes): Long

আপনার মডেল (সংগ্রহশালা) শ্রেণিতে: (এমভিভিএম)

fun addRecipesData(cookingRecipes: CookingRecipes): Single<Long>? {
        return Single.fromCallable<Long> { recipesDao.insertManual(cookingRecipes) }
}

আপনার মডেলভিউ ক্লাসে: (এমভিভিএম) ডিসপোজেবলসিংলঅবার্সভার সহ লাইভ ডেটা হ্যান্ডেল করুন।
ওয়ার্কিং সোসার রেফারেন্স: https://github.com/SupriyaNaveen/ কুকিংআরসিপস


1

অনেক লড়াইয়ের পরেও আমি এটি সমাধান করতে পেরেছি। এমএমভিএম আর্কিটেকচার ব্যবহার করে আমার সমাধানটি এখানে দেওয়া হয়েছে :

Student.kt

@Entity(tableName = "students")
data class Student(
    @NotNull var name: String,
    @NotNull var password: String,
    var subject: String,
    var email: String

) {

    @PrimaryKey(autoGenerate = true)
    var roll: Int = 0
}

StudentDao.kt

interface StudentDao {
    @Insert
    fun insertStudent(student: Student) : Long
}

StudentRepository.kt

    class StudentRepository private constructor(private val studentDao: StudentDao)
    {

        fun getStudents() = studentDao.getStudents()

        fun insertStudent(student: Student): Single<Long>? {
            return Single.fromCallable(
                Callable<Long> { studentDao.insertStudent(student) }
            )
        }

 companion object {

        // For Singleton instantiation
        @Volatile private var instance: StudentRepository? = null

        fun getInstance(studentDao: StudentDao) =
                instance ?: synchronized(this) {
                    instance ?: StudentRepository(studentDao).also { instance = it }
                }
    }
}

StudentViewModel.kt

class StudentViewModel (application: Application) : AndroidViewModel(application) {

var status = MutableLiveData<Boolean?>()
private var repository: StudentRepository = StudentRepository.getInstance( AppDatabase.getInstance(application).studentDao())
private val disposable = CompositeDisposable()

fun insertStudent(student: Student) {
        disposable.add(
            repository.insertStudent(student)
                ?.subscribeOn(Schedulers.newThread())
                ?.observeOn(AndroidSchedulers.mainThread())
                ?.subscribeWith(object : DisposableSingleObserver<Long>() {
                    override fun onSuccess(newReturnId: Long?) {
                        Log.d("ViewModel Insert", newReturnId.toString())
                        status.postValue(true)
                    }

                    override fun onError(e: Throwable?) {
                        status.postValue(false)
                    }

                })
        )
    }
}

খণ্ডে:

class RegistrationFragment : Fragment() {
    private lateinit var dataBinding : FragmentRegistrationBinding
    private val viewModel: StudentViewModel by viewModels()

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initialiseStudent()
        viewModel.status.observe(viewLifecycleOwner, Observer { status ->
            status?.let {
                if(it){
                    Toast.makeText(context , "Data Inserted Sucessfully" , Toast.LENGTH_LONG).show()
                    val action = RegistrationFragmentDirections.actionRegistrationFragmentToLoginFragment()
                    Navigation.findNavController(view).navigate(action)
                } else
                    Toast.makeText(context , "Something went wrong" , Toast.LENGTH_LONG).show()
                //Reset status value at first to prevent multitriggering
                //and to be available to trigger action again
                viewModel.status.value = null
                //Display Toast or snackbar
            }
        })

    }

    fun initialiseStudent() {
        var student = Student(name =dataBinding.edName.text.toString(),
            password= dataBinding.edPassword.text.toString(),
            subject = "",
            email = dataBinding.edEmail.text.toString())
        dataBinding.viewmodel = viewModel
        dataBinding.student = student
    }
}

আমি ডেটাবাইন্ডিং ব্যবহার করেছি e এখানে আমার এক্সএমএল:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="student"
            type="com.kgandroid.studentsubject.data.Student" />

        <variable
            name="listener"
            type="com.kgandroid.studentsubject.view.RegistrationClickListener" />

        <variable
            name="viewmodel"
            type="com.kgandroid.studentsubject.viewmodel.StudentViewModel" />

    </data>


    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        tools:context="com.kgandroid.studentsubject.view.RegistrationFragment">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/constarintLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:isScrollContainer="true">

            <TextView
                android:id="@+id/tvRoll"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="16dp"
                android:gravity="center_horizontal"
                android:text="Roll : 1"
                android:textColor="@color/colorPrimary"
                android:textSize="18sp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <EditText
                android:id="@+id/edName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="16dp"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="Name"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvRoll" />

            <TextView
                android:id="@+id/tvName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="16dp"
                android:layout_marginEnd="16dp"
                android:text="Name:"
                android:textColor="@color/colorPrimary"
                android:textSize="18sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/edName"
                app:layout_constraintEnd_toStartOf="@+id/edName"
                app:layout_constraintStart_toStartOf="parent" />

            <TextView
                android:id="@+id/tvEmail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Email"
                android:textColor="@color/colorPrimary"
                android:textSize="18sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/edEmail"
                app:layout_constraintEnd_toStartOf="@+id/edEmail"
                app:layout_constraintStart_toStartOf="parent" />

            <EditText
                android:id="@+id/edEmail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="16dp"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="Name"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/edName" />

            <TextView
                android:id="@+id/textView6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Password"
                android:textColor="@color/colorPrimary"
                android:textSize="18sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/edPassword"
                app:layout_constraintEnd_toStartOf="@+id/edPassword"
                app:layout_constraintStart_toStartOf="parent" />

            <EditText
                android:id="@+id/edPassword"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="16dp"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="Name"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/edEmail" />

            <Button
                android:id="@+id/button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="32dp"
                android:layout_marginTop="24dp"
                android:layout_marginEnd="32dp"
                android:background="@color/colorPrimary"
                android:text="REGISTER"
                android:onClick="@{() -> viewmodel.insertStudent(student)}"
                android:textColor="@android:color/background_light"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/edPassword" />
        </androidx.constraintlayout.widget.ConstraintLayout>


    </androidx.core.widget.NestedScrollView>
</layout>

রুম সন্নিবেশ এবং মুছে ফেলা অপারেশনটি আলাদা থ্রেডে করতে হবে বলে আমি এ্যাসিনটাস্ক দিয়ে এটি সম্পাদন করতে অনেক সংগ্রাম করেছি। শেষ পর্যন্ত আরএক্সজেবাতে একক প্রকারের পর্যবেক্ষণযোগ্য এর সাহায্যে এটি করতে সক্ষম।

Rxjava এর জন্য গ্রেডল নির্ভরতা:

implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.0.3' 

0

ডকুমেন্টেশন অনুসারে @ ইনসার্ট দ্বারা বর্ণিত ফাংশনগুলি রো-আইড ফিরে আসতে পারে।

যদি @ অন্তর্ভুক্ত পদ্ধতিটি কেবলমাত্র 1 টি প্যারামিটার গ্রহণ করে তবে এটি একটি দীর্ঘ ফিরিয়ে দিতে পারে, যা sertedোকানো আইটেমটির জন্য নতুন সারিআইডি। যদি প্যারামিটারটি একটি অ্যারে বা সংগ্রহ হয় তবে এটির পরিবর্তে দীর্ঘ [] বা তালিকা << দীর্ঘ> ফিরিয়ে দেওয়া উচিত।

আমার এটির যে সমস্যাটি তা হ'ল এটি রোডআইডি ফিরিয়ে দেয় এবং আইডিটি দেয় না এবং আমি এখনও রোডআইডি ব্যবহার করে কীভাবে আইডি পেতে পারি তা খুঁজে পাইনি।

দুঃখজনকভাবে আমি এখনও মন্তব্য করতে পারি না, কারণ আমার 50 টি খ্যাতি নেই, সুতরাং আমি পরিবর্তে এটি উত্তর হিসাবে পোস্ট করছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.