您的位置:首页 > 移动开发 > Android开发

Android聊天软件的开发(二)--数据库

2014-06-16 20:24 435 查看

一,服务器数据库

服务器端的数据库是MySQL,使用Hibernate实现数据的增删改查。主要存储的数据有:用户信息,好友列表。






其中,好友列表中的friend_list字段是好友ID的集合,格式为 "好友ID1&好友ID2&好友ID3&好友ID4"。

Hibernate使用:
1.导入相应的jar
一般需要hibernate.jar, antlr.jar, commons-collections.jar, commons-logging.jar, dom4j.jar, jta.jar, cglib.jar等,另外还需要数据库驱动类mysql-connector.jar。

这些jar可以在 http://www.hibernate.org 下载。

2.配置文件

在src目录下,添加一个hibernate.cfg.xml文件,用于配置数据URL,用户名,密码,数据库驱动等。也可以添加一个hibernate.properties文件作为配置文件,格式与一般配置文件一致。

hibernate.cfg.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-Hibernate/Hibernate Configuration DTD 3.0//EN//"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
	
	<hibernate-configuration>
		<session-factory>
			<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
			<property name="connection.url">jdbc:mysql:///talking</property>
			<property name="connection.username">root</property>
			<property name="connection.password">vaint</property>
			
			<!-- 这项设置可以在Hibernate每次连接数据库时,都将之前的数据清空。none为不清空 -->
			<property name="hbm2ddl.auto">none</property>
			
			<!-- 产生统计信息 -->
			<property name="generate_statistics">true</property>
			
			<!-- 输出每次执行的sql语句 -->
			<property name="show_sql">true</property>
			
			<!-- 方言,指明使用什么数据库 -->
			<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
			
			<!-- 映射文件 -->
			<mapping resource="vaint/wyt/db/User.hbm.xml"/>
			<mapping resource="vaint/wyt/db/Friends.hbm.xml"/>
			
			
			<!-- 事件监听 -->
			<event type="save">
				<listener class="org.hibernate.event.def.DefaultSaveOrUpdateEventListener"/>
			</event>
	
		</session-factory>
	</hibernate-configuration>


3.JavaBean类
有两个JavaBean类:User和Friends,分别对应user表(用户信息)和friends表(好友列表)。属性要与表中字段一一对应。

4.映射文件
在JavaBean所在目录下添加类名.hbm.xml,比如User.hbm.xml。然后在文件中将JavaBean属性和数据表字段映射起来。映射文件需要在配置文件中配置,如<mapping resource="vaint/wyt/db/User.hbm.xml"/>

User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-Hibernate/Hibernate Mapping DTD 3.0//EN//"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
	
	<hibernate-mapping package="vaint.wyt.db">
		<class name="User" table="user">
			<id name="userId" column="user_id">
				<generator class="assigned"/>
			</id>
			
			<property name="name" type="string" length="25" />
			<property name="gender" type="string" length="10" />
			<property name="password" type="string" length="20"/>
			<property name="photo" type="text" length="2147483647"/>
			
		</class>
		
	</hibernate-mapping>


二,客户端数据库

客户端使用SQLite数据库,主要存储的数据有:好友列表,聊天列表,聊天记录和好友添加请求列表。
好友列表



聊天列表



聊天记录



好友添加请求列表



由于同一个客户端可能在不同时段,有不同的的账号进行登录,所以账号必须有自己独立的数据库,如果ID:1234的用户数据存储在1234.db中。对于用户与每个好友的聊天记录,则存储在以该好友ID命名的聊天记录表中(因为SQLite不支持数字字符串作为表名的首字,所以特定添加了chatting_前缀)。
另外,聊天列表,聊天记录和好友添加请求列表的属性,都是根据界面显示的需要设计的。










SQLite数据操作:
1.创建表(DBHelper类)
public class DBHelper extends SQLiteOpenHelper{
	private static final int DATABASE_VERSION = 1;
	
	/**好友列表 表名*/
	public static final String FRIENDS = "friends";
	/**聊天列表 表名*/
	public static final String CHAT_LIST = "chat_list";
	/**好友请求 表名*/
	public static final String NEW_FRIENDS = "new_friends";
	/**聊天记录表名前缀*/
	public static final String CHATTING_PREFIX = "chatting_";
	
	
	/**@param userId 以当前用户ID作为数据库名称*/
	public DBHelper(Context context,String userId) {
		//CursorFactory设置为null,使用默认值
		super(context, userId, null, DATABASE_VERSION);
	}

	//数据库第一次被创建时onCreate会被调用
	@Override
	public void onCreate(SQLiteDatabase db) {
		//好友列表
		db.execSQL("CREATE TABLE IF NOT EXISTS " + FRIENDS + " (friend_id VARCHAR(20) PRIMARY KEY, name VARCHAR(25), gender VARCHAR(10), photo TEXT)");
		//聊天列表
		db.execSQL("CREATE TABLE IF NOT EXISTS  " + CHAT_LIST + " (friend_id VARCHAR(20) PRIMARY KEY, unread INTEGER, content VARCHAR(20), time VARCHAR(10))");
		//好友请求列表
		db.execSQL("CREATE TABLE IF NOT EXISTS  " + NEW_FRIENDS + " (user_id VARCHAR(20) PRIMARY KEY, name VARCHAR(25), gender VARCHAR(10), verify_msg VARCHAR(20), time VARCHAR(10), is_agree INTEGER, photo TEXT)");
	}
	
