android基础总结篇之八:创建及调用自己的ContentProvider

今天我们来讲解一下如何创建及调用自己的ContentProvider。

在前面两篇文章中我们分别讲了如何读写联系人和短消息,相信大家对于ContentProvider的操作方法已经有了一定程度的了解。在有些场合,除了操作ContentProvider之外,我们还有可能需要创建自己的ContentProvider,来提供信息共享的服务,这就要求我们很好的掌握ContentProvider的创建及使用技巧。下面我们就由表及里的逐步讲解每个步骤。

在正式开始实例演示之前,我们先来了解以下两个知识点:

授权:

在Android中,每一个ContentProvider都会用类似于域名的字符串来注册自己,我们成为授权(authority)。这个唯一标识的字符串是此ContentProvider可提供的一组URI的基础,有了这个基础,才能够向外界提供信息的共享服务。

授权是在AndroidManifest.xml中完成的,每一个ContentProvider必须在此声明并授权,方式如下:

<provider android:name=".SomeProvider"
  android:authorities="com.your-company.SomeProvider"/> 

上面的<provider>元素指明了ContentProvider的提供者是“SomeProvider”这个类,并为其授权,授权的基础URI为“com.your-company.SomeProvider”。有了这个授权信息,系统可以准确的定位到具体的ContentProvider,从而使访问者能够获取到指定的信息。这和浏览Web页面的方式很相似,“SomeProvider”就像一台具体的服务器,而“com.your-company.SomeProvider”就像注册的域名,相信大家对这个概念并不陌生,由此联想一下就可以了解ContentProvider授权的作用了。(需要注意的是,除了Android内置应用程序之外,第三方程序应尽量使用以上方式的完全限定的授权名。)

MIME类型:

就像网站返回给定URL的MIME(Multipurpose Internet Mail Extensions,多用途Internet邮件扩展)类型一样(这使浏览器能够用正确的程序来查看内容),ContentProvider还负责返回给定URI的MIME类型。根据MIME类型规范,MIME类型包含两部分:类型和子类型。例如:text/html,text/css,text/xml等等。

Android也遵循类似的约定来定义MIME类型。

对于单条记录,MIME类型类似于:

vnd.android.cursor.item/vnd.your-company.content-type

而对于记录的集合,MIME类型类似于:

vnd.android.cursor.dir/vnd.your-company.comtent-type

其中的vnd表示这些类型和子类型具有非标准的、供应商特定的形式;content-type可以根据ContentProvider的功能来定,比如日记的ContentProvider可以为note,日程安排的ContentProvider可以为schedule,等等。

了解了以上两个知识点之后,我们就结合实例来演示一下具体的过程。

我们将会创建一个记录person信息的ContentProvider,实现对person的CRUD操作,访问者可以通过下面路径操作我们的ContentProvider:

访问者可以通过“[BASE_URI]/persons”来操作person集合,也可以通过“[BASE_URI]/persons/#”的形式操作单个person。
我们创建一个person的ContentProvider需要两个步骤:

1.创建PersonProvider类:

我们需要继承ContentProvider类,实现onCreate、query、insert、update、delete和getType这几个方法。具体代码如下:

package com.scott.provider; 

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; 

public class PersonProvider extends ContentProvider { 

  private static final UriMatcher matcher;
  private DBHelper helper;
  private SQLiteDatabase db; 

  private static final String AUTHORITY = "com.scott.provider.PersonProvider";
  private static final int PERSON_ALL = 0;
  private static final int PERSON_ONE = 1; 

  public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.scott.person";
  public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.scott.person"; 

  //数据改变后立即重新查询
  private static final Uri NOTIFY_URI = Uri.parse("content://" + AUTHORITY + "/persons"); 

  static {
    matcher = new UriMatcher(UriMatcher.NO_MATCH); 

    matcher.addURI(AUTHORITY, "persons", PERSON_ALL);  //匹配记录集合
    matcher.addURI(AUTHORITY, "persons/#", PERSON_ONE); //匹配单条记录
  } 

  @Override
  public boolean onCreate() {
    helper = new DBHelper(getContext());
    return true;
  } 

  @Override
  public String getType(Uri uri) {
    int match = matcher.match(uri);
    switch (match) {
    case PERSON_ALL:
      return CONTENT_TYPE;
    case PERSON_ONE:
      return CONTENT_ITEM_TYPE;
    default:
      throw new IllegalArgumentException("Unknown URI: " + uri);
    }
  } 

  @Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    db = helper.getReadableDatabase();
    int match = matcher.match(uri);
    switch (match) {
    case PERSON_ALL:
      //doesn't need any code in my provider.
      break;
    case PERSON_ONE:
      long _id = ContentUris.parseId(uri);
      selection = "_id = ?";
      selectionArgs = new String[]{String.valueOf(_id)};
      break;
    default:
      throw new IllegalArgumentException("Unknown URI: " + uri);
    }
    return db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
  } 

  @Override
  public Uri insert(Uri uri, ContentValues values) {
    int match = matcher.match(uri);
    if (match != PERSON_ALL) {
      throw new IllegalArgumentException("Wrong URI: " + uri);
    }
    db = helper.getWritableDatabase();
    if (values == null) {
      values = new ContentValues();
      values.put("name", "no name");
      values.put("age", "1");
      values.put("info", "no info.");
    }
    long rowId = db.insert("person", null, values);
    if (rowId > 0) {
      notifyDataChanged();
      return ContentUris.withAppendedId(uri, rowId);
    }
    return null;
  } 

  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    db = helper.getWritableDatabase();
    int match = matcher.match(uri);
    switch (match) {
    case PERSON_ALL:
      //doesn't need any code in my provider.
      break;
    case PERSON_ONE:
      long _id = ContentUris.parseId(uri);
      selection = "_id = ?";
      selectionArgs = new String[]{String.valueOf(_id)};
    }
    int count = db.delete("person", selection, selectionArgs);
    if (count > 0) {
      notifyDataChanged();
    }
    return count;
  } 

  @Override
  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    db = helper.getWritableDatabase();
    int match = matcher.match(uri);
    switch (match) {
    case PERSON_ALL:
      //doesn't need any code in my provider.
      break;
    case PERSON_ONE:
      long _id = ContentUris.parseId(uri);
      selection = "_id = ?";
      selectionArgs = new String[]{String.valueOf(_id)};
      break;
    default:
      throw new IllegalArgumentException("Unknown URI: " + uri);
    }
    int count = db.update("person", values, selection, selectionArgs);
    if (count > 0) {
      notifyDataChanged();
    }
    return count;
  } 

  //通知指定URI数据已改变
  private void notifyDataChanged() {
    getContext().getContentResolver().notifyChange(NOTIFY_URI, null);
  }
}

在PersonProvider中,我们定义了授权地址为“com.scott.provider.PersonProvider”,相信大家在前面也有所了解了。基于这个授权,我们使用了一个UriMatcher对其路径进行匹配,“[BASE_URI]/persons"和“[BASE_URI]/persons/#”这两种路径我们在上面也介绍过,分别对应记录集合和单个记录的操作。在query、insert、update和delete方法中我们根据UriMatcher匹配结果来判断该URI是操作记录集合还是单条记录,从而采取不同的处理方法。在getType方法中,我们会根据匹配的结果返回不同的MIME类型,这一步是不能缺少的,比如我们在query方法中有可能是查询全部集合,有可能是查询单条记录,那么我们返回的Cursor或是集合类型,或是单条记录,这个跟getType返回的MIME类型是一致的,就好像浏览网页一样,指定的url返回的信息是什么类型,那么浏览器就应该接收到对应的MIME类型。另外,我们注意到,上面代码中,在insert、update、delete方法中都调用了notifyDataChanged方法,这个方法中仅有的一步操作就是通知“[BASE_URI]/persons"的访问者,数据发生改变了,应该重新加载了。

在我们的PersonProvider中,我们用到了Person、DBHelper类,代码如下:

package com.scott.provider; 

public class Person {
  public int _id;
  public String name;
  public int age;
  public String info; 

  public Person() {
  } 

  public Person(String name, int age, String info) {
    this.name = name;
    this.age = age;
    this.info = info;
  }
}
[java] view plain copy
package com.scott.provider; 

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; 

public class DBHelper extends SQLiteOpenHelper { 

  private static final String DATABASE_NAME = "provider.db";
  private static final int DATABASE_VERSION = 1; 

  public DBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  } 

  @Override
  public void onCreate(SQLiteDatabase db) {
    String sql = "CREATE TABLE IF NOT EXISTS person" +
        "(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, info TEXT)";
    db.execSQL(sql);
  } 

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS person");
    onCreate(db);
  }
}

最后,要想让这个ContentProvider生效,我们需要在AndroidManifest.xml中声明并为其授权,如下所示:

<provider android:name=".PersonProvider"
  android:authorities="com.scott.provider.PersonProvider"
  android:multiprocess="true"/> 

其中,android:multiprocess代表是否允许多进程操作。另外我们也可以为其声明相应的权限,对应的属性是:android:permission。

2.调用PersonProvider类:

完成了person的ContentProvider后,下面我们来看一下如何访问它。这一步我们在MainActivity中完成,看下面代码:

package com.scott.provider; 

import java.util.ArrayList; 

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter; 

public class MainActivity extends Activity { 

  private ContentResolver resolver;
  private ListView listView; 

  private static final String AUTHORITY = "com.scott.provider.PersonProvider";
  private static final Uri PERSON_ALL_URI = Uri.parse("content://" + AUTHORITY + "/persons"); 

  private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
      //update records.
      requery();
    };
  }; 

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 

    resolver = getContentResolver();
    listView = (ListView) findViewById(R.id.listView); 

    //为PERSON_ALL_URI注册变化通知
    getContentResolver().registerContentObserver(PERSON_ALL_URI, true, new PersonObserver(handler));
  } 

  /**
   * 初始化
   * @param view
   */
  public void init(View view) {
    ArrayList<Person> persons = new ArrayList<Person>(); 

    Person person1 = new Person("Ella", 22, "lively girl");
    Person person2 = new Person("Jenny", 22, "beautiful girl");
    Person person3 = new Person("Jessica", 23, "sexy girl");
    Person person4 = new Person("Kelly", 23, "hot baby");
    Person person5 = new Person("Jane", 25, "pretty woman"); 

    persons.add(person1);
    persons.add(person2);
    persons.add(person3);
    persons.add(person4);
    persons.add(person5); 

    for (Person person : persons) {
      ContentValues values = new ContentValues();
      values.put("name", person.name);
      values.put("age", person.age);
      values.put("info", person.info);
      resolver.insert(PERSON_ALL_URI, values);
    }
  } 

  /**
   * 查询所有记录
   * @param view
   */
  public void query(View view) {
//   Uri personOneUri = ContentUris.withAppendedId(PERSON_ALL_URI, 1);查询_id为1的记录
    Cursor c = resolver.query(PERSON_ALL_URI, null, null, null, null); 

    CursorWrapper cursorWrapper = new CursorWrapper(c) { 

      @Override
      public String getString(int columnIndex) {
        //将简介前加上年龄
        if (getColumnName(columnIndex).equals("info")) {
          int age = getInt(getColumnIndex("age"));
          return age + " years old, " + super.getString(columnIndex);
        }
        return super.getString(columnIndex);
      }
    }; 

    //Cursor须含有"_id"字段
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,
        cursorWrapper, new String[]{"name", "info"}, new int[]{android.R.id.text1, android.R.id.text2});
    listView.setAdapter(adapter); 

    startManagingCursor(cursorWrapper); //管理Cursor
  } 

  /**
   * 插入一条记录
   * @param view
   */
  public void insert(View view) {
    Person person = new Person("Alina", 26, "attractive lady");
    ContentValues values = new ContentValues();
    values.put("name", person.name);
    values.put("age", person.age);
    values.put("info", person.info);
    resolver.insert(PERSON_ALL_URI, values);
  } 

  /**
   * 更新一条记录
   * @param view
   */
  public void update(View view) {
    Person person = new Person();
    person.name = "Jane";
    person.age = 30;
    //将指定name的记录age字段更新为30
    ContentValues values = new ContentValues();
    values.put("age", person.age);
    resolver.update(PERSON_ALL_URI, values, "name = ?", new String[]{person.name}); 

    //将_id为1的age更新为30
//   Uri updateUri = ContentUris.withAppendedId(PERSON_ALL_URI, 1);
//   resolver.update(updateUri, values, null, null);
  } 

  /**
   * 删除一条记录
   * @param view
   */
  public void delete(View view) {
    //删除_id为1的记录
    Uri delUri = ContentUris.withAppendedId(PERSON_ALL_URI, 1);
    resolver.delete(delUri, null, null); 

    //删除所有记录
//   resolver.delete(PERSON_ALL_URI, null, null);
  } 

  /**
   * 重新查询
   */
  private void requery() {
    //实际操作中可以查询集合信息后Adapter.notifyDataSetChanged();
    query(null);
  }
}

