说明:最近碰到一个需求,在安卓上使用greendao框架,实现增删改查数据
效果图:
step1:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
step2:
plugins {
id 'com.android.application'
id 'org.greenrobot.greendao'
}
android {
compileSdkVersion 32
defaultConfig {
applicationId "com.example.iosdialogdemo"
minSdkVersion 16
targetSdkVersion 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
greendao {
schemaVersion 7
daoPackage 'com.example.iosdialogdemo'
targetGenDir 'src/main/java'
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'org.greenrobot:greendao:3.2.2'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
}
step3:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.iosdialogdemo">
<application
android:name=".GreenApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.IosDialogDemo">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
step4:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/etLanguage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingRight="8dp" />
<Button
android:id="@+id/btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:backgroundTint="@android:color/holo_purple"
android:text="新增"
android:textColor="@android:color/white" />
<Button
android:id="@+id/btn_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:backgroundTint="@android:color/holo_purple"
android:text="修改"
android:textColor="@android:color/white" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvLanguage"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item" />
</LinearLayout>
step5:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tvOrderNumber"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="1"
android:textColor="@color/white"
android:background="@color/purple_200"
app:layout_constraintBottom_toBottomOf="@+id/tvLanguage"
app:layout_constraintEnd_toStartOf="@+id/tvLanguage"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/tvLanguage" />
<TextView
android:id="@+id/tvLanguage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Bahasa"
android:textColor="@color/white"
android:background="@color/teal_200"
app:layout_constraintBottom_toBottomOf="@+id/btnDelete"
app:layout_constraintEnd_toStartOf="@+id/btnDelete"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/tvOrderNumber"
app:layout_constraintTop_toTopOf="@+id/btnDelete" />
<Button
android:id="@+id/btnDelete"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="删除"
android:backgroundTint="@android:color/holo_blue_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/tvLanguage"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
step6:
package com.example.iosdialogdemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
import org.greenrobot.greendao.AbstractDaoMaster;
import org.greenrobot.greendao.database.StandardDatabase;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaseOpenHelper;
import org.greenrobot.greendao.identityscope.IdentityScopeType;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* Master of DAO (schema version 7): knows all DAOs.
*/
public class DaoMaster extends AbstractDaoMaster {
public static final int SCHEMA_VERSION = 7;
/** Creates underlying database table using DAOs. */
public static void createAllTables(Database db, boolean ifNotExists) {
UserDao.createTable(db, ifNotExists);
}
/** Drops underlying database table using DAOs. */
public static void dropAllTables(Database db, boolean ifExists) {
UserDao.dropTable(db, ifExists);
}
/**
* WARNING: Drops all table on Upgrade! Use only during development.
* Convenience method using a {@link DevOpenHelper}.
*/
public static DaoSession newDevSession(Context context, String name) {
Database db = new DevOpenHelper(context, name).getWritableDb();
DaoMaster daoMaster = new DaoMaster(db);
return daoMaster.newSession();
}
public DaoMaster(SQLiteDatabase db) {
this(new StandardDatabase(db));
}
public DaoMaster(Database db) {
super(db, SCHEMA_VERSION);
registerDaoClass(UserDao.class);
}
public DaoSession newSession() {
return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}
public DaoSession newSession(IdentityScopeType type) {
return new DaoSession(db, type, daoConfigMap);
}
/**
* Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} -
*/
public static abstract class OpenHelper extends DatabaseOpenHelper {
public OpenHelper(Context context, String name) {
super(context, name, SCHEMA_VERSION);
}
public OpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory, SCHEMA_VERSION);
}
@Override
public void onCreate(Database db) {
Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
createAllTables(db, false);
}
}
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name) {
super(context, name);
}
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
}
}
step7:
package com.example.iosdialogdemo;
import java.util.Map;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.AbstractDaoSession;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.identityscope.IdentityScopeType;
import org.greenrobot.greendao.internal.DaoConfig;
import com.example.iosdialogdemo.User;
import com.example.iosdialogdemo.UserDao;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* {@inheritDoc}
*
* @see org.greenrobot.greendao.AbstractDaoSession
*/
public class DaoSession extends AbstractDaoSession {
private final DaoConfig userDaoConfig;
private final UserDao userDao;
public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
daoConfigMap) {
super(db);
userDaoConfig = daoConfigMap.get(UserDao.class).clone();
userDaoConfig.initIdentityScope(type);
userDao = new UserDao(userDaoConfig, this);
registerDao(User.class, userDao);
}
public void clear() {
userDaoConfig.clearIdentityScope();
}
public UserDao getUserDao() {
return userDao;
}
}
step8:
package com.example.iosdialogdemo;
import android.app.Application;
import org.greenrobot.greendao.database.Database;
/**
* Created by rhodel on 8/15/2017.
*/
public class GreenApp extends Application {
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db");
Database db = helper.getWritableDb();
daoSession = new DaoMaster(db).newSession();
}
@Override
public void onTerminate() {
super.onTerminate();
daoSession.clear();
}
public DaoSession getDaoSession() {
return daoSession;
}
}
step9:
package com.example.iosdialogdemo;
public interface ILanguageRecycleListener {
void itemOnClick(int model,Long id,String title,int position);
/* mode1 0:id,1:title,2:delete*/
}
step10:
package com.example.iosdialogdemo;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class LanguageRecycleAdapter extends RecyclerView.Adapter<LanguageViewHolder> {
private List<User> languageList = new ArrayList<>();
private ILanguageRecycleListener listener;
public LanguageRecycleAdapter(List<User> languageList, ILanguageRecycleListener listener) {
this.languageList = languageList;
this.listener = listener;
Log.e("TAG", "LanguageRecycleAdapter " + languageList.size());
}
public void setData(List<User> languageList2) {
this.languageList = languageList2;
}
@NonNull
@Override
public LanguageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LanguageViewHolder holder;
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
holder = new LanguageViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull LanguageViewHolder holder, final int position) {
holder.orderNumber.setText(String.valueOf(position));
holder.language.setText(languageList.get(position).getName());
holder.orderNumber.setText(String.valueOf(languageList.get(position).getId()));
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.itemOnClick(2,languageList.get(position).getId(),languageList.get(position).getName(),position);
}
});
holder.orderNumber.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.itemOnClick(0,languageList.get(position).getId(),languageList.get(position).getName(),position);
}
});
holder.language.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.itemOnClick(1,languageList.get(position).getId(),languageList.get(position).getName(),position);
}
});
}
@Override
public int getItemCount() {
return languageList.size();
}
}
step11:
package com.example.iosdialogdemo;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class LanguageViewHolder extends RecyclerView.ViewHolder {
TextView orderNumber;
TextView language;
Button btnDelete;
public LanguageViewHolder(@NonNull View itemView) {
super(itemView);
orderNumber = itemView.findViewById(R.id.tvOrderNumber);
language = itemView.findViewById(R.id.tvLanguage);
btnDelete = itemView.findViewById(R.id.btnDelete);
}
}
step12:
package com.example.iosdialogdemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ILanguageRecycleListener {
private LanguageRecycleAdapter languageRecycleAdapter;
private RecyclerView rvLanguage;
// private List<String> languageList = new ArrayList<>();
private EditText editText;
private Button btn_add,btn_update;
private UserDao userDao;
private DaoSession daoSession;
private List<User> languageList;
private Long id2;
private String title2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
daoSession = ((GreenApp) getApplication()).getDaoSession();
userDao = daoSession.getUserDao();
languageList = new ArrayList<>();
if (languageList!=null){
languageList.clear();
}
languageList.addAll(userDao.queryBuilder().list());
rvLanguage = findViewById(R.id.rvLanguage);
editText= findViewById(R.id.etLanguage);
btn_add= findViewById(R.id.btn_add);
btn_update= findViewById(R.id.btn_update);
RecyclerView.LayoutManager layoutManager = new
LinearLayoutManager(this);
rvLanguage.setLayoutManager(layoutManager);
languageRecycleAdapter = new LanguageRecycleAdapter(languageList, this);
rvLanguage.setAdapter(languageRecycleAdapter);
btn_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String etString = editText.getText().toString();
// languageList.add(etString);
User user = new User();
user.setName(etString);
userDao.insert(user);
if (languageList!=null){
languageList.clear();
}
languageList.addAll(userDao.queryBuilder().list());
languageRecycleAdapter.setData(languageList);
languageRecycleAdapter.notifyDataSetChanged();
}
});
btn_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String etString = editText.getText().toString();
// languageList.add(etString);
Log.e("TAG", "sql_itemOnClick: " +id2+"==="+title2);
User user = new User();
user.setName(etString);
user.setId(id2);
userDao.update(user);
if (languageList!=null){
languageList.clear();
}
languageList.addAll(userDao.queryBuilder().list());
languageRecycleAdapter.setData(languageList);
languageRecycleAdapter.notifyDataSetChanged();
}
});
}
@Override
public void itemOnClick(int model,Long id, String title,int position) {
Log.e("TAG", "itemOnClick: " + id + ", " + position);
if (model==2){
userDao.deleteByKey(id);
if (languageList!=null){
languageList.clear();
}
languageList.addAll(userDao.queryBuilder().list());
Log.e("TAG", "sql_itemOnClick: " +languageList);
languageRecycleAdapter.setData(languageList);
languageRecycleAdapter.notifyDataSetChanged();
/* languageList.remove(position);
languageRecycleAdapter.setData(languageList);
languageRecycleAdapter.notifyDataSetChanged();*/
}else if (model==1){
editText.setText(title);
id2 = id;
title2=title;
}
}
}
step13:
package com.example.iosdialogdemo;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Generated;
/**
* Created by rhodel on 8/15/2017.
*/
@Entity
public class User {
@Id(autoincrement = true)
private Long id;
private String name;
@Generated(hash = 873297011)
public User(Long id, String name) {
this.id = id;
this.name = name;
}
@Generated(hash = 586692638)
public User() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
step14:
package com.example.iosdialogdemo;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.Property;
import org.greenrobot.greendao.internal.DaoConfig;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaseStatement;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* DAO for table "USER".
*/
public class UserDao extends AbstractDao<User, Long> {
public static final String TABLENAME = "USER";
/**
* Properties of entity User.<br/>
* Can be used for QueryBuilder and for referencing column names.
*/
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property Name = new Property(1, String.class, "name", false, "NAME");
}
public UserDao(DaoConfig config) {
super(config);
}
public UserDao(DaoConfig config, DaoSession daoSession) {
super(config, daoSession);
}
/** Creates the underlying database table. */
public static void createTable(Database db, boolean ifNotExists) {
String constraint = ifNotExists? "IF NOT EXISTS ": "";
db.execSQL("CREATE TABLE " + constraint + "\"USER\" (" + //
"\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
"\"NAME\" TEXT);"); // 1: name
}
/** Drops the underlying database table. */
public static void dropTable(Database db, boolean ifExists) {
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"USER\"";
db.execSQL(sql);
}
@Override
protected final void bindValues(DatabaseStatement stmt, User entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
String name = entity.getName();
if (name != null) {
stmt.bindString(2, name);
}
}
@Override
protected final void bindValues(SQLiteStatement stmt, User entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
String name = entity.getName();
if (name != null) {
stmt.bindString(2, name);
}
}
@Override
public Long readKey(Cursor cursor, int offset) {
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
@Override
public User readEntity(Cursor cursor, int offset) {
User entity = new User( //
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // name
);
return entity;
}
@Override
public void readEntity(Cursor cursor, User entity, int offset) {
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
entity.setName(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));
}
@Override
protected final Long updateKeyAfterInsert(User entity, long rowId) {
entity.setId(rowId);
return rowId;
}
@Override
public Long getKey(User entity) {
if(entity != null) {
return entity.getId();
} else {
return null;
}
}
@Override
public boolean hasKey(User entity) {
return entity.getId() != null;
}
@Override
protected final boolean isEntityUpdateable() {
return true;
}
}
end