最近在写个简单的“我的智能客服”功能。基于Socket长链接,需要存储聊天信息。按消息顺序插入本地数据库。ORMLite就两个jar放进去即可,集成方便,简单易用,网上博客也比较多,所以就拿来集成到项目中。
参考:
https://blog.csdn.net/da_caoyuan/article/details/61414626
https://blog.csdn.net/da_caoyuan/article/details/60876336
https://blog.csdn.net/u013501637/article/details/52388861
一.下载ORMLite的jar包
官网地址:http://ormlite.com/releases/
包括核心包和Android包
ormlite-core-5.1.jar
ormlite-android-5.1.jar
并add as library
二.开始写代码
创建实体类
消息的实体类:
注意两点:
1.标明要创建的表名:@DatabaseTable(tableName = "ChatMessage")
2.标明数据库中id和字段的名字:@DatabaseField(generatedId = true),@DatabaseField(columnName = "name")
package com.app.ormlite;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "ChatMessage")
public class ChatMessage {
@DatabaseField(generatedId = true)
private long id;
@DatabaseField(columnName = "name")
public String name;
@DatabaseField(columnName = "msg")
public String msg;
@DatabaseField(columnName = "time")
public long time;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
@Override
public String toString() {
return "ChatMessage{" +
"id=" + id +
", name='" + name + '\'' +
", msg='" + msg + '\'' +
", time=" + time +
'}';
}
}
创建数据库的Helper:(和SqlLite真像)
在Helper中可能创建有多张表,想获取某一张表的Dao时,直接在getDao(Class clazz);方法中传入关联实体类的类型即可。最后注意释放资源。
package com.app.ormlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class AppDatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DB_NAME = "App.db";
public static final int DB_VERSION = 1;
public AppDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
try {
TableUtils.createTable(connectionSource, ChatMessage.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int oldVersion, int newVersion) {
System.out.println("MyDatabaseHelper.onUpgrade oldVersion=" + oldVersion + " newVersion=" + newVersion);
try {
switch (oldVersion) {
case 1:
//如果现在是第一版本,想在下一版本更新数据库添加字段
getDao(ChatMessage.class).executeRaw("alter table ChatMessage add column xxx varchar(20)");
case 2:
// TableUtils.createTable(connectionSource, MyBean2.class);
//在数据库版本2的下一版本,新增加了一张表
default:
break;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private static AppDatabaseHelper instance;
public static AppDatabaseHelper getHelper(Context context) {
if (instance == null) {
synchronized (AppDatabaseHelper.class) {
if (instance == null)
instance = new AppDatabaseHelper(context);
}
}
return instance;
}
private Map daos = new HashMap();
public synchronized Dao getDao(Class clazz) throws SQLException {
Dao dao = null;
String className = clazz.getSimpleName();
if (daos.containsKey(className)) {
dao = daos.get(clazz);
}
if (dao == null) {
dao = super.getDao(clazz);
daos.put(className, dao);
}
return dao;
}
/**
* 释放资源
*/
@Override
public void close() {
super.close();
for (String key : daos.keySet()) {
Dao dao = daos.get(key);
dao = null;
}
}
}
下面轮到Dao层了
业务主要涉及到:
1.添加单条消息。
2.批量删除消息
3.分组查询
4.查询所有
定义接口
package com.app.ormlite.dao;
import com.app.ormlite.ChatMessage;
import java.util.Collection;
import java.util.List;
public interface ChatMessageDao {
/**
* 添加单条消息
* @param chatMessage
* @return
*/
int insert(ChatMessage chatMessage);
/**
* 删除单条消息
* @param id
* @return
*/
int delete(long id);
/**
* 批量删除指定id的消息
* @param ids
* @return
*/
int delete(Collection ids);
/**
* 删除所有消息
* @return
*/
int deleteAll();
/**
* 查询单条消息
* @param id
* @return
*/
ChatMessage query(long id);
/**
* 分组查询消息
* @param start
* @param end
* @return
*/
List queryLimit(long start, long end);
/**
* 查询所有消息
* @return
*/
List queryAll();
}
实现接口方法
在构造方法里通过AppDatabaseHelper获取关于ChatMessage的Dao。
package com.app.ormlite.dao;
import android.content.Context;
import com.app.ormlite.AppDatabaseHelper;
import com.app.ormlite.ChatMessage;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ChatMessageDaoImpl implements ChatMessageDao {
private Dao dao;
public ChatMessageDaoImpl(Context context) {
AppDatabaseHelper helper = AppDatabaseHelper.getHelper(context);
try {
dao = helper.getDao(ChatMessage.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public int insert(ChatMessage chatMessage) {
try {
int i = dao.create(chatMessage);
return i;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
@Override
public int delete(long id) {
try {
int i = dao.deleteById(id);
return i;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public int delete(Collection ids) {
try {
int i = dao.deleteIds(ids);
return i;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
@Override
public int deleteAll() {
DeleteBuilder builder = dao.deleteBuilder();
try {
int i = builder.delete();
return i;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public ChatMessage query(long id) {
try {
ChatMessage chatMessage = dao.queryForId(id);
return chatMessage;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
public List queryLimit(long offset, long limit) {
QueryBuilder builder = dao.queryBuilder();
try {
builder.offset(offset);
builder.limit(limit);
// builder.where().between("id", offset, limit);
List list = builder.query();
return list;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
public List queryAll() {
try {
List list = dao.queryForAll();
return list;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
queryLimit(long start, long limit)方法中我刚开始犯了个错误:
之前以为批量分组查询是
builder.where().between("id", offset, limit);
between方法是查询在id处于两个值之间的数据。比如id在10-19之间,如果id=15的数据没有了就,就只能查到9条。
应该是下面这样的写法:
builder.offset(offset);
builder.limit(limit);
offset:从第一条存在的记录偏移几条开始查,注意是实际存在的第一条,而不是从id=1开始偏移几条。
如:第一条数据id=11,想查id在12-15的4条数据,
应该这样写
builder.offset(1);
builder.limit(4);
我之前一直查不到数据,就是这点理解错了。
终于到测试代码阶段了
布局文件
代码很简单,我就不粘贴了
下面是MainActivity的方法
public class MainActivity extends AppCompatActivity {
private static final String TAG = "ORMLiteDemo_";
private EditText mEtQId;
private EditText mEtQOffset;
private EditText mEtQLimit;
private ChatMessageDaoImpl dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEtQId = ((EditText) findViewById(R.id.et_query_id));
mEtQOffset = ((EditText) findViewById(R.id.et_query_offset));
mEtQLimit = ((EditText) findViewById(R.id.et_query_limit));
dao = new ChatMessageDaoImpl(this);
}
//添加一条记录,并打印影响的行数,这里insert应该=1
public void add(View v) {
ChatMessage chatMessage = new ChatMessage();
chatMessage.setName("张三");
chatMessage.setMsg("消息2");
chatMessage.setTime(new Date().getTime());
int insert = dao.insert(chatMessage);
Log.e(TAG, "insert: " + insert);
}
//删除一条记录,并打印影响的行数,
//delete=1说明删除成功,delete=0说明没有这条记录
public void delete(View v) {
int delete = dao.delete(1);
Log.e(TAG, "delete: " + delete);
}
//删除指定多条记录,并打印影响的行数,
//第一次打印delete=2,说明删除id为2、3的记录成功。第二次delete=0,说明已经删除了
public void deletes(View v) {
ArrayList ids = new ArrayList<>();
ids.add(2l);
ids.add(3l);
int delete = dao.delete(ids);
Log.e(TAG, "delete: " + delete);
}
//删除全部记录,并打印影响的行数
public void deleteAll(View v) {
int i = dao.deleteAll();
Log.e(TAG, "deleteAll: " + i);
}
//查询指定id的记录,没有则返回null
public void query(View v) {
String s = mEtQId.getText().toString().trim();
int i = Integer.parseInt(s);
ChatMessage query = dao.query(i);
if (query != null) {
Log.e(TAG, query.toString());
} else {
Log.e(TAG, "null");
}
}
//分组查询,分别输入1和4,打印id从12-15的数据
public void queryLimit(View v) {
String offsetStr = mEtQOffset.getText().toString().trim();
String limitStr = mEtQLimit.getText().toString().trim();
int offset = Integer.parseInt(offsetStr);
int limit = Integer.parseInt(limitStr);
List query = dao.queryLimit(offset, limit);
Log.e(TAG, "queryLimit: "+(query == null));
Log.e(TAG, "queryLimit: "+query.size());
for (ChatMessage c :
query) {
Log.e(TAG, "q_limit: " + c.toString());
}
}
//获取全部数据
public void getAll(View v) {
List chatMessages = dao.queryAll();
for (ChatMessage c :
chatMessages) {
Log.e("item: ", c.toString());
}
}
}
至此,一个简单的demo就完成了。
再次感谢:
https://blog.csdn.net/da_caoyuan
https://blog.csdn.net/u013501637/article/details/52388861