	/**创建对应好友的聊天记录表,由于聊天记录表名需要根据好友ID来确定,所以只能在需要时新建*/
	public void createChattingTable(SQLiteDatabase db, String dbName)
	{
		db.execSQL("CREATE TABLE IF NOT EXISTS " + dbName + " (id INTEGER PRIMARY KEY AUTOINCREMENT, time VARCHAR(10), msg TEXT, send INTEGER, show_time INTEGER)");
	}

	//如果DATABASE_VERSION值被修改,系统发现现有数据库版本不同,即会调用onUpgrade
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}

}


2.增删改查(DBManager类)
以聊天列表为例,主要有获取和更新操作。
public class DBManager {
	/** 获得聊天列表信息 */
	public List<ChatListModel> GetChatList() {
		List<ChatListModel> chatList = new ArrayList<ChatListModel>();

		// 查询所有聊天列表数据
		Cursor cursor = mSQLite.rawQuery("SELECT * FROM " + DBHelper.CHAT_LIST,null);

		while (cursor.moveToNext()) {
			ChatListModel model = new ChatListModel();
			// friend_id , unread , content , time
			String friendId = cursor.getString(cursor.getColumnIndex("friend_id"));
			model.setFriendId(friendId);
			model.setContent(cursor.getString(cursor.getColumnIndex("content")));
			model.setTime(cursor.getString(cursor.getColumnIndex("time")));
			model.setUnread(cursor.getInt(cursor.getColumnIndex("unread")));
			//ChatListModel的title和photo需要从friends表中获取
			Cursor c = mSQLite.rawQuery("SELECT * FROM " + DBHelper.FRIENDS + " WHERE friend_id=?",	new String[]{friendId});
			if(c.moveToNext())
			{
				model.setTitle(c.getString(c.getColumnIndex("name")));
				model.setPhoto(c.getString(c.getColumnIndex("photo")));
			}

			chatList.add(model);
		}
		cursor.close();

		return chatList;
	}

	/** 更新聊天列表信息 覆盖更新 */
	public void UpdateChatList(List<ChatListModel> chatList) {

		ChatListModel model;
		// 开启事务
		mSQLite.beginTransaction();
		
		// 清空原来的聊天列表数据
		mSQLite.delete(DBHelper.CHAT_LIST, null, null);
		try {
			for (int i = 0; i < chatList.size(); i++) {
				model = chatList.get(i);
				// friend_id , unread , content , time 
				mSQLite.execSQL(
						"INSERT INTO " + DBHelper.CHAT_LIST + " VALUES(?, ?, ?, ?)",
						new Object[] { model.getFriendId(), model.getUnread(),model.getContent(), model.getTime()});
			}
			// 设置事务成功,不设置则回滚不提交
			mSQLite.setTransactionSuccessful();
		} finally {
			// 结束事务
			mSQLite.endTransaction();
		}
	}
}


3.缓存机制
除了需要将当前登录用户的信息进行缓存外,数据库数据也可以通过使用缓存,减少数据库的操作。并且将数据的修改操作(比如聊天列表项位置的改动)在缓存中完成,可以简化复杂度。
还是以聊天列表为例。
public class CacheUtils {
	private static List<ChatListModel> chatList = null;
	
	/**缓存聊天列表*/
	public static void UpdateChatList(List<ChatListModel> list) 
	{
		chatList = list;
	}
	
	/** 根据好友列表信息更新聊天会话信息。
	  * 如头像和昵称<BR/>需要判断返回值是否为null,再进行本地化存储 
  	  */
	public static List<ChatListModel> UpdateChatList(FriendList friendList) {
		if(chatList == null)
			return null;
		
		for(int i=0;i<chatList.size();i++)
		{
			ChatListModel model = chatList.get(i);
			String friendId = model.getFriendId();
			User user = friendList.getFriendsMap().get(friendId);
			if(user!=null)
			{
				//更新数据
				model.setPhoto(user.getPhoto());
				model.setTitle(user.getName());
				//删除原数据
				chatList.remove(i);
				//插入新数据
				chatList.add(i, model);
			}
		}
		
		return chatList;
	}
	
	/**更新对应好友的聊天列表信息*/
	public static List<ChatListModel> UpdateChatList(String friendId, ChatListModel model)
	{
		if(chatList == null)
			chatList = new ArrayList<ChatListModel>();
		
		int index = GetChatPosition(friendId);
		if(index != -1)//聊天会话已经存在
		{
			ChatListModel m = chatList.remove(index);//删除原记录
			//未读消息数目:原来+本次
			int unread = m.getUnread() + model.getUnread();
			model.setUnread(unread);
		}
		chatList.add(0, model);//添加到首位
		
		return chatList;
	}
	/**
	 * 删除聊天列表中的对应会话<BR/>
	 * @return 返回true,说明原来该好友的聊天会话存在,需要更新本地数据,以及删除对应聊天记录<BR/>
	 * 否则无需更新其他数据
	 */
	public static boolean RemoveChat(String friendId)
	{
		int index = GetChatPosition(friendId);
		if(index != -1)//聊天会话存在
		{
			chatList.remove(index);//删除原记录
			return true;
		}
		return false;
	}
	
	/**获得聊天列表*/
	public static List<ChatListModel> GetChatList()
	{
		return chatList;
	}
	
	/**根据好友ID,获得聊天会话在聊天列表的位置。-1表示会话不存在,需要新建*/
	private static int GetChatPosition(String friendId)
	{
		if(chatList == null)
			return -1;
		
		for(int i=0; i<chatList.size(); i++)
		{
			ChatListModel model = chatList.get(i);
			if(model.getFriendId().equals(friendId))
			{
				return i;
			}
		}
		
		return -1;
	}
}


首页 Android聊天软件的开发
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: