एंड्रॉइड रूम में एक इकाई के कुछ विशिष्ट क्षेत्र को अपडेट करें


122

मैं अपने नए प्रोजेक्ट के लिए एंड्रॉइड रूम दृढ़ता पुस्तकालय का उपयोग कर रहा हूं। मैं तालिका के कुछ क्षेत्र को अपडेट करना चाहता हूं। मैंने अपनी तरह की कोशिश की है Dao-

// Method 1:

@Dao
public interface TourDao {
    @Update
    int updateTour(Tour tour);
}

लेकिन जब मैं इस पद्धति का उपयोग करके अपडेट करने का प्रयास करता हूं तो यह इकाई के प्रत्येक क्षेत्र को अपडेट करता है जहां यह टूर ऑब्जेक्ट के प्राथमिक मुख्य मूल्य से मेल खाता है। मैंने उपयोग कर लिया है@Query

// Method 2:

@Query("UPDATE Tour SET endAddress = :end_address WHERE id = :tid")
int updateTour(long tid, String end_address);

यह काम कर रहा है लेकिन मेरे मामले में कई प्रश्न होंगे क्योंकि मेरी इकाई में कई क्षेत्र हैं। मैं जानना चाहता हूं कि मैं कुछ फ़ील्ड (सभी नहीं) को कैसे अपडेट कर सकता हूं जैसे Method 1आईडी = 1; (आईडी ऑटो उत्पन्न प्राथमिक कुंजी है)।

// Entity:

@Entity
public class Tour {
    @PrimaryKey(autoGenerate = true)
    public long id;
    private String startAddress;
    private String endAddress;
    //constructor, getter and setter
}

टेबल में सूची कैसे अपडेट करें। वास्तव में मैंने TypeConverter द्वारा तालिका में सूची सम्मिलित की है। लेकिन अपडेट के साथ आते समय यह काम नहीं कर रहा है। कृपया सुझाव दें, यदि आपने इस तरह के किसी मुद्दे का सामना किया है।
अमन गुप्ता - ShooTeR

@ AmanGupta-ShOoTeR क्या आपको ऊपर टिप्पणी के लिए कोई समाधान मिला?
स्काईजेक

मेरी लाइब्रेरी क्रिप्टन पर्सिस्टेंस लाइब्रेरी उस रूम लाइब्रेरी के समान काम करती है। अगर आप क्रिप्टन
xcesco

@ AmanGupta-ShOoTeR मैंने '@Query' का उपयोग करके अपडेट पर इस तरह के मुद्दे का सामना किया। तब मैंने अद्यतन के बजाय एक ही प्राथमिक कुंजी मान के साथ एक ऑब्जेक्ट बनाकर '@Insert (onConflict = OnConflictStrategy.REPLACE) का उपयोग किया और यह काम किया
Rasel

जवाबों:


68

मैं जानना चाहता हूं कि मैं विधि 1 की तरह कुछ फ़ील्ड (सभी नहीं) को कैसे अपडेट कर सकता हूं जहां आईडी = 1

उपयोग @Query, जैसा कि आपने विधि 2 में किया था।

मेरे मामले में बहुत लंबी क्वेरी है क्योंकि मेरी इकाई में कई क्षेत्र हैं

फिर छोटी इकाइयाँ हैं। या, व्यक्तिगत रूप से फ़ील्ड्स को अपडेट न करें, बल्कि डेटाबेस के साथ अधिक मोटे-अनाज वाले इंटरैक्शन करें।

IOW, स्वयं कक्ष में ऐसा कुछ भी नहीं है जो आप चाहते हैं।


क्या किसी भी पैरामीटर को पारित किए बिना तालिका को अपडेट करना संभव है? मेरा मतलब है कि एक बूलियन मूल्य स्वैप करना।
विष्णु टीबी

1
@ विष्णु टीबी: यदि आप एक एसक्यूएल स्टेटमेंट बना सकते हैं, जो आप चाहते हैं, तो आपको इसका उपयोग करने में सक्षम होना चाहिए @Query
कॉमंसवेयर

@CommonsWare मिल गया। मैं एक बूलियन सच्चे मूल्य के साथ पंक्तियों का एक सेट प्राप्त करना चाहता था। लेकिन रूम आर्क ने मुझे पैरामीटर के रूप में सच / गलत पास करने की अनुमति नहीं दी। इसके बजाय true =1,false=0 SELECT * FROM note_table WHERE isNoteArchived == 0
विष्णु टीबी

4
कमरा 2.2.0-अल्फा01 ( डेवलपर. android.com/jetpack/androidx/releases/… ) @Update के लिए एक नया पैरामीटर पेश किया, जो आपको लक्ष्य इकाई सेट करने देता है। इससे आंशिक अद्यतन संभव होना चाहिए।
जोनास

