1
问题场景
系统的数据层采用 Spring.net 框架。
项目对数据的要求
1)每一个业务表的业务信息只能注销,不能物理删除(也就是我们经常说的保存历史数据)
2)不能将表的失效信息暴露在实体类中
2 解决流程
解决的流程
Step one 通过Session中的SessionFactory 查找到业务实体类的ORM信息
在这里,我们最关注ORM信息中的有两点
1) 业务实体类 -------- 数据库中表
2) 业务实体类的主键属性 ---数据库中列信息
补充说明:
在这边我们支持类的映射信息配置的主键主要包含了三个组成方式
1 类的主键类型为复合主键且子主键为key-property
2 类的主键类型为复合主键且子键中包含了key-property 也包含了key-many-to-one
3 类的主键类型直接为property
Step Two 根据ORM信息取对应数据库中表的列对应的业务实体属性值
Step Three 将Step Two 提取出来的的信息转化成我们需要数据格式
属性 属性说明
TableName 表名
IdentifierColumnNames 主键对应数据库表中的列名
identifierValues 业务实体中的主键属性值
KeyNum 主键的列数目
Step Four 根据 step three 的信息拼装SQL语句并执行
3类的设计
类图
3.1 ClassMappingInfo 类
功能说明:存储了类和数据库表之间的NHibernate配置信息
属性
属性名 | 属性含义 | 属性数据类型 |
TableName | 表名 | String |
IdentifierColumnNames | 主键列名 | String[] |
IdentifierValues | 主键对应的对象属性值 | String[] |
ColumnLength | 主键列的数目 | Int |
3.2 ClassMappingInfoBuilder类
功能说明:
根据类和Isession来获取ClassMappingInfo
函数
public ClassMappingInfo Get(object obj, ISession session)
参数:
Obj :数据持久类
Session:NHibernate 的Session实例
返回类型 ClassMappingInfo
3.3 DeleteCommandCreater类
功能说明:
根据ClassMappingInfo 映射信息,来生成删除功能的sql语句
函数
public override string GetSqlCommand()
返回类型 string
4 核心代码说明
下面是核心函数
参数接口为 业务实体对象的类型,业务实体对象,spring.net 中的Session对象
实现的功能是:
提取业务实体对象的主键信息(包含实体中主键属性值和数据表中的主键列的信息)
1
2 /**//************************************************************
3 * this file is part of Platform Project
4 * Copyright (C)YuChuang Soft
5 *
6 * Author : xwb
7 * Mail :
8 * Create Date : 2009/1/21
9 * Summary : 负责根据类和Nhibernate的Session信息 来获取类的Mapping配置信息
10 *
11 *
12 * *************************************************************/
13
14 public class ClassMappingInfoBuilder
15 {
16
17 /**//// <summary>
18 /// 在获取类的映射信息时主键主要包含了三个组成方式
19 /// 1 类的主键类型为复合主键且子主键为key-property
20 /// 2 类的主键类型为复合主键且子键中包含了key-property 也包含了key-many-to-one
21 /// 3 类的主键类型直接为property
22 /// </summary>
23 /// <param name="obj"></param>
24 /// <param name="session"></param>
25 /// <returns></returns>
26
27 public ClassMappingInfo Get(Type T, object obj, ISession session)
28 {
29 //获取映射信息
30 ClassMappingInfo classMappingInfo = new ClassMappingInfo();
31
32 //--取类对应的表名---
33
34 //注意Nhibernate对我们的持久类封装了一道
35
36 IClassMetadata classMeta = session.SessionFactory.GetClassMetadata(T);
37 classMappingInfo.TableName = ((SingleTableEntityPersister)classMeta).TableName;
38
39 NHibernate.Type.IType IdentifierType = classMeta.IdentifierType;
40 string IdentifierPropertyName= classMeta.IdentifierPropertyName;
41
42
43 object IdentifierInstance = T.GetProperty(IdentifierPropertyName).GetValue(obj,null);
44
45
46 //-----取类的主键信息---//
47
48 //主键 为复合主键
49 Type Type1 = typeof(NHibernate.Type.ComponentType);
50 Type Type2 = IdentifierType.GetType();
51
52 if (Type1.ToString() == Type2.ToString())//为复合主键
53 {
54 // 取每个主键属性。
55 NHibernate.Type.ComponentType currentType = ((NHibernate.Type.ComponentType)IdentifierType);
56 string[] ColumnNames = new string[currentType.PropertyNames.Length];
57 string[] AttributeValues = new string[currentType.PropertyNames.Length];
58
59 for (int index = 0; index < currentType.PropertyNames.Length; index++)
60 {
61
62 NHibernate.Type.IType subType = currentType.Subtypes[index];
63 ColumnNames[index]=((SingleTableEntityPersister)classMeta).IdentifierColumnNames[index];
64 if (subType.IsEntityType)//注意主键是ManyToOne 的方式
65 {
66 object subidentifierobj= IdentifierInstance.GetType().GetProperty(currentType.PropertyNames[index]).GetValue(IdentifierInstance, null);
67
68 //递归获取对应的主键子类的Mapping信息
69 ClassMappingInfo subclassMappinginfo = Get(subType.ReturnedClass, subidentifierobj, session);
70 AttributeValues[index] = subclassMappinginfo.identifierValues[0];
71
72 }
73 else
74 {
75 AttributeValues[index] =IdentifierInstance.GetType().GetProperty(currentType.PropertyNames[index]).GetValue(IdentifierInstance, null).ToString();
76 }
77
78 }
79 classMappingInfo.IdentifierColumnNames = ColumnNames;
80 classMappingInfo.identifierValues = AttributeValues;
81 }
82 else //为单一主键
83 {
84 string[] ColumnNames = new string[1];
85 string[] AttributeValues = new string[1];
86 ColumnNames[0] = ((SingleTableEntityPersister)classMeta).IdentifierColumnNames[0];
87 AttributeValues[0] = IdentifierInstance.ToString();
88 classMappingInfo.IdentifierColumnNames = ColumnNames;
89 classMappingInfo.identifierValues = AttributeValues;
90 }
91
92 return classMappingInfo;
93 }
94 }
95}