我们看到,在上面的代码中,分别对应每一种情况进行测试,相对较为简单。我们主要讲一下registerContentObserver这一环节。

在前面的PersonProvider我们也提到,在数据更改后,会向指定的URI访问者发出通知,以便于更新查询记录。大家注意,仅仅是ContentProvider出力还不够,我们还需要在访问者中注册一个ContentObserver,才能够接收到这个通知。下面我们创建一个

PersonObserver:
package com.scott.provider; 

import android.database.ContentObserver;
import android.os.Handler;
import android.os.Message;
import android.util.Log; 

public class PersonObserver extends ContentObserver { 

  public static final String TAG = "PersonObserver";
  private Handler handler; 

  public PersonObserver(Handler handler) {
    super(handler);
    this.handler = handler;
  } 

  @Override
  public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    Log.i(TAG, "data changed, try to requery.");
    //向handler发送消息,更新查询记录
    Message msg = new Message();
    handler.sendMessage(msg);
  }
}

这样一来,当ContentProvider发来通知之后,我们就能立即接收到,从而向handler发送一条消息,重新查询记录,使我们能够看到最新的记录信息。

最后,我们要在AndroidManifest.xml中为MainActivity添加MIME类型过滤器,告诉系统MainActivity可以处理的信息类型:

<!-- MIME类型 -->
<intent-filter>
  <data android:mimeType="vnd.android.cursor.dir/vnd.scott.person"/>
</intent-filter>
<intent-filter>
  <data android:mimeType="vnd.android.cursor.item/vnd.scott.person"/>
</intent-filter> 

这样就完成了访问者的代码,我们来看一下效果:

鉴于操作类型太多,我在这里就不再展示了,大家可以自己试一试。

原文链接:http://blog.csdn.net/liuhe688/article/details/7050868

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android ContentProvider实现获取手机联系人功能

    在之前项目中有用到关于获取手机联系人的部分,闲置就想和大家分享一下,话不多说,上代码: java部分: package com.example.content; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle

  • Android 中自定义ContentProvider与ContentObserver的使用简单实例

    Android 中自定义ContentProvider与ContentObserver的使用简单实例 示例说明: 该示例中一共包含两个工程.其中一个工程完成了自定义ContentProvider,另外一个工程用于测试该自定义ContentProvider且在该工程中使用了ContentObserver监听自定义ContentProvider的数据变化 以下代码为工程TestContentProvider ContentProviderTest如下: package cn.testcontentp

  • Android应用中使用ContentProvider扫描本地图片并显示

    之前群里面有朋友问我,有没有关于本地图片选择的Demo,类似微信的效果,他说网上没有这方面的Demo,问我能不能写一篇关于这个效果的Demo,于是我研究了下微信的本地图片选择的Demo,自己仿照的写了下分享给大家,希望对以后有这样子需求的朋友有一点帮助吧,主要使用的是ContentProvider扫描手机中的图片,并用GridView将图片显示出来,关于GridView和ListView显示图片的问题,一直是一个很头疼的问题,因为我们手机的内存有限,手机给每个应用程序分配的内存也有限,所以图片多

  • 实例讲解Android中ContentProvider组件的使用方法

    ContentProvider基本使用 为了在应用程序之间交换数据,android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过提供ContentPRovider来实现,其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据. 实现ContentProvider的步骤: 1)编写一个类,继承ContentProvid

  • Android 自定义ContentProvider简单实例

    Android 自定义ContentProvider简单实例 Android允许我们定义自己的的ContentProvider对象来共享数据,练练手,简单来实现一下. 要使用ContentProvider来操作数据,必须要有保存数据的场所.可以使用文件或SQLite数据库的方式来保存数据,通常使用SQLite数据库. 1,创建一个数据库帮助类,归根结底都是它在操作数据库.代码如下: package com.njue; import android.content.Context; import

  • Android ContentProvider获取手机联系人实例

    在做项目的时候,因为要用到我们自动获取联系人的姓名和电话,就想到了ContentProvider分享数据的功能,这样做既节省了时间,也减少了我们输入错误号码的几率,所以,想在这里把小demo分享给大家,方便以后要用的时候可以看看 我们先看下获取所有联系人的方式,把所有联系人展示在listView上 public void getLinkMan(View view){ //获取联系人 Uri uri=Uri.parse("content://com.android.contacts/raw_con

  • Android数据持久化之ContentProvider机制详解

    本文实例讲述了Android数据持久化之ContentProvider机制.分享给大家供大家参考,具体如下: 一般而言,android操作系统的应用程序所建立的数据只允许自己使用,应用程序彼此间无法借助公用存储器来共享数据,android系统提供了一个机制,即内容提供器(ContentProvider),来公开自己私有的数据到数据内容器,通过该机制,可以供其他应用程序来读取自己内部的数据,当然也可以访问其他应用程序的数据.通常,内容提供器背后都有SQLite数据库的支持,用以存储内容提供内部数据

  • Android 中ContentProvider的实例详解

    Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据.这也是跨应用 共享数据的唯一方式.在Android系统中,没有一个公共的内存区域,供多个应用共享存储数据: * Android 提供了一些主要数据类型的ContentProvider ,比如:音频.视频.图片和私人通讯录等: 在android.provider 包下面找到一些android提供的C

  • android基础总结篇之八:创建及调用自己的ContentProvider

    今天我们来讲解一下如何创建及调用自己的ContentProvider. 在前面两篇文章中我们分别讲了如何读写联系人和短消息,相信大家对于ContentProvider的操作方法已经有了一定程度的了解.在有些场合,除了操作ContentProvider之外,我们还有可能需要创建自己的ContentProvider,来提供信息共享的服务,这就要求我们很好的掌握ContentProvider的创建及使用技巧.下面我们就由表及里的逐步讲解每个步骤. 在正式开始实例演示之前,我们先来了解以下两个知识点:

  • Android基础总结篇之三:Activity的task相关介绍

    本篇文章主要介绍了android基础总结篇之三:Activity的task相关,具有一定的参考价值,有需要的可以了解一下. 今天我们来讲一下Activity的task相关内容. 上次我们讲到Activity的四种启动模式的时候,已经了解到一些关于task的技术,今天我再向大家介绍一下.task是一个具有栈结构的容器,可以放置多个Activity实例.启动一个应用,系统就会为之创建一个task,来放置根Activity:默认情况下,一个Activity启动另一个Activity时,两个Activi

  • android基础总结篇之二:Activity的四种launchMode

    我们今天要讲的是Activity的四种launchMode. launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里.这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task. Activity一共有以下四种launchMode: 1.standard 2.

  • android基础总结篇之一:Activity生命周期

    近来回顾了一下关于Activity的生命周期,参看了相关书籍和官方文档,也有了不小的收获,对于以前的认知有了很大程度上的改善,在这里和大家分享一下. 熟悉javaEE的朋友们都了解servlet技术,我们想要实现一个自己的servlet,需要继承相应的基类,重写它的方法,这些方法会在合适的时间被servlet容器调用.其实Android中的Activity运行机制跟servlet有些相似之处,Android系统相当于servlet容器,Activity相当于一个servlet,我们的Activi

  • android基础总结篇之九:Intent应用详解

    今天我们来讲一下Android中Intent的原理和应用. 前面我们总结了几个Android中重要组件,相信大家对于这些组件已经有了清晰的认识,我们就来看一下几个常见的操作: 启动一个Activity:Context.startActivity(Intent intent); 启动一个Service:Context.startService(Intent service); 绑定一个Service:Context.bindService(Intent service, ServiceConnec

  • Android基础之隐藏标题栏/设置为全屏/横竖屏切换

    目录 隐藏标题栏 设置为全屏 横竖屏切换 屏幕旋转方式 动态设置屏幕方向 设置横竖屏切换 总结 隐藏标题栏 基于xml <application android:theme="@style/Theme.AppCompat.Light.NoActionBar"> 动态隐藏 //继承自Activity时使用 requestWindowFeature(Window.FEATURE_NO_TITLE); //继承自AppCompatActivity时使用 getSupportAct

  • Android基础之常用控件属性介绍

    目录 常用控件之常用属性 控件可见性 TextView Button EditText ImageView ProgressBar AlertDialog ProgressDialog Toast Menu 常用控件之常用属性 控件可见性 android:visibility="visible/invisible/gone" visible表示控件可见(默认)/invisible表示控件不可见/gone表示控件不可见且不再占用任何屏幕空间 TextView android:layout

  • Android基础入门之dataBinding的简单使用教程

    目录 前言 1.前期准备 1.1打开dataBinding 1.2修改布局文件 1.3修改Activity方法 2.DataBinding的使用 2.1属性更新 2.2<data>标签 2.2.1简单数据的定义与绑定 2.2.2复杂数据的定义与绑定 2.3事件绑定 2.3.1点击事件绑定 2.3.2点击事件回传数据 2.3.3动态改变对象数据在控件上显示 2.3.4动态改变基本数据在控件上显示 2.4与输入控件结合 2.5与图片控件结合 总结 前言 dataBinding是实现 view 和

  • MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划

    一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存在system.indexes 中,且默认总是为_id创建索引,它的索引使用基本和MySQL 等关系型数据库一样.其实可以这样说说,索引是凌驾于数据存储系统之上的另一层系统,所以各种结构迥异的存储都有相同或相似的索引实现及使用接口并不足为 奇. 1.基础索引 在字段age 上创建索引,1(升序);-1(降序): db.users.ensureIndex({age:1}) _id 是创建表的时候自动创建的索引,此索引是不能够删除的.当

  • Java基础之Bean的创建、定位和使用

    一.前言 Bean是一个由Spring IoC容器实例化.组装和管理的对象.在 Spring 中,类的实例化.依赖的实例化.依赖的传入都交由 Spring Bean 容器控制,而不是用new方式实例化对象.通过非构造函数方法传入依赖等常规方式.这样可以减少垃圾回收对大量实例的回收工作. 在举例中使用到了三个类AAA,BBB和CCC.其中AAA和BBB是平等的两个类,可以相互调用.CCC是以BBB为构造参数的类. 二.自动装配Bean 2.1 注册Bean 为所有想要创建Bean的类添加@Comp

随机推荐