软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 数据库 -> asorm1.0betaandroidSqlite3ORM框架说明文档20160329 -> 正文阅读

[数据库]asorm1.0betaandroidSqlite3ORM框架说明文档20160329

1.前言


作为一个java工程师,做点android开发的时候,自己做了个orm数据库的映射框架,使用比较方便,所以就放出来;
大家喜欢就拿去用,源码https://github.com/huitoukest/asorm;
很少用github,别见怪;
asorm1.0beta-->android Sqlite3 ORM;
1.本数据库支持自动创建表格,表的名字是你指定的Entity的名字;
如果要更改建表的名称,可以在你的Entity中复写BaseEntity中的public String getTableName()方法即可;
2.支持事务管理;
3.如果需要实现外键和存储过程需要自己编写相关sql语句;
4.不支持外键映射,只是支持对象和sql表之间的映射;
5.本数据库依赖于fastJson,请导入相关的包,对于Entity中不需要序列化的属性,请用@JSONField(serialize=false)注解;

2.开始使用

1.建立实体


这个和j2ee上使用Hibernate等框架是类似的,简历和数据库中表格相对应的类;
此类必须继承自BaseEntity;
示例:

public class User extends BaseEntity {

    public Long Id;	
    public String Login_Name;
    public String Password;
    public String Real_Name;
    public Long State;
    public String Uid;
     @Entity_FieldProperty(FieldType=FieldType.JsonObject,cls=Sys_User_Info.class)
     public Sys_User_Info UserInfo;
     @Override
 	public Long getPrimaryKeyValue() {
 		return Id;
 	}
	@Override
	public String getPrimaryKeyName() {
		return "Id";
	}
}
其中你必须Override其中的两个方法public Long getPrimaryKeyValue()和public String getPrimaryKeyName(),返回此实体的主键值与主键名称;
此实体对应的表的名称默认为其类名,不可更改;
主键只能是Long或者int类型;
默认支持的属性类型有:int,Integer,Short,short,Double,double,Float,float,Date,String,Long,long,Byte,byte;以及注解过的对象
对于实体Entity类的属性,可以通过@Entity_FieldProperty注解来对其映射方式做说明;
对于Entity_FieldProperty的FieldType=FieldType.XXX有四种方式;
JsonList,JsonObject,Base,Transient,具体功能见下面代码说明;
注解内容:

/**
 * 指定当前Entity中的属性的属性,即自生的类别和转换的方式
 * JsonList,JsonObject,Base,Transient
 * 当FieldType.Base的时候,将会按照默认识别的类型使用,即此时的cls属性不会生效
 * JsonList,JsonObject表示此对象需要转换为一个json对象或者字符串;
 * Transient表示此对象,不进行数据库的存和取操作,选择Transient的时候,cls属性不会生效
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity_FieldProperty {
	
	/**
	 * 指定一个类型是FieldType的,表现为FieldType=默认为FieldType.Base的Annotation
	 * @return
	 */
	FieldType FieldType() default FieldType.Base;
	/**
	 * 指定一个类型是Class的,表现为cls=默认为String.class的Annotation
	 * @return
	 */
	Class<?> cls() default String.class;
	/**
     * 指定当前属性的类型
     *
     */
    public enum FieldType{   	  
    	JsonList,JsonObject,Base,Transient;
    	};       	
}


对于对象,本框架是以json方式序列化属性为字符串之后存储到数据库的;

2.初始化数据库和asorm


在android使用此框架操作数据之前,需要对数据库进行初始化;
调用DataBaseManager.initializeInstance(Context c,EntityInfos entityInfos);方法来初始化数据库和asorm;
只有初始化之后才可以使用和数据库相关的操作;建议在app启动的第一个类中最先调用此方法;并传入Application 的context
EntityInfos是一个接口,我们需要实现此接口,此接口包含如下方法:

/**
	 * 返回Entity类,你的Entity类的set
	 * @return
	 */
	public HashSet<Class<? extends BaseEntity>> getEntityClasses();
	/**
	 * 返回数据库的名称,如"123";
	 * @return
	 */
	public String getDataBaseName();
	/**
	 * 返回数据库的版本,如1;
	 * @return
	 */
	public int getDataBaseVersion();
	/**
	 * 当数据库版本变化的时候先调用此方法;
	 * 然后返回true表示调用默认方法,删除所有数据然后重新建立表;
	 * 然会false表示不调用默认方法,此方法不会自己管理事务;
	 * @return
	 */
	public boolean onDataBaseVersionChange(SQLiteDatabase db);
示例:

public class MyEntityInfos implements EntityInfos{

