LitePal数据库框架 -- 源码解析之创建数据库

使用LitePal创建数据库,表

准备工作:
①:引入LitePal jar包或者源码
②:写好实体类
public class News {
private int id;
private String title;
private String content;
private Date publishDate;
private int commentCount;
...get set 方法
}
③:在assets目录下创建LitePal.xml文件,文件格式如下:
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<!-- 设置数据库名字 -->
<dbname value="demo"></dbname>
<!-- 数据库版本号 -->
<version value="1"></version>
<!-- 设置数据库存储位置 value=internal,external -->
<storage value="external"></storage>
<!-- 显示数据库查询语句的大小写,可以设置为upper,lower,keep -->
<cases value="lower"></cases>
<!-- 设置所有表的映射模型 -->
<list>
<mapping class="com.example.databasetest.model.News"></mapping>
</list>
</litepal>
④:初始化Context对象
LitePal.initialize(getApplicationContext());
// getApplicationContext():获取的是全局的Application对象
⑤:创建数据库,表:Connector.getDatabase()

LitePal创建数据库源码解析

Connector.getDatabase()创建数据库,表源码解析
public static SQLiteDatabase getDatabase() {
return getWritableDatabase();
}
public synchronized static SQLiteDatabase getWritableDatabase() {
LitePalOpenHelper litePalHelper = buildConnection();
// 创建或更新数据库
return litePalHelper.getWritableDatabase();
}
private static LitePalOpenHelper buildConnection() {
// 获取LitePalAttr的属性
LitePalAttr litePalAttr = LitePalAttr.getInstance();
// 检查设置的属性是否合法
litePalAttr.checkSelfValid();
if (mLitePalHelper == null) {
String dbName = litePalAttr.getDbName();
// 是否是外部存储
if ("external".equalsIgnoreCase(litePalAttr.getStorage())) {
dbName = LitePalApplication.getContext().getExternalFilesDir("") + "/databases/" + dbName;
}
// 创建SQLiteOpenHelper类
mLitePalHelper = new LitePalOpenHelper(dbName, litePalAttr.getVersion());
}
return mLitePalHelper;
}

解析assets目录下的LitePal.xml文件,并读取里面设置的值