84

SQLite अपडेट डॉक्स के अनुसार :

<!-- language: lang-java -->
@Query("UPDATE tableName SET 
    field1 = :value1,
    field2 = :value2, 
    ...
    //some more fields to update
    ...
    field_N= :value_N
    WHERE id = :id)

int updateTour(long id, 
               Type value1, 
               Type value2, 
               ... ,
               // some more values here
               ... ,
               Type value_N);

उदाहरण:

निकाय:

@Entity(tableName = "orders")
public class Order {

@NonNull
@PrimaryKey
@ColumnInfo(name = "order_id")
private int id;

@ColumnInfo(name = "order_title")
private String title;

@ColumnInfo(name = "order_amount")
private Float amount;

@ColumnInfo(name = "order_price")
private Float price;

@ColumnInfo(name = "order_desc")
private String description;

// ... methods, getters, setters
}

दाव:

@Dao
public interface OrderDao {

@Query("SELECT * FROM orders")
List<Order> getOrderList();

@Query("SELECT * FROM orders")
LiveData<List<Order>> getOrderLiveList();

@Query("SELECT * FROM orders WHERE order_id =:orderId")
LiveData<Order> getLiveOrderById(int orderId);

/**
* Updating only price
* By order id
*/
@Query("UPDATE orders SET order_price=:price WHERE order_id = :id")
void update(Float price, int id);

/**
* Updating only amount and price
* By order id
*/
@Query("UPDATE orders SET order_amount = :amount, price = :price WHERE order_id =:id")
void update(Float amount, Float price, int id);

/**
* Updating only title and description
* By order id
*/
@Query("UPDATE orders SET order_desc = :description, order_title= :title WHERE order_id =:id")
void update(String description, String title, int id);

@Update
void update(Order order);

@Delete
void delete(Order order);

@Insert(onConflict = REPLACE)
void insert(Order order);
}

4
क्या आप इसे और अधिक समझा सकते हैं?
माइकल

1
प्रश्न से इकाई के साथ DAO विधि इस तरह दिखाई देगी: @Query ("UPDATE Tour SET endAddress =: end_address, startAdress =: start_address WHERE id =: tid) int updateTour (long tid, स्ट्रिंग end_address, String start_address);
Jurij Pitul

1
मुझे आपके समाधान का मतलब था :) अन्य उपयोगकर्ताओं के लिए इसे देखने के लिए बेहतर है
माइकल

ओह, मुझे लगा कि यह स्पष्ट है। अब तय हो गया।
ज्यूरिज पिटुलजा

14

के रूप में कक्ष 2.2.0 अक्टूबर 2019 को जारी किया है, तो आप अद्यतन के लिए एक लक्ष्य इकाई निर्दिष्ट कर सकते हैं। फिर यदि अपडेट पैरामीटर अलग है, तो कक्ष केवल आंशिक इकाई कॉलम को अपडेट करेगा। ओपी प्रश्न के लिए एक उदाहरण यह थोड़ा और स्पष्ट रूप से दिखाएगा।

@Update(entity = Tour::class)
fun update(obj: TourUpdate)

@Entity
public class TourUpdate {
    @ColumnInfo(name = "id")
    public long id;
    @ColumnInfo(name = "endAddress")
    private String endAddress;
}

ध्यान दें कि आपको प्रश्न में अपनी वास्तविक टूर इकाई के साथ, एक नई आंशिक इकाई बनाना है जिसका नाम टूरअपडेट है। अब जब आप TourUpdate ऑब्जेक्ट के साथ अपडेट कॉल करते हैं, तो यह एंडएड्रेस को अपडेट करेगा और स्टार्टअड्रेस वैल्यू को वही छोड़ देगा। यह मेरे लिए मेरे DAO में एक InsertOrUpdate पद्धति के usecase के लिए एकदम सही काम करता है जो API से नए दूरस्थ मानों के साथ DB को अद्यतन करता है लेकिन स्थानीय ऐप डेटा को अकेले तालिका में छोड़ देता है।


6

आप यह कोशिश कर सकते हैं, लेकिन प्रदर्शन थोड़ा खराब हो सकता है:

@Dao
public abstract class TourDao {

    @Query("SELECT * FROM Tour WHERE id == :id")
    public abstract Tour getTour(int id);

    @Update
    public abstract int updateTour(Tour tour);

    public void updateTour(int id, String end_address) {
        Tour tour = getTour(id);
        tour.end_address = end_address;
        updateTour(tour);
    }
}

2

मुझे लगता है कि आपको केवल कुछ विशिष्ट फ़ील्ड को अपडेट करने की आवश्यकता नहीं है। बस पूरे डेटा को अपडेट करें।