	@Override
	public HashSet<Class<? extends BaseEntity>> getEntityClasses() {
		HashSet<Class<? extends BaseEntity>> set=new HashSet<Class<? extends BaseEntity>>();
		set.add(User.class);
		return set;
	}

	@Override
	public String getDataBaseName() {
        return "dview242.db";
	}

	@Override
	public int getDataBaseVersion() {
		return 1;
	}
	@Override
	public boolean onDataBaseVersionChange(SQLiteDatabase db) {
		return true;
	}
}
初始化中,主要做如下工作:
建立和Entity对应的表,同时保持表名称和主键信息;
之后我们可以调用EntityManager.getTableNameByCls(Class<? extends BaseEntity> cls);方法来获取表明,
同样,可以调用EntityManager的public static String getPrimaryKeyNameByCls(Class<? extends BaseEntity> cls);方法来获取主键名称;

3.建立service层;


一个app应该有数据库层;控制层;表现层;
而asorm框架主要封装了数据层的操作的dao层,我们需要在控制层做好事务控制;
框架要求,所有的和数据库操作相关的顶层封装都需要建立事务的控制下,
意思就是你操作数据库的任何操作,都必须使用此框架提供的事务控制方式来控制事务,同时不要自己打开关闭数据库和事务,而是应该交给asorm来控制;

第一步:建立Service方法接口,并继承自BaseServiceI接口:

public interface LoginTypeServiceI extends BaseServiceI{
	@SqliteTransaction(Type=TransActionType.Write)
	public abstract LoginType getLoginType() throws Exception;
	@SqliteTransaction(Type=TransActionType.Write)
	public abstract boolean saveOrUpdate(LoginType loginType) throws Exception;

}
public interface BaseServiceI {
	@SqliteTransaction(Type=TransActionType.Write)
	public BaseEntityDaoI getBaseEntityDao();
}
BaseServiceI的主要作用是返回BaseEntityDaoI这个接口;

第二步:建立Service的实现类;


实现自定的service接口,并实现其方法;
对于public BaseEntityDaoI getBaseEntityDao();可以继承类BaseService,此类中复写了此方法;

public class BaseService implements BaseServiceI{
	@SqliteTransaction(Type=TransActionType.Write)
	public BaseEntityDaoI getBaseEntityDao(){
		return BaseEntityDao.getBaseEntityDaoI();
	}
}

当然,用户也可以自己复写方法,内容如下 BaseEntityDao.getBaseEntityDaoI();
对于BaseEntityDaoI系统提供的是BaseEntityDao实现,用户熟读源码后可以自行实现内容;

第三步:注解事务


     利用BaseEntityDao我们可以对对象进行crud等操作;在操作之前,需要对方法事务进行管理;
     在此方法对应的接口的方法上,用注解来说明事物;

public interface LoginTypeServiceI extends BaseServiceI{
	@SqliteTransaction(Type=TransActionType.Read)
	public abstract LoginType getLoginType() throws Exception;
	@SqliteTransaction(Type=TransActionType.Write)
	public abstract boolean saveOrUpdate(LoginType loginType) throws Exception;

}

 目前支持Read和Write两种方式,底层的实现实际上都是得到一个可写的数据库连接;
不同的是对事物的管理不同;对于读写方式,请选择Write

   第四步:操作对象


对Entity对象进行增删改查等操作,由于方法之间事务的独立性,service层也可以考虑做成单例;
示例:

public class LoginTypeService implements LoginTypeServiceI {
private BaseEntityDaoI baseDao;

       private LoginTypeService(){
    	   baseDao=BaseEntityDao.getBaseEntityDaoI();
       }
       
       public static LoginTypeServiceI getNewProxyInstance(){
    	   return (LoginTypeServiceI) MySqliteTransactionProxy.getSqliteTransactionProxy(LoginTypeServiceI.class,new LoginTypeService());
       }

    @Override
	public LoginType getLoginType() throws Exception{
    	   LoginType lt=new LoginType();
    	   lt.setId(1L);
    	   try {
    		   lt=baseDao.get(lt);
			   return lt;
		} catch (Exception e) {
			throw new ReturnException(null);
		}
       }
    @Override
	public boolean saveOrUpdate(LoginType loginType) throws Exception{
    	   if(loginType==null||loginType.getPrimaryKeyValue()==null)
    		   return false;
    	   try {
    		   baseDao.saveOrUpdate(loginType);
			   return true;
		} catch (Exception e) {
			throw new ReturnException(false);
		}
    	   
       }

