精华内容
下载资源
问答
  • 第一步 先装数据库要用到的对象创建出来 package com.example.myapplication; public class Person { private String name; private int age; public String getName() { return name; } public void...
    第一步 先装数据库要用到的对象创建出来
    
    package com.example.myapplication;
    
    public class Person {
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
    
    
        //创建构造函数
        public Person() {
    
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

     

     

    //第二步 创建数据库  以及表明。

    package com.example.myapplication;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    
    public class OpenHelper extends SQLiteOpenHelper {
        public OpenHelper(Context context) {
            //这三个参数分别为上下文对象,数据库名称,游标,版本号
            super(context, "xjj.db", null, 1);
    
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("create table person(name varchar(50),age integer)");
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // 注:生产环境上不能做删除操作
            db.execSQL("DROP TABLE IF EXISTS person");
            onCreate(db);
        }
    }
    

     

     

    第三部增删改查的方法 

    package com.example.myapplication;
    
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    
    public class PersonDao {
    
    
        private OpenHelper helper = null;
    
        public PersonDao(Context context) {
            helper = new OpenHelper(context);
        }
    
        //实现对该数据库的增加
        public void addPerson(Person person) {
            //获取操作实例
            SQLiteDatabase db = helper.getWritableDatabase();
            //此方法推荐使用
            String sqlStr = "insert into person(name,age)values(?,?)";
            //执行SQL语句
            db.execSQL(sqlStr, new Object[]{person.getName(), person.getAge()});
            //关闭数据库
            db.close();
        }
    
    
        //实现对数据库的删除
        public void deletePerson(String name) {
            //获取数据库操作的实例
            SQLiteDatabase db = helper.getWritableDatabase();
            //创建SQL字符串
            String sqlStr = "delete from person where name=?";
            db.execSQL(sqlStr, new String[]{name});
            //关闭数据库
            db.close();
        }
    
        //实现对数据库的修改
        public void updatePerson(Person person) {
            //获取数据库的操作实例
            SQLiteDatabase db = helper.getWritableDatabase();
            //创建SQl字符串
            String sqlStr = "update person set name=? where age=?";
            //执行SQL语句
            db.execSQL(sqlStr, new Object[]{person.getName(), person.getAge()});
            //关闭数据库
            db.close();
        }
    
    
        //实现对数据库的查询
        public List<Person> selectPerson() {
            //创建集合
            List<Person> persons = new ArrayList<Person>();
            //获取数据库操作实例
            SQLiteDatabase db = helper.getReadableDatabase();
            //创建Cursor对象
            Cursor cursor = null;
            try {
                cursor = db.rawQuery("select * from person", null);
                while (cursor.moveToNext()) {
                    String name = cursor.getString(cursor.getColumnIndex("name"));
                    int age = cursor.getInt(cursor.getColumnIndex("age"));
                    //创建Person对象
                    Person p = new Person(name, age);
                    //将创建出来的Person对象添加到集合中去
                    persons.add(p);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭相应的资源
                if (cursor != null) {
                    cursor.close();
                }
                if (db != null) {
                    db.close();
                }
            }
            return persons;
        }
    
    }
    

     

     

    最后的调用 

    package com.example.myapplication;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        private PersonDao dao;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            dao = new PersonDao(this);
    
        }
    
        public void Remove(View view) {
            dao.deletePerson("张三0");
        }
    
    
        public void Add(View view) {
            for (int i = 0; i < 10; i++) {
                Person person = new Person("张三" + i, 10 + i);
                List<Person> people = dao.selectPerson();
                for (int j = 0; j < people.size(); j++) {
                    if (people.get(j).getName().equals(person.getName()) && people.get(j).getAge() == person.getAge()) {
                        dao.deletePerson(people.get(j).getName());
                    }
                }
                dao.addPerson(person);
            }
        }
    
        public void Seleted(View view) {
            List<Person> people = dao.selectPerson();
            if (people != null && people.size() > 0) {
                for (int i = 0; i < people.size(); i++) {
                    Log.i("-----------", "Seleted: " + people.get(i));
                }
            }
        }
    
        public void Update(View view) {
            Person p=new Person("刘丹", 11);
            dao.updatePerson(p);
        }
    }
    
    展开全文
  • ContentValues类和Hashtable比较类似,它也是负责存储一些名值对,但是它存储的名值对当中的名是一个String类型,而值都是基本类型。 我们回顾一下,在上一个例子当中,我们是通过SQL语句进行插入操作,SQL语句的...
    ContentValues类和Hashtable比较类似,它也是负责存储一些名值对,但是它存储的名值对当中的名是一个String类型,而值都是基本类型。
    我们回顾一下,在上一个例子当中,我们是通过SQL语句进行插入操作,SQL语句的好处是比较直观,但是容易出错。但是在这个例子当中我们有更好的办法,在这里我们将要插入的值都放到一个ContentValues的实例当中
    ContentValues initialValues = new ContentValues()语句实例化一个contentValues类。
    initialValues.put(KEY_TITLE, title)语句将列名和对应的列值放置到initialValues里边。
    mDb.insert(DATABASE_TABLE, null, initialValues)语句负责插入一条新的纪录,如果插入成功则会返回这条记录的id,如果插入失败会返回-1。
    展开全文
  • 安卓原生db操作进行封装,方便数据库的增删改查操作。使用简单方便。
  • 安卓ORMLite数据库框架

    2016-12-08 17:08:55
    以前使用过安卓自带的sqlite数据库,但是是使用原生的方法实现的,最近接触到的项目是使用ORMLite框架实现的,感觉很好用,能够提高开发效率,而事实上,ormlite框架对数据的增删改查也是要优于原生的。 一、Gradle:...

    以前使用过安卓自带的sqlite数据库,但是是使用原生的方法实现的,最近接触到的项目是使用ORMLite框架实现的,感觉很好用,能够提高开发效率,而事实上,ormlite框架对数据的增删改查也是要优于原生的。

    一、Gradle: compile 'com.j256.ormlite:ormlite-android:4.48'

    二、创建DataBase

    创建名为info.db的数据库 ,我这里只有一张表 基于StudentModel。

    public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
    
        public static final int version = 1;
    
        private static DatabaseHelper instance;
    
        private DatabaseHelper(Context context) {
            super(context, "info.db", null, version);
        }
    
        public static DatabaseHelper getInstance(Context context) {
            if (instance == null) {
                synchronized (DatabaseHelper.class) {
                    if (instance == null) {
                        instance = new DatabaseHelper(context);
                    }
                }
            }
            return instance;
        }
    
        public static void release() {
            synchronized (DatabaseHelper.class) {
                instance = null;
            }
        }
    
        @Override
        public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
            try {
                TableUtils.createTable(connectionSource, StudentModel.class);
            } catch (SQLException e) {
            }
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    
        }
    }

    需要使用Dao层对数据库进行操作,下面是一个封装的Dao方法:
    public class DaoProvider {
        private Map<Class,BaseDao> mDaoMap;
        private static DaoProvider ourInstance = new DaoProvider();
    
        public static DaoProvider getInstance() {
            return ourInstance;
        }
    
        private DaoProvider() {
            mDaoMap = new HashMap<>();
        }
    
        public void clear() {
            DatabaseHelper.release();
            mDaoMap.clear();
        }
    
        public synchronized <T extends BaseDao> T getDao(Class<T> clazz) {
            if (!mDaoMap.containsKey(clazz)) {
                try {
                    T dao = clazz.newInstance();
                    mDaoMap.put(clazz, dao);
                } catch (Exception e) {
                    throw new IllegalStateException("创建dao失败:" + clazz);
                }
            }
            return (T) mDaoMap.get(clazz);
        }
    
    }
    

    三、数据模型(数据表)

    新建一个StudentModel.class 

    StudentModel类上添加@DatabaseTable(tableName = "student"),标明这是数据库中的一张表。对应的这张表中的每一个字段,需要添加@DatabaseField注解,例如@DatabaseField(columnName = "name"),columnName 标明了字段名,即字段在数据中的列名。

    @DatabaseTable (tableName = "student")
    public class StudentModel extends BaseModel {
        @DatabaseField (columnName = "name",useGetSet = true)
        private String name;
        @DatabaseField (columnName = "age" ,useGetSet = true)
        private int age;
    
        @DatabaseField(columnName = "tel",useGetSet = true)
        private String rel;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getRel() {
            return rel;
        }
    
        public void setRel(String rel) {
            this.rel = rel;
        }
    }

    这里StudentModel继承了BaseModel,因为我们擦欧洲哦数据库一般有多张表,共同的字段比如create_time、update_time等搞一个父类方便管理。

    public class BaseModel implements Serializable {
    
        public static final String ID = "id";
        public static final String CREATE_TIME = "create_time";
        public static final String UPDATE_TIME = "update_time";
        public static final String DELETED = "deleted";
    
        @DatabaseField(id = true, useGetSet = true,columnName = ID)
        private String id;
    
        @DatabaseField(format = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", columnName = CREATE_TIME, useGetSet = true)
        private Date createTime;
    
        @DatabaseField(format = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", columnName = UPDATE_TIME, useGetSet = true)
        private Date updateTime;
    
        @DatabaseField(columnName = DELETED,useGetSet = true)
        private int deleted;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public Date getCreateTime() {
            return copyDate(createTime);
        }
    
        public void setCreateTime(Date createTime) {
            this.createTime = copyDate(createTime);
        }
    
        public Date getUpdateTime() {
            return copyDate(updateTime);
        }
    
        public void setUpdateTime(Date updateTime) {
            this.updateTime = copyDate(updateTime);
        }
    
        public int getDeleted() {
            return deleted;
        }
    
        public void setDeleted(int deleted) {
            this.deleted = deleted;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            BaseModel baseModel = (BaseModel) o;
    
            return id != null ? id.equals(baseModel.id) : baseModel.id == null;
    
        }
    
        @Override
        public int hashCode() {
            return id != null ? id.hashCode() : 0;
        }
    
        public  Date copyDate(Date date) {
            return date == null ? null : new Date(date.getTime());
        }
    }

    四、Model的Dao

    对应StudentModel的StudentDao,我这里只实现了查询方法,比如insert等方法在BaseDao中实现

    public class StudentDao extends BaseDao<StudentModel>{
        public StudentDao() throws SQLException {
            super();
        }
    
        public List<StudentModel> queryAll( ) {
            try {
                return getDao().queryBuilder().query();
            } catch (SQLException e) {
            }
            return null;
        }
    
    }
    
    BaseDao:为了方便使用,通过上下文的工具类AppContextUtils.getContext()来获得context

    public class BaseDao<T extends BaseModel> {
        protected DatabaseHelper mHelper;
        protected Dao<T, String> mDao;
    
        public BaseDao() throws SQLException {
            try {
                mHelper = DatabaseHelper.getInstance(AppContextUtils.getContext());
                mDao = mHelper.getDao(getTClass());
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    
        public SQLiteDatabase getDb() {
            return mHelper.getWritableDatabase();
        }
    
        public FieldType[] getStableTableColumn() {
            TableInfo tableInfo = null;
            FieldType[] fieldTypes = null;
            try {
                tableInfo = new TableInfo(getDao().getConnectionSource(), (BaseDaoImpl)getDao(), getTClass());
                fieldTypes = tableInfo.getFieldTypes();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return fieldTypes;
        }
    
        public boolean addColumn(String tableName, String columnName, String columnSpec) {
            mHelper.getWritableDatabase().execSQL(String.format("ALTER TABLE %s ADD %s %s", tableName, columnName, columnSpec));
            return true;
        }
    
        public String[] getColumns(String tableName) {
            Cursor cursor = mHelper.getWritableDatabase().rawQuery(String.format("select * from %s where id=1", tableName), null);
            String[] columnNames = cursor.getColumnNames();
            return columnNames;
        }
    
        public Dao<T, String> getDao() {
            return mDao;
        }
    
        public boolean isExist(T model) throws SQLException {
            if (model == null || model.getId() == null) {
                return false;
            } else {
                return mDao.queryForId(model.getId()) != null;
            }
        }
    
        public int add(T model) throws SQLException {
            if (model.getId() == null) {
                model.setId(UUID.randomUUID().toString());
            }
            if (model.getCreateTime() == null) {
                model.setCreateTime(new Date());
            }
            if (model.getUpdateTime() == null) {
                model.setUpdateTime(new Date());
            }
    
            return mDao.create(model);
        }
    
        public synchronized Dao.CreateOrUpdateStatus addOrUpdate(T model) throws SQLException {
            if (isExist(model)) {
                return new Dao.CreateOrUpdateStatus(false, true, update(model));
            } else {
                return new Dao.CreateOrUpdateStatus(true, false, add(model));
            }
        }
    
        public int delete(T model) throws SQLException {
            return mDao.delete(model);
        }
    
        public int deleteById(String id) throws SQLException {
            return mDao.deleteById(id);
        }
    
        public int update(T model) throws SQLException {
            model.setUpdateTime(new Date());
            return mDao.update(model);
        }
    
        public long querySize() throws SQLException {
            return mDao.countOf();
        }
    
        public T query(String id) throws SQLException {
            return mDao.queryForId(id);
        }
    
        public List<T> queryAll() throws SQLException {
            return mDao.queryForAll();
        }
    
        protected Class<T> getTClass() {
            return  (Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
    }


    AppContextUtils:需要在使用前调用init方法

    public class AppContextUtils {
        private static Context sAppContext;
        private static long millTime = 0L;
    
        private AppContextUtils() {
        }
    
        public static void init(Context ctx) {
            sAppContext = ctx.getApplicationContext();
        }
    
        public static Context getContext() {
            return sAppContext;
        }
    
        public static Context getContext(Context context) {
            return context != null?context:sAppContext;
        }
    
        public static long getMafInitMilTime() {
            return millTime;
        }
    
        public static void setMafInitMilTime(long setMillTime) {
            millTime = setMillTime;
        }
    }
    

    五、数据操作

    铺垫了这么多,都是为了方便数据库扩展,接下来的方法就是对数据库进行操作

    public class DatabaseService {
    
        private StudentDao studentDao;
        private static DatabaseService sInstance;
    
        private DatabaseService(){
            studentDao = DaoProvider.getInstance().getDao(StudentDao.class);
        }
    
        public static synchronized DatabaseService getInstance() {
            if (sInstance == null) {
                    sInstance = new DatabaseService();
            }
            return sInstance;
        }
    
        public void reSet(){
            studentDao = null;
            sInstance = null;
        }
    
        public boolean insertOrUpdateMeeting(StudentModel meetingModel) {
            try {
                Dao.CreateOrUpdateStatus createOrUpdateStatus = studentDao.addOrUpdate(meetingModel);
                return createOrUpdateStatus.getNumLinesChanged() == 1;
            } catch (SQLException e) {
            }
            return false;
        }
    
        public List<StudentModel> search() {
                return  studentDao.queryAll();
        }
    }
    

    在MainActivity调用
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
        private Button mBtnAdd;
        private Button mBtnSearch;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mBtnAdd = (Button)findViewById(R.id.button);
            mBtnAdd.setOnClickListener(this);
            mBtnSearch = (Button)findViewById(R.id.button2);
            mBtnSearch.setOnClickListener(this);
            AppContextUtils.init(MainActivity.this);
        }
    
        @Override
        public void onClick(View view) {
            if (view==mBtnAdd){
                StudentModel studentModel  = new StudentModel();
                studentModel.setName("swd");
                DatabaseService.getInstance().insertOrUpdateMeeting(studentModel);
                return;
            }
            if (view == mBtnSearch){
                List<StudentModel> studentModels = new ArrayList<StudentModel>();
                studentModels = DatabaseService.getInstance().search();
                studentModels.clear();
            }
        }
    }
    

    关于数据库更新

    关于Android数据库升级的实践(以ormlite为例)点击打开链接

    展开全文
  • 原生数据库 public class MySQLiteHelper extends SQLiteOpenHelper { private static final String TAG = MySQLiteHelper; //数据库建表语句 public static final String sql = sql语句; public static final ...
  • 我也不清楚为啥需要5个币 本地的数据库的增删改查,原生数据库,后面也会上传一些三方数据库的使用,例如litepal GreenDao 等
  • 原生: Android :SQLlite数据库 使用手册:https://www.jianshu.com/p/8e3f294e2828 第三方常用ORM的框架: GreenDao:SQLite 的orm框架 Reaml-java:基于Reaml轻量级数据库,跨平台iOS,Android...

    原生:

    Android :SQLlite数据库 使用手册:https://www.jianshu.com/p/8e3f294e2828



    第三方常用ORM的框架:

    GreenDao:SQLite 的orm框架
    Reaml-java:基于Reaml轻量级数据库,跨平台iOS,Android等
    展开全文
  • 通过报名功能的制作实现安卓端数据保存到数据库,使用SharedPreferences实现窗体之间的数据共享,最后讲解了安卓APP的签名和发布及安卓图标的定制。【老师花了大量的时间和精力去准备和录制本套教程,希望同学们在...
  • 安卓原生数据库SQLite的小白级使用方法。自己刚开始学的时候踩过的坑,给大家标出来,供大家参考,也算是记录我的学习过程,我将以用户注册验证登录信息为例。 刚开始学的时候,数据库的查询方法在网上看了很多,...
  • 1.数据库的管理类package com.biyu6.creatdb;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class MyOpenHelper extends...
  • 使用原生sql操作数据库 新增数据:db.execSQL("insert into Book (name, author, pages, prices) values (?,?,?,?)", new String[] {"love", "guanjia", "520", "25.5"}); 更新数据:db.execSQL("update Book set ...
  • html5使用原生数据库有时候不大方便,所以有时会有使用安卓原生数据库的需求,这个是详细的实现,附带说明文档
  • 安卓中的数据库操作

    2017-05-08 11:23:00
    1.原生操作 Android 中封装好的方法-------SQLliteOpenHelper 面向对象的操作 sql语句的操作 2.三方操作 ORM是指对象关系映射(Object Relation Mapping),是一种程序设计技术,(greenDao和ormLite都是...
  • 安卓原生提供了操作数据库的API接口,但是操作较为繁杂,于是涌现了大量第三方的开源操作库,如GreenDAO、Realm等.但Google最新推出Jetpack全家桶,自带Room数据库操作库,使用上方便快捷,同时可以和Jetpack中的其
  • 关注 安卓007 ,免费获取全套安卓开发学习资料什么是SQLite数据库SQLite数据库是适合在移动...安卓原生提供了操作数据库的API接口,但是操作较为繁杂,于是涌现了大量第三方的开源操作库,如GreenDAO、Realm等.但Goog...
  • 我正在开发一个非常简单的原生Android应用程序,其中包含一个简单的主菜单,包括今天,昨天,本周,本月和按日期搜索选项.(我买了lynda课程:“使用Dreamweaver构建Android和iOS应用程序”,HTML5以及应用程序的设计和功能...
  • LitePal是一个Android开源原生库,它使开发者使用SQLite数据库变得非常容易。 你可以不用写一句SQL语句就可以完成大部分数据库操作,包括创建表,更新表,约束操作,聚合功能等等。LitePal的安装也相当简单,3分钟之...
  • 输入用户名和密码,后台是到数据库校验是否通过,然后再把用户信息放置在session中,然后返回给客户端, 事实上返回response的header信息里面有一个set-cookie属性,这个就是下次访问时浏览器要把这个放置在请求头中...
  • 安卓里面数据库怎么用呢,简单来说可用分为以下三步: 1、新建一个数据库帮助类,继承自SQLiteOpenHelper,复写onCreate() 和 onUpgrade() 2、新建一个数据里操作类(dao类),利用 数据库帮助类 得到数据库的...
  • 平常进行Android数据库开发时,都是使用原生的API,即SQLiteDatabase。但,使用系统的API开发时,尤其是SQL语句的书写时经常出现一些问题,因此便出现了许多针对数据库开发的开源框架,例:LiteOrm、GreenDao、Realm...
  • Android3数据库

    2021-05-06 19:39:17
    今天先积累一下安卓数据库操作中比较简单的LitePal,有时间了在把比较复杂的原生安卓数据库语句总结出来 LitePal简介+配置选项 Litepal简介 LitePal:这是一个开源库,它做的就是采用了对象关系映射(ORM)模式,...
  • 2020.11.24 更新1 背景开发一个App与后台数据库交互,基于MySQL+原生JDBC+Tomcat,没有使用DBUtils或JDBC框架,纯粹底层JDBC实现。这几天踩了很多坑,说得夸张点真是踩到没有知觉,希望能帮助读者少踩坑...2 开发...
  • GreenDao官网:学习方法3步骤:第一找原生文档,第二看视频,第三看博客。 ORM百度百科:对象关系映射...GreenDao:安卓针对你SQLite数据库的关系对象映射。 提示:对于新的应用,我们推荐ObjectBox,一个新的比SQL...
  • 我们都知道,Android系统...在Android中,我们既可以使用原生的SQL语句来对数据进行操作,也可以使用Android API提供的CRUD方法来对数据库进行操作,两种方式各有特点,选择使用哪一种就全凭个人喜好了。不过,使用...
  • 还没有看过前面一篇文章的朋友建议先去参考logo.png传统的查询数据方式最传统的查询数据的方式当然是使用SQL语句了,Android当中也提供了直接使用原生SQL语句来查询数据库表的方法,即SQLiteD...
  • 接下来就讲一下怎么搭建影视软件:必备条件:服务器或虚拟主机+域名服务器或虚拟主机+域名:这个相当于我们的仓库,用来存放源码文件和数据库;(如果不知道怎么注册使用的,建议先百度了解)后台搭建环境:...
  • 在Flutter中的数据库叫Sqflite跟原生安卓的Sqlite叫法不一样。我们来看下Sqflite官方对它的解释说明: SQLite plugin for Flutter. Supports both iOS and Android. Support transactions and b...
  • 安卓原生的数据存储方式主要有三个: 1是文件存储;2是SharedPreferences存储,在安卓软件分析中经常会看到里面明文存储着用户名与密码;3是SQLite数据库存储 分别存储的位置在/data/data/包名/File、/data/data/包...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 129
精华内容 51
关键字:

安卓原生数据库