@ उपयोगी क्वेरी

यह मूल रूप से दी गई क्वेरी है। कुछ नई क्वेरी बनाने की आवश्यकता नहीं है।

@Dao
interface MemoDao {

    @Insert
    suspend fun insert(memo: Memo)

    @Delete
    suspend fun delete(memo: Memo)

    @Update
    suspend fun update(memo: Memo)
}

Memo.class

@Entity
data class Memo (
    @PrimaryKey(autoGenerate = true) val id: Int,
    @ColumnInfo(name = "title") val title: String?,
    @ColumnInfo(name = "content") val content: String?,
    @ColumnInfo(name = "photo") val photo: List<ByteArray>?
)

केवल एक चीज जिसे आपको जानना है, वह है 'आईडी'। उदाहरण के लिए, यदि आप केवल 'शीर्षक' को अद्यतन करना चाहते हैं, तो आप पहले से सम्मिलित डेटा से 'सामग्री' और 'फोटो' का पुन: उपयोग कर सकते हैं वास्तविक कोड में, इस तरह का उपयोग करें

val memo = Memo(id, title, content, byteArrayList)
memoViewModel.update(memo)

-3

यदि आपको एक विशिष्ट उपयोगकर्ता आईडी "x" के लिए उपयोगकर्ता जानकारी अपडेट करने की आवश्यकता है,

  1. आपको एक dbManager वर्ग बनाने की आवश्यकता है जो डेटाबेस को इसके निर्माता में इनिशियलाइज़ करेगा और आपके viewModel और DAO के बीच मध्यस्थ के रूप में कार्य करेगा, और भी।
  2. ViewModel डेटाबेस का उपयोग करने के लिए dbManager का एक उदाहरण प्रारंभ हो जाएगा। कोड इस तरह दिखना चाहिए:

       @Entity
        class User{
        @PrimaryKey
        String userId;
        String username;
        }
    
        Interface UserDao{
        //forUpdate
        @Update
        void updateUser(User user)
        }
    
        Class DbManager{
        //AppDatabase gets the static object o roomDatabase.
        AppDatabase appDatabase;
        UserDao userDao;
        public DbManager(Application application ){
        appDatabase = AppDatabase.getInstance(application);
    
        //getUserDao is and abstract method of type UserDao declared in AppDatabase //class
        userDao = appDatabase.getUserDao();
        } 
    
        public void updateUser(User user, boolean isUpdate){
        new InsertUpdateUserAsyncTask(userDao,isUpdate).execute(user);
        }
    
    
    
        public static class InsertUpdateUserAsyncTask extends AsyncTask<User, Void, Void> {
    
    
         private UserDao userDAO;
         private boolean isInsert;
    
         public InsertUpdateBrandAsyncTask(BrandDAO userDAO, boolean isInsert) {
           this. userDAO = userDAO;
           this.isInsert = isInsert;
         }
    
         @Override
         protected Void doInBackground(User... users) {
           if (isInsert)
        userDAO.insertBrand(brandEntities[0]);
           else
        //for update
        userDAO.updateBrand(users[0]);
        //try {
        //  Thread.sleep(1000);
        //} catch (InterruptedException e) {
        //  e.printStackTrace();
        //}
           return null;
         }
          }
        }
    
         Class UserViewModel{
         DbManager dbManager;
         public UserViewModel(Application application){
         dbmanager = new DbMnager(application);
         }
    
         public void updateUser(User user, boolean isUpdate){
         dbmanager.updateUser(user,isUpdate);
         }
    
         }
    
    
    
    
    Now in your activity or fragment initialise your UserViewModel like this:
    
    UserViewModel userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
    

    फिर अपने उपयोगकर्ता आइटम को इस तरह अपडेट करें, मान लें कि आपका उपयोगकर्ता 1111 है और उपयोगकर्ता नाम "xyz" है जिसे "zyx" में बदलना होगा।

    उपयोगकर्ता का id 1122 उपयोगकर्ता ऑब्जेक्ट प्राप्त करें

User user = new user();
 if(user.getUserId() == 1122){
   user.setuserName("zyx");
   userViewModel.updateUser(user);
 }

यह एक कच्चा कोड है, आशा है कि यह आपकी मदद करेगा।

खुश कोडिंग


10
आप वास्तव में एक दृश्यदर्शी में डेटाबेस कार्रवाई करते हैं ??? भगवान नहीं plz नहीं ...: '(सिर्फ मॉडल का नाम आपको चेहरे पर मारना चाहिए
mcfly

@mcfly, दृश्य मॉडल में डेटाबेस संचालन करना क्यों बुरा माना जाता है?
डैनियल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.