	@Override
	public BaseEntityDaoI getBaseEntityDao() {
		return baseDao;
	}
       
}
说明:
在显示层,一般是activity中;我们通过LoginTypeServiceI service=(LoginTypeServiceI)
 MySqliteTransactionProxy.getSqliteTransactionProxy(LoginTypeServiceI.class,new LoginTypeService());
方式来获取servic层;即用MySqliteTransactionProxy.getSqliteTransactionProxy(service接口类,service实现类)得到service接口的一个实现来获取service;
然后通过返回的接口示例来操作数据库;
若果想要在serive层方法执行的时候发生异常的时候返回一个值;可以使用throw new ReturnException(XXXX);
这样将会回滚当前的事务,并返回指定的值;
示例:

public class UserLoginActivity extends BaseFragmentActivity {
	private UserServiceI userService;</span>
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_userlogin);	
		userService=(UserServiceI) MySqliteTransactionProxy.getSqliteTransactionProxy(UserServiceI.class,new UserService());
		initView();
	}
	
	public void initView(){
		......
	}
	
	public void user_login_click(View v){
		switch (v.getId()) {
		case R.id.submit_button_userlogin:
			{
				<span style="color:#ff0000;">userService.LoginFromServer(userName,password,webServiceCallBack);</span>
		    }
			break;
		case .......
		default:
			break;
		}
	}
}

3.BaseDaoI中方法一览


BaseDao中方法的实现是花了一点时间和精力的,有兴趣的童鞋可以去查看;没兴趣的可以直接使用;

public interface BaseEntityDaoI {

	public abstract SQLiteDatabase getDataBase();

	/**
	 * 得到当前的最大的id号码的值
	 * @param db
	 * @return
	 */
	public abstract <T extends BaseEntity> Long getMaxId(T t);

	/**
	 * 得到当前的最小的id号码的值
	 * @param db
	 * @return
	 */
	public abstract <T extends BaseEntity> Long getMinId(T t);

	/**
	 * 得到当前的的记录总数
	 * @param db
	 * @return
	 */
	public abstract <T extends BaseEntity> Long getCount(Class<T> cls);

	/**
	 *得到除开指定名称的属性列 
	 */
	public abstract <T extends BaseEntity> String[] getEntityColumnNames(
			Class<T> cls, Boolean isRepacePrimaryKeyName,
			String... exceptCoulums);

	/**失败返回null
	 *  传入代Id值的Entity的值实例
	 * @param t 返回t
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> T get(Class<T> cls, String id)
			throws Exception;

	/**失败返回null
	 *  传入代Id值的Entity的值实例
	 * @param t 返回t
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> T get(T t) throws Exception;

	/**手动的条件搜索
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> T get(Class<T> cls,
			String[] columns, String selection, String[] selectionArgs,
			String orderBy) throws Exception;

	/**失败返回null
	 *  传入代Id值的Entity的值实例
	 * @param t 返回t
	 * @param exceptCoulums 不需要取出的数据列的名称
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> T get(Class<T> cls, String id,
			String... exceptCoulums) throws Exception;

	/**
	 * 
	 * 失败返回空数组
	 * @param db
	 * @param cls
	 * @param selection
	 * @param selectionArgs
	 * @param orderBy
	 * @param limit select * from table_name limit N,M //N序号从0开始
	 * @param exceptCoulums 指定不从数据库取出的列
	 * @return
	 * @throws Exception
	 */
	public abstract <T extends BaseEntity> List<T> getList(Class<T> cls,
			String selection, String[] selectionArgs, String orderBy,
			String limit, String... exceptCoulums) throws Exception;

	/**
	 * 失败返回空数组
	 * @param db
	 * @param cls
	 *@param selection
	 * @param selectionArgs
	 * @param orderBy
	 * @param limit select * from table_name limit N,M //N序号从0开始
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> List<T> getList(Class<T> cls,
			String selection, String[] selectionArgs, String orderBy,
			String limit) throws Exception;

	/**
	 * 获取数据库中的所有的记录
	 * @param db
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public abstract <T extends BaseEntity> List<T> getList(Class<T> cls)
			throws Exception;

	public abstract <T extends BaseEntity> void saveOrUpdate(T t)
			throws Exception;

	/**
	 * 
	 * @param t
	 * @return 插入返回1
	 * @param columnName 如果指定的字段,有相同的值存在于数据库,那么就更新数据库,否则保存
	 * @throws Exception
	 */
	public abstract <T extends BaseEntity> void saveOrUpdate(T t,
			String columnName) throws Exception;

	/**
	 * 先删除,后保存,没有则不删除
	 * @param db
	 * @param t
	 * @throws Exception
	 */
	public abstract <T extends BaseEntity> void deleteAndSave(T t)
			throws Exception;

	/**
	 * 
	 * @param db
	 * @param list
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> void saveOrUpdateList(List<T> list)
			throws Exception;

	/**
	 * 
	 * @param db
	 * @param list
	 * @param column 指定列的值相同就更新,否则就保存
	 * @throws Exception
	 */
	public abstract <T extends BaseEntity> void saveOrUpdateList(List<T> list,
			String column) throws Exception;

	/**
	 *删除后保存所有 
	 * @param db
	 * @param list
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> void deleteAndSaveList(List<T> list)
			throws Exception;

	public abstract <T extends BaseEntity> int update(T t) throws Exception;

	/**
	 * 
	 * @param t
	 * @param notUpdateColumns 不需要更新的字段名称的数组
	 * @return
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> int update(T t,
			String[] notUpdateColumns) throws Exception;

	public abstract <T extends BaseEntity> int save(T t) throws Exception;

	public abstract <T extends BaseEntity> int delete(Class<T> cls, String id)
			throws Exception;

	public abstract <T extends BaseEntity> int delete(T t) throws Exception;

	public abstract <T extends BaseEntity> int deleteList(Class<T> cls,
			String ids) throws Exception;

	public abstract <T extends BaseEntity> int deleteList(List<T> ts)
			throws Exception;

	public abstract <T extends BaseEntity> int deleteAll(Class<T> cls)
			throws Exception;

	/**
	 * 
	 * @param db
	 * @param sqlString
	 * @param selectionArgs sql中?占位符的参数
	 * @param columns 需要出去的列的名称,没有会赋值null;取出的列只支持float/string/blob/string/null这几种类型;
	 * *其中二进制会转换成为byte[]类型;除开这些类型外,系统会默认用string来取出数据
	 * @return List<Object[]>
	 */
	public abstract <T extends BaseEntity> List<Object[]> getColumns(
			String sqlString, String[] selectionArgs, String... columns);

	/**
	 * 判断一个属性是否是静态变量,此类暂时不用
	 * @param field
	 */
	public abstract boolean isStaticField(Field field);

	//通过Cursor自动将值赋值到实体
	public abstract <T extends BaseEntity> T initFromCursor(Cursor c,
			Class<T> cls) throws IllegalAccessException,
			IllegalArgumentException, InstantiationException;

	public abstract <T extends BaseEntity> T initFromCursor(Cursor c, T t)
			throws IllegalAccessException, IllegalArgumentException,
			InstantiationException;

	public abstract <T extends BaseEntity> ContentValues getContentValues(T t)
			throws IllegalAccessException, IllegalArgumentException;

	/**
	 * 返回该类属性的键值对,键和值均为String类型
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	public abstract <T extends BaseEntity> Map<String, Object> getMapValues(T t)
			throws IllegalAccessException, IllegalArgumentException;

	public abstract <T extends BaseEntity> void saveToDataBase(T t)
			throws Exception;

	public abstract <T extends BaseEntity> void updateToDataBase(T t)
			throws Exception;

	/**
	 * 
	 * @param tableName
	 * @param db
	 * @param columnName 指定此此表的一个列名称,更新所有相同的记录
	 * @throws Exception
	 */
	public abstract <T extends BaseEntity> void updateToDataBaseByColumn(T t,
			String columnName) throws Exception;

	/**
	 * 
	 * @param tableName
	 * @param data
	 * @param notUpdateColumns 不需要跟新的字段,区分大小写
	 * @throws Exception 
	 */
	public abstract <T extends BaseEntity> void updateToDataBase(T t,
			String[] notUpdateColumns) throws Exception;

}

4.小结


1.本框架为非正式版,肯定有不少的bug,作者也没有全部测试,有bug的可以反馈留言;
2.此版本通过同步锁对数据库写操作进行阻塞,理论上并不好,实际高并发或者大量输入写入的不推荐使用;
3.下一个版本想要实现的功能:
(1)采用回调的方式来进行数据库的读写操作;
(2)采用一个表一个数据库的方式提高并发写操作;
4.文档可能不全,不过源码注释还是很多,建议看看源码即可
5.附上jar包地址
http://download.csdn.net/detail/huitoukest/9475537

......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-03-29 23:04:38  
数据库 最新文章
Python&MySQL&PyQt
最新用python来操作mysql完全解析
mongodb的安装详解
1.PDO简介
《MySQL必知必会学习笔记》:高级联结
【翻译自mos文章】怎么对Microsoft(Office)
MyCAT全局表描述及示例
ocp
关于SQL数据表存储过程表名前缀换成dbo代码
数据库调优教程(二)慢查询数据准备
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年7日历
2018-7-19 13:48:25
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --