基于特性和反射机制的通用持久化类的引入
首先声明下:第一次把文章放在首页。如果觉得不适合的勿怪。
主要的思路是:通过特性和反射机制动态生成通用的sql语句,实现的是对sql语句的分装。当然hibernate等框架也有类似的功能。但是我这里的思路是在不需要外部xml配置文件。比较适合中小项目,我在这里以插入为例子说明下思路。其他的大家可以去拓展。
直接上代码吧:
1、自定义特性类:
自定义特性
1 using System;
2
3 [AttributeUsage(AttributeTargets.All,
4 AllowMultiple=true,
5 Inherited=false)]
6 public class TestAttribute:System.Attribute//继承系统特性类
7 {
8 private string _id;//主键标识
9 private string _table;//表名标识
10 public TestAttribute()
11 {
12
13 }
14 public TestAttribute(string id,string table)
15 {
16 _id = id;
17 _table = table;
18 }
19 public string ID//属性
20 {
21 get
22 {
23 return _id;
24 }
25 set
26 {
27 _id = value;
28 }
29 }
30 public string Table//属性
31 {
32 get
33 {
34 return _table;
35 }
36 set
37 {
38 _table = value;
39 }
40 }
41 }
42
1 using System;
2
3 [AttributeUsage(AttributeTargets.All,
4 AllowMultiple=true,
5 Inherited=false)]
6 public class TestAttribute:System.Attribute//继承系统特性类
7 {
8 private string _id;//主键标识
9 private string _table;//表名标识
10 public TestAttribute()
11 {
12
13 }
14 public TestAttribute(string id,string table)
15 {
16 _id = id;
17 _table = table;
18 }
19 public string ID//属性
20 {
21 get
22 {
23 return _id;
24 }
25 set
26 {
27 _id = value;
28 }
29 }
30 public string Table//属性
31 {
32 get
33 {
34 return _table;
35 }
36 set
37 {
38 _table = value;
39 }
40 }
41 }
42
2、实体类
实体类
1using System;
2
3[Test("bookId","t_book")]//特性
4public class Book
5{
6 private String bookId;
7 private String title;
8 private String amount;
9 public Book()
10 {
11 }
12 public Boolean ValidateInsert()//验证方法,未定义。
13 {
14 return true;
15 }
16 public string BookId//对应数据库中的BookId字段
17 {
18 get
19 {
20 return bookId;
21 }
22 set
23 {
24 bookId = value;
25 }
26 }
27 public string Title//对应数据库中的Title字段
28 {
29 get
30 {
31 return title;
32 }
33 set
34 {
35 title = value;
36 }
37 }
38 public string Amount//对应数据库中的Amount字段
39 {
40 get
41 {
42 return amount;
43 }
44 set
45 {
46 amount = value;
47 }
48 }
49}
50
1using System;
2
3[Test("bookId","t_book")]//特性
4public class Book
5{
6 private String bookId;
7 private String title;
8 private String amount;
9 public Book()
10 {
11 }
12 public Boolean ValidateInsert()//验证方法,未定义。
13 {
14 return true;
15 }
16 public string BookId//对应数据库中的BookId字段
17 {
18 get
19 {
20 return bookId;
21 }
22 set
23 {
24 bookId = value;
25 }
26 }
27 public string Title//对应数据库中的Title字段
28 {
29 get
30 {
31 return title;
32 }
33 set
34 {
35 title = value;
36 }
37 }
38 public string Amount//对应数据库中的Amount字段
39 {
40 get
41 {
42 return amount;
43 }
44 set
45 {
46 amount = value;
47 }
48 }
49}
50
3、持久类
持久类
1 using System;
2 using System.Data;
3 using System.Data.SqlClient;
4 using System.Collections;
5 using System.Collections.Generic;
6 using System.Reflection;
7 using System.Text;
8 /// <summary>
9 /// Summary description for Persister
10 /// </summary>
11 public class Persister
12 {
13 private SqlConnection connection;
14 private SqlCommand command;
15 public Persister()
16 {
17
18 }
19 public Persister(SqlConnection con)
20 {
21 connection = con;
22 }
23
24 static String GetTableName(Type beanClass)//得到表的名字
25 {
26 MemberInfo info = beanClass;
27 TestAttribute testAttribute = (TestAttribute)Attribute.GetCustomAttribute(info,
28 typeof(TestAttribute));
29 return testAttribute.Table;
30 }
31 static String GetIdName(Type beanClass)//得到主键的名字,在此为说明问题仅设置一个
32 {
33 MemberInfo info = beanClass;
34 TestAttribute testAttribute = (TestAttribute)Attribute.GetCustomAttribute(info,
35 typeof(TestAttribute));
36 return testAttribute.ID;
37 }
38 public void Insert(Object objectInstance)//插入的定义
39 {
40 StringBuilder sbSql = new StringBuilder();// 存储insert sql语句
41 ArrayList values = new ArrayList();// 保存对象的字段值的列表
42 //开始动态拼接sql语句
43 sbSql.Append("insert into ");
44 sbSql.Append(GetTableName(objectInstance.GetType()));
45 sbSql.Append(" ( ");
46 PropertyInfo[] fields = objectInstance.GetType().GetProperties();//反射得到属性
47 for (int index = 0; index < fields.Length; index++)//
48 {
49 PropertyInfo field = fields[index];
50 sbSql.Append(field.Name);
51 values.Add(field.GetValue(objectInstance,null));
52 if (index < fields.Length - 1) { sbSql.Append(","); }
53 }
54 sbSql.Append(") values('");
55 for (int i = 0; i < values.Count; i++)
56 {
57 if (i != 0)
58 {
59 sbSql.Append("'");
60 }
61 sbSql.Append(values[i]);
62 if (i != 2)
63 {
64 sbSql.Append("'");
65 }
66 if (i < values.Count - 1) { sbSql.Append(","); }
67
68 }
69 sbSql.Append("')");
70 //拼接sql语句完成
71 //执行插入
72 command = new SqlCommand(sbSql.ToString(), connection);
73 connection.Open();
74 command.ExecuteNonQuery();
75 connection.Close();
76 //结束插入
77 }
78 }
79
1 using System;
2 using System.Data;
3 using System.Data.SqlClient;
4 using System.Collections;
5 using System.Collections.Generic;
6 using System.Reflection;
7 using System.Text;
8 /// <summary>
9 /// Summary description for Persister
10 /// </summary>
11 public class Persister
12 {
13 private SqlConnection connection;
14 private SqlCommand command;
15 public Persister()
16 {
17
18 }
19 public Persister(SqlConnection con)
20 {
21 connection = con;
22 }
23
24 static String GetTableName(Type beanClass)//得到表的名字
25 {
26 MemberInfo info = beanClass;
27 TestAttribute testAttribute = (TestAttribute)Attribute.GetCustomAttribute(info,
28 typeof(TestAttribute));
29 return testAttribute.Table;
30 }
31 static String GetIdName(Type beanClass)//得到主键的名字,在此为说明问题仅设置一个
32 {
33 MemberInfo info = beanClass;
34 TestAttribute testAttribute = (TestAttribute)Attribute.GetCustomAttribute(info,
35 typeof(TestAttribute));
36 return testAttribute.ID;
37 }
38 public void Insert(Object objectInstance)//插入的定义
39 {
40 StringBuilder sbSql = new StringBuilder();// 存储insert sql语句
41 ArrayList values = new ArrayList();// 保存对象的字段值的列表
42 //开始动态拼接sql语句
43 sbSql.Append("insert into ");
44 sbSql.Append(GetTableName(objectInstance.GetType()));
45 sbSql.Append(" ( ");
46 PropertyInfo[] fields = objectInstance.GetType().GetProperties();//反射得到属性
47 for (int index = 0; index < fields.Length; index++)//
48 {
49 PropertyInfo field = fields[index];
50 sbSql.Append(field.Name);
51 values.Add(field.GetValue(objectInstance,null));
52 if (index < fields.Length - 1) { sbSql.Append(","); }
53 }
54 sbSql.Append(") values('");
55 for (int i = 0; i < values.Count; i++)
56 {
57 if (i != 0)
58 {
59 sbSql.Append("'");
60 }
61 sbSql.Append(values[i]);
62 if (i != 2)
63 {
64 sbSql.Append("'");
65 }
66 if (i < values.Count - 1) { sbSql.Append(","); }
67
68 }
69 sbSql.Append("')");
70 //拼接sql语句完成
71 //执行插入
72 command = new SqlCommand(sbSql.ToString(), connection);
73 connection.Open();
74 command.ExecuteNonQuery();
75 connection.Close();
76 //结束插入
77 }
78 }
79
4、测试代码
测试
1 Persister p = new Persister(con);//声明持久类
2 Book book = new Book();//定义对象
3 book.BookId = "KB123";
4 book.Title = "三国演义";
5 book.Amount = "12";
6 p.Insert(book);//插入
1 Persister p = new Persister(con);//声明持久类
2 Book book = new Book();//定义对象
3 book.BookId = "KB123";
4 book.Title = "三国演义";
5 book.Amount = "12";
6 p.Insert(book);//插入
5、最后说明
当然上面的例子主要说明设计思想,代码没有重构。比如插入最好参数化,对持久类的声明进行封装等等。我相信大部分人能看懂。如有问题留言讨论!最大的好处是避免了配置文件。如果有人在此基础上完成十分完整的通用的数据库操作持久类希望分享。