获取LitePalAttr类
public static LitePalAttr getInstance() {
if (litePalAttr == null) {
synchronized (LitePalAttr.class) {
if (litePalAttr == null) {
litePalAttr = new LitePalAttr();
// 判断Assets目录下是否存在LitePal.xml文件
if (BaseUtility.isLitePalXMLExists()) {
// 解析LitePal文件里面的值并设置到LitePalAttr类中
LitePalConfig config = LitePalParser.parseLitePalConfiguration();
litePalAttr.setDbName(config.getDbName());
litePalAttr.setVersion(config.getVersion());
litePalAttr.setClassNames(config.getClassNames());
litePalAttr.setCases(config.getCases());
litePalAttr.setStorage(config.getStorage());
}
}
}
}
return litePalAttr;
}
判断在assets目录下面是否存在LitePal.xml文件
public static boolean isLitePalXMLExists() {
try {
AssetManager assetManager = LitePalApplication.getContext().getAssets();
String[] fileNames = assetManager.list("");
if (fileNames != null && fileNames.length > 0) {
for (String fileName : fileNames) {
if (Const.Config.CONFIGURATION_FILE_NAME.equalsIgnoreCase(fileName)) {
return true;
}
}
}
} catch (IOException e) {
}
return false;
}
解析LitePal.xml文件,并取出里面的值,使用的是Pull解析
public static LitePalConfig parseLitePalConfiguration() {
if (parser == null) {
parser = new LitePalParser();
}
return parser.usePullParse();
}
private LitePalConfig usePullParse() {
try {
LitePalConfig litePalConfig = new LitePalConfig();
// 使用pull解析
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(getConfigInputStream(), "UTF-8");
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch (eventType) {
case XmlPullParser.START_TAG: {
// 解析的标签有:dbname,version,mapping,cases,storage;标签的属性有:value,class
// 从解析LitePal文件可以知道LitePal文件的规范
if (NODE_DB_NAME.equals(nodeName)) {
String dbName = xmlPullParser.getAttributeValue("", ATTR_VALUE);
litePalConfig.setDbName(dbName);
} else if (NODE_VERSION.equals(nodeName)) {
String version = xmlPullParser.getAttributeValue("", ATTR_VALUE);
litePalConfig.setVersion(Integer.parseInt(version));
} else if (NODE_MAPPING.equals(nodeName)) {
String className = xmlPullParser.getAttributeValue("", ATTR_CLASS);
litePalConfig.addClassName(className);
} else if (NODE_CASES.equals(nodeName)) {
String cases = xmlPullParser.getAttributeValue("", ATTR_VALUE);
litePalConfig.setCases(cases);
} else if (NODE_STORAGE.equals(nodeName)) {
String storage = xmlPullParser.getAttributeValue("", ATTR_VALUE);
litePalConfig.setStorage(storage);
}
break;
}
default:
break;
}
eventType = xmlPullParser.next();
}
return litePalConfig;
} catch (XmlPullParserException e) {
throw new ParseConfigurationFileException(
ParseConfigurationFileException.FILE_FORMAT_IS_NOT_CORRECT);
} catch (IOException e) {
throw new ParseConfigurationFileException(ParseConfigurationFileException.IO_EXCEPTION);
}
}
检查LitePal.xml配置文件里面设置的属性是否合法
public void checkSelfValid() {
// 数据库名不能为空
if (TextUtils.isEmpty(dbName)) {
throw new InvalidAttributesException(
InvalidAttributesException.DBNAME_IS_EMPTY_OR_NOT_DEFINED);
}
// 数据库名是否有.db后缀,如果没有加上.db后缀
if (!dbName.endsWith(Const.Config.DB_NAME_SUFFIX)) {
dbName = dbName + Const.Config.DB_NAME_SUFFIX;
}
// 数据库版本号不能小于1
if (version < 1) {
throw new InvalidAttributesException(
InvalidAttributesException.VERSION_OF_DATABASE_LESS_THAN_ONE);
}
// 数据库版本不能小于上一次的版本
if (version < SharedUtil.getLastVersion(extraKeyName)) {
throw new InvalidAttributesException(
InvalidAttributesException.VERSION_IS_EARLIER_THAN_CURRENT);
}
// 默认设置数据库语句为小写
if (TextUtils.isEmpty(cases)) {
cases = Const.Config.CASES_LOWER;
} else {
if (!cases.equals(Const.Config.CASES_UPPER)
&& !cases.equals(Const.Config.CASES_LOWER)
&& !cases.equals(Const.Config.CASES_KEEP)) {
throw new InvalidAttributesException(cases
+ InvalidAttributesException.CASES_VALUE_IS_INVALID);
}
}
}
是否存储到外部存储设备
if (mLitePalHelper == null) {
String dbName = litePalAttr.getDbName();
if ("external".equalsIgnoreCase(litePalAttr.getStorage())) {
dbName = LitePalApplication.getContext().getExternalFilesDir("") + "/databases/" + dbName;
}
mLitePalHelper = new LitePalOpenHelper(dbName, litePalAttr.getVersion());
}

创建SQLiteOpenHelper类

mLitePalHelper = new LitePalOpenHelper(dbName, litePalAttr.getVersion());

执行创建数据库操作

litePalHelper.getWritableDatabase();
如果是第一次创建,则会执行onCreate方法
@Override
public void onCreate(SQLiteDatabase db) {
Generator.create(db);
}
Generator类的create方法
static void create(SQLiteDatabase db) {
// 创建数据库
create(db, true);
// 增加表之间的关联
addAssociation(db, true);
}

把实体类转换成对应的表model

private static void create(SQLiteDatabase db, boolean force) {
Creator creator = new Creator();
creator.createOrUpgradeTable(db, force);
}
@Override
protected void createOrUpgradeTable(SQLiteDatabase db, boolean force) {
for (TableModel tableModel : getAllTableModels()) {
// 创建或更新表
createOrUpgradeTable(tableModel, db, force);
}
}
protected Collection<TableModel> getAllTableModels() {
if (mTableModels == null) {
mTableModels = new ArrayList<TableModel>();
}
if (!canUseCache()) {
mTableModels.clear();
for (String className : LitePalAttr.getInstance().getClassNames()) {
mTableModels.add(getTableModel(className));
}
}
return mTableModels;
}
protected TableModel getTableModel(String className) {
// 获取类名
String tableName = DBUtility.getTableNameByClassName(className);
// 创建每张表的model
TableModel tableModel = new TableModel();
tableModel.setTableName(tableName);
tableModel.setClassName(className);
// 获取这个类的字段,并设置到对应的表model中
List<Field> supportedFields = getSupportedFields(className);
for (Field field : supportedFields) {
ColumnModel columnModel = convertFieldToColumnModel(field);
tableModel.addColumnModel(columnModel);
}
return tableModel;
}
protected List<Field> getSupportedFields(String className) {
List<Field> fieldList = classFieldsMap.get(className);
if (fieldList == null) {
List<Field> supportedFields = new ArrayList<Field>();
Class<?> clazz;
try {
// 通过反射获取这个类的Class对象
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new DatabaseGenerateException(DatabaseGenerateException.CLASS_NOT_FOUND + className);
}
// 递归查询类的字段,可以查询父类的字段
recursiveSupportedFields(clazz, supportedFields);
// 把类的字段设置到map中,以classname为key
classFieldsMap.put(className, supportedFields);
return supportedFields;
}
return fieldList;
}
private void recursiveSupportedFields(Class<?> clazz, List<Field> supportedFields) {
// 如果递归查询到DataSupport类或者Object类,则退出,默认所有的类都继承    Object类
if (clazz == DataSupport.class || clazz == Object.class) {
return;
}
// 获取类的字段,包括公共,保护,默认(包)访问和私有字段,但不包括继承的字段
Field[] fields = clazz.getDeclaredFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
// 获取字段上面的注解
Column annotation = field.getAnnotation(Column.class);
// 如果有注解,并且注解的ignore为true则不加入
if (annotation != null && annotation.ignore()) {
continue;
}
// 获取字段的修饰符
int modifiers = field.getModifiers();
// 如果是静态(static)字段则不加入
if (!Modifier.isStatic(modifiers)) {
Class<?> fieldTypeClass = field.getType();
String fieldType = fieldTypeClass.getName();
// 判断是否支持此字段的类型,包括:boollean, float, double, int, long, short, char, byte, String, Date
if (BaseUtility.isFieldTypeSupported(fieldType)) {
supportedFields.add(field);
}
}
}
}
// 递归查询,查询父类的字段clazz.getSupper
recursiveSupportedFields(clazz.getSuperclass(), supportedFields);
}
支持的字段的类型
public static boolean isFieldTypeSupported(String fieldType) {
if ("boolean".equals(fieldType) || "java.lang.Boolean".equals(fieldType)) {
return true;
}
if ("float".equals(fieldType) || "java.lang.Float".equals(fieldType)) {
return true;
}
if ("double".equals(fieldType) || "java.lang.Double".equals(fieldType)) {
return true;
}
if ("int".equals(fieldType) || "java.lang.Integer".equals(fieldType)) {
return true;
}
if ("long".equals(fieldType) || "java.lang.Long".equals(fieldType)) {
return true;
}
if ("short".equals(fieldType) || "java.lang.Short".equals(fieldType)) {
return true;
}
if ("char".equals(fieldType) || "java.lang.Character".equals(fieldType)) {
return true;
}
if ("[B".equals(fieldType) || "[Ljava.lang.Byte;".equals(fieldType)) {
return true;
}
if ("java.lang.String".equals(fieldType) || "java.util.Date".equals(fieldType)) {
return true;
}
return false;
}
把一个字段转变成ColumnModel
private ColumnModel convertFieldToColumnModel(Field field) {
// 子段的名称
String fieldType = field.getType().getName();
// 获取字段的类型
String columnType = getColumnType(fieldType);
boolean nullable = true;
boolean unique = false;
String defaultValue = "";
// 获取字段上面的注解
Column annotation = field.getAnnotation(Column.class);
if (annotation != null) {
nullable = annotation.nullable();
unique = annotation.unique();
defaultValue = annotation.defaultValue();
}
ColumnModel columnModel = new ColumnModel();
// 判断列名是否合法,因为列名有可能会和sql语句关键字冲突
columnModel.setColumnName(DBUtility.convertToValidColumnName(field.getName()));
columnModel.setColumnType(columnType);
columnModel.setIsNullable(nullable);
columnModel.setIsUnique(unique);
columnModel.setDefaultValue(defaultValue);
return columnModel;
}
protected String getColumnType(String fieldType) {
String columnType;
for (OrmChange ormChange : typeChangeRules) {
// 返回字段的类型
columnType = ormChange.object2Relation(fieldType);
if (columnType != null) {
return columnType;
}
}
return null;
}
当前数组中的所有支持映射类型
private OrmChange[] typeChangeRules = { new NumericOrm(), new TextOrm(), new BooleanOrm(),
new DecimalOrm(), new DateOrm(), new BlobOrm()};
列名关键字合法性判断
public static String convertToValidColumnName(String columnName) {
if (isFieldNameConflictWithSQLiteKeywords(columnName)) {
// 如果有冲突则在列名后面_lpcolumn
return columnName + KEYWORDS_COLUMN_SUFFIX;
}
return columnName;
}
public static boolean isFieldNameConflictWithSQLiteKeywords(String fieldName) {
if (!TextUtils.isEmpty(fieldName)) {
String fieldNameWithComma = "," + fieldName.toLowerCase() + ",";
if (SQLITE_KEYWORDS.contains(fieldNameWithComma)) {
return true;
}
}
return false;
}
关键字如下:
,abort,add,after,all,alter,and,as,asc,autoincrement,before,begin,between,by,cascade,check,collate,column,commit,conflict,constraint,create,cross,database,deferrable,deferred,delete,desc,distinct,drop,each,end,escape,except,exclusive,exists,foreign,from,glob,group,having,in,index,inner,insert,intersect,into,is,isnull,join,like,limit,match,natural,not,notnull,null,of,offset,on,or,order,outer,plan,pragma,primary,query,raise,references,regexp,reindex,release,rename,replace,restrict,right,rollback,row,savepoint,select,set,table,temp,temporary,then,to,transaction,trigger,union,unique,update,using,vacuum,values,view,virtual,when,where,

执行Sql语句创建表

@Override
protected void createOrUpgradeTable(SQLiteDatabase db, boolean force) {
for (TableModel tableModel : getAllTableModels()) {
createOrUpgradeTable(tableModel, db, force);
}
}
 
protected void createOrUpgradeTable(TableModel tableModel, SQLiteDatabase db, boolean force) {
execute(getCreateTableSQLs(tableModel, db, force), db);
giveTableSchemaACopy(tableModel.getTableName(), Const.TableSchema.NORMAL_TABLE, db);
}
获取Sql语句
protected String[] getCreateTableSQLs(TableModel tableModel, SQLiteDatabase db, boolean force) {
// force:true,则创建表之前判断是否存在表,存在就先删除,再创建;false:直接创建
if (force) {
return new String[] { generateDropTableSQL(tableModel),
generateCreateTableSQL(tableModel) };
} else {
if (DBUtility.isTableExists(tableModel.getTableName(), db)) {
return null;
} else {
return new String[] { generateCreateTableSQL(tableModel) };
}
}
}
删除表的sql语句
protected String generateDropTableSQL(String tableName) {
return "drop table if exists " + tableName;
}
创建表的sql语句
protected String generateCreateTableSQL(String tableName, List<ColumnModel> columnModels,
boolean autoIncrementId) {
StringBuilder createTableSQL = new StringBuilder("create table ");
createTableSQL.append(tableName).append(" (");
if (autoIncrementId) {
createTableSQL.append("id integer primary key autoincrement,");
}
if (columnModels.size() == 0) {
createTableSQL.deleteCharAt(createTableSQL.length() - 1);
}
boolean needSeparator = false;
for (ColumnModel columnModel : columnModels) {
if (columnModel.isIdColumn()) {
continue;
}
if (needSeparator) {
createTableSQL.append(", ");
}
needSeparator = true;
createTableSQL.append(columnModel.getColumnName()).append(" ").append(columnModel.getColumnType());
if (!columnModel.isNullable()) {
createTableSQL.append(" not null");
}
if (columnModel.isUnique()) {
createTableSQL.append(" unique");
}
String defaultValue = columnModel.getDefaultValue();
if (!TextUtils.isEmpty(defaultValue)) {
createTableSQL.append(" default ").append(defaultValue);
}
}
createTableSQL.append(")");
LogUtil.d(TAG, "create table sql is >> " + createTableSQL);
return createTableSQL.toString();
}
执行sql语句
protected void execute(String[] sqls, SQLiteDatabase db) {
String throwSQL = "";
try {
if (sqls != null) {
for (String sql : sqls) {
throwSQL = sql;
// 执行sql语句,并设置sql语句的显示方式,主要有三种显示方式:keep, upper, lower
db.execSQL(BaseUtility.changeCase(sql));
}
}
} catch (SQLException e) {
throw new DatabaseGenerateException(DatabaseGenerateException.SQL_ERROR + throwSQL);
}
}
public static String changeCase(String string) {
if (string != null) {
LitePalAttr litePalAttr = LitePalAttr.getInstance();
String cases = litePalAttr.getCases();
if (Const.Config.CASES_KEEP.equals(cases)) {
return string;
} else if (Const.Config.CASES_UPPER.equals(cases)) {
return string.toUpperCase(Locale.US);
}
return string.toLowerCase(Locale.US);
}
return null;
}

新表创建时,把表名保存到table_schema表中,每张表只保存一次

protected void giveTableSchemaACopy(String tableName, int tableType, SQLiteDatabase db) {
// tableType:0代表正常的表,1代表中间连接表
StringBuilder sql = new StringBuilder("select * from ");
sql.append(Const.TableSchema.TABLE_NAME);
LogUtil.d(TAG, "giveTableSchemaACopy SQL is >> " + sql);
Cursor cursor = null;
try {
cursor = db.rawQuery(sql.toString(), null);
// 是否需要把新表保存到schema表中
if (isNeedtoGiveACopy(cursor, tableName)) {
ContentValues values = new ContentValues();
values.put(Const.TableSchema.COLUMN_NAME, BaseUtility.changeCase(tableName));
values.put(Const.TableSchema.COLUMN_TYPE, tableType);
db.insert(Const.TableSchema.TABLE_NAME, null, values);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}

创建关联表

private static void addAssociation(SQLiteDatabase db, boolean force) {
AssociationCreator associationsCreator = new Creator();
// 增加表之间的关联
associationsCreator.addOrUpdateAssociation(db, force);
}
获取所有的关联
protected Collection<AssociationsModel> getAllAssociations() {
if (mAllRelationModels == null || mAllRelationModels.isEmpty()) {
mAllRelationModels = getAssociations(LitePalAttr.getInstance().getClassNames());
}
return mAllRelationModels;
}
protected Collection<AssociationsModel> getAssociations(List<String> classNames) {
if (mAssociationModels == null) {
mAssociationModels = new HashSet<AssociationsModel>();
}
if (mGenericModels == null) {
mGenericModels = new HashSet<GenericModel>();
}
mAssociationModels.clear();
mGenericModels.clear();
for (String className : classNames) {
analyzeClassFields(className, GET_ASSOCIATIONS_ACTION);
}
return mAssociationModels;
}
private void analyzeClassFields(String className, int action) {
// 分析字段来查询表之间是否有关联
try {
Class<?> dynamicClass = Class.forName(className);
Field[] fields = dynamicClass.getDeclaredFields();
for (Field field : fields) {
if (isPrivateAndNonPrimitive(field)) {
oneToAnyConditions(className, field, action);
manyToAnyConditions(className, field, action);
}
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
throw new DatabaseGenerateException(DatabaseGenerateException.CLASS_NOT_FOUND + className);
}
}
处理一对一,一对多的表关联
private void oneToAnyConditions(String className, Field field, int action) throws ClassNotFoundException {
Class<?> fieldTypeClass = field.getType();
// If the mapping list contains the class name
// defined in one class.
if (LitePalAttr.getInstance().getClassNames().contains(fieldTypeClass.getName())) {
Class<?> reverseDynamicClass = Class.forName(fieldTypeClass.getName());
Field[] reverseFields = reverseDynamicClass.getDeclaredFields();
// Look up if there's a reverse association
// definition in the reverse class.
boolean reverseAssociations = false;
// Begin to check the fields of the defined
// class.
for (int i = 0; i < reverseFields.length; i++) {
Field reverseField = reverseFields[i];
if (!Modifier.isStatic(reverseField.getModifiers())) {
Class<?> reverseFieldTypeClass = reverseField.getType();
// If there's the from class name in the
// defined class, they are one2one bidirectional
// associations.
if (className.equals(reverseFieldTypeClass.getName())) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, fieldTypeClass.getName(),
fieldTypeClass.getName(), Const.Model.ONE_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, fieldTypeClass.getName(),
fieldTypeClass.getName(), field, reverseField, Const.Model.ONE_TO_ONE);
}
reverseAssociations = true;
}
// If there's the from class Set or List in
// the defined class, they are many2one bidirectional
// associations.
else if (isCollection(reverseFieldTypeClass)) {
String genericTypeName = getGenericTypeName(reverseField);
if (className.equals(genericTypeName)) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, fieldTypeClass.getName(),
className, Const.Model.MANY_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, fieldTypeClass.getName(),
className, field, reverseField, Const.Model.MANY_TO_ONE);
}
reverseAssociations = true;
}
}
}
}
// If there's no from class in the defined class, they are
// one2one unidirectional associations.
if (!reverseAssociations) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, fieldTypeClass.getName(),
fieldTypeClass.getName(), Const.Model.ONE_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, fieldTypeClass.getName(),
fieldTypeClass.getName(), field, null, Const.Model.ONE_TO_ONE);
}
}
}
}
处理多对多的表关联
private void manyToAnyConditions(String className, Field field, int action) throws ClassNotFoundException {
if (isCollection(field.getType())) {
String genericTypeName = getGenericTypeName(field);
// If the mapping list contains the genericTypeName, begin to check
// this genericTypeName class.
if (LitePalAttr.getInstance().getClassNames().contains(genericTypeName)) {
Class<?> reverseDynamicClass = Class.forName(genericTypeName);
Field[] reverseFields = reverseDynamicClass.getDeclaredFields();
// Look up if there's a reverse association
// definition in the reverse class.
boolean reverseAssociations = false;
for (int i = 0; i < reverseFields.length; i++) {
Field reverseField = reverseFields[i];
// Only map private fields
if (!Modifier.isStatic(reverseField.getModifiers())) {
Class<?> reverseFieldTypeClass = reverseField.getType();
// If there's a from class name defined in the reverse
// class, they are many2one bidirectional
// associations.
if (className.equals(reverseFieldTypeClass.getName())) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, genericTypeName,
genericTypeName, Const.Model.MANY_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, genericTypeName, genericTypeName,
field, reverseField, Const.Model.MANY_TO_ONE);
}
reverseAssociations = true;
}
// If there's a List or Set contains from class name
// defined in the reverse class, they are many2many
// association.
else if (isCollection(reverseFieldTypeClass)) {
String reverseGenericTypeName = getGenericTypeName(reverseField);
if (className.equals(reverseGenericTypeName)) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, genericTypeName, null,
Const.Model.MANY_TO_MANY);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, genericTypeName, null, field,
reverseField, Const.Model.MANY_TO_MANY);
}
reverseAssociations = true;
}
}
 
}
}
// If there's no from class in the defined class, they
// are many2one unidirectional associations.
if (!reverseAssociations) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, genericTypeName,
genericTypeName, Const.Model.MANY_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, genericTypeName, genericTypeName,
field, null, Const.Model.MANY_TO_ONE);
}
}
} else if(BaseUtility.isGenericTypeSupported(genericTypeName) && action == GET_ASSOCIATIONS_ACTION) {
Column annotation = field.getAnnotation(Column.class);
if (annotation != null && annotation.ignore()) {
return;
}
GenericModel genericModel = new GenericModel();
genericModel.setTableName(DBUtility.getGenericTableName(className, field.getName()));
genericModel.setValueColumnName(DBUtility.convertToValidColumnName(field.getName()));
genericModel.setValueColumnType(getColumnType(genericTypeName));
genericModel.setValueIdColumnName(DBUtility.getGenericValueIdColumnName(className));
mGenericModels.add(genericModel);
}
}
}
分析表关联关系,如果是一对一,一对多的关联,则在多的一方加入外键;如果是多对多的关联则创建中间表
private void addAssociations(Collection<AssociationsModel> associatedModels, SQLiteDatabase db,
boolean force) {
for (AssociationsModel associationModel : associatedModels) {
if (Const.Model.MANY_TO_ONE == associationModel.getAssociationType()
|| Const.Model.ONE_TO_ONE == associationModel.getAssociationType()) {
addForeignKeyColumn(associationModel.getTableName(),
associationModel.getAssociatedTableName(),
associationModel.getTableHoldsForeignKey(), db);
} else if (Const.Model.MANY_TO_MANY == associationModel.getAssociationType()) {
createIntermediateTable(associationModel.getTableName(),
associationModel.getAssociatedTableName(), db, force);
}
}
for (GenericModel genericModel : getGenericModels()) {
createGenericTable(genericModel, db, force);
}
}

相关文章


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章