数据操作,在这里主要介绍INSERT、UPDATE、DELETE。我们在使用NHibernate的时候,如果只是查询数据,不需要改变数据库的值,那么是不需要提交或者回滚到数据库的。
一、INSERT
通过调用ISession.Save()方法,然后同步同步到数据库。
Program.cs
class Program { static void Main(string[] args) { ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); ISession session = sessionFactory.OpenSession(); PersonModel p = new PersonModel(); p.Id = 5; p.Name = "郭嘉"; session.Save(p); session.Flush(); //执行此行代码,才真正提交到数据库 Console.ReadKey(); } }
输出结果如下:
NHibernate执行了插入语句。
如果在添加的时候想知道NHibernate返回的Id以判断添加是否成功,可以这样写:
public bool Add(Ad ad) { return (int)NHibernateHelper.GetSession().Save(ad) > 0; }
二、UPDATE
通过调用ISession.Update,同步到数据库。
Program.cs
class Program { static void Main(string[] args) { ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); ISession session = sessionFactory.OpenSession(); PersonModel p = session.Get<PersonModel>(1); p.Name = p.Name + "Nhiberante修改名字!"; session.Update(p); session.Flush(); Console.ReadKey(); } }
输出如下:
不知道为什么UPDATE语句为什么不显示出来,但是数据库已经更改了。
三、SaveOrUpdate
NHibernate能够做到自动判断是应该执行INSERT还是UPDATE。这就是SaveOrUpdate()方法,当我们执行这个方法的时候,NHibernate完成如下工作:
- 检查这个对象是否已经存在Session中。
- 如果对象不在,调用Save(object)来保存。
- 如果对象存在,检查这个对象是否改变了。
- 如果对象改变,调用Update(object)来更新。
Program.cs
class Program { static void Main(string[] args) { ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); using (ISession session = sessionFactory.OpenSession()) { PersonModel p1 = session.Get<PersonModel>(1); p1.Name = p1.Name + "Nhiberante修改名字!"; session.SaveOrUpdate(p1); } using (ISession session = sessionFactory.OpenSession()) { PersonModel p2 = new PersonModel(); p2.Name = "曹仁"; session.SaveOrUpdate(p2); } Console.ReadKey(); } }
输出如下:
UPDATE语句,一样没show,不知道什么原因,另外要注意的是,如果你配置了Id由数据库生成,希望insert的数据,不要添加Id编号。否则SaveOrUpdate会报异常,有了Id,NHibernate会执行UPDATE,而数据库没有此行数据,因此报错。
四、DELETE
查出一个对象,调用ISession.Delete(),同步到数据库。
Program.cs
class Program { static void Main(string[] args) { ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); using (ISession session = sessionFactory.OpenSession()) { PersonModel p1 = session.Get<PersonModel>(1); session.Delete(p1); session.Flush(); } Console.ReadKey(); } }
数据库显示如下:
但是这种方法也有个问题,这种方法要先把这条记录查出来(SELECT),然后映射成实体,然后再把实体传回去执行删除操作(DELETE)。这样处理可能能够解决缓存与数据库同步等一系列问题。
HQL是NHibernate特有的操作语言,它能够理解,既然能理解那么就能正常处理与缓存的关系(未实测),不过跟踪了SQL语句,还是先查询后删除,唯一不同只是返回多了一个影响行数。
public int Delete(int Id) { int Count = NHibernateHelper.GetSession().Delete("from Ad ad where ad.Id = ?", Id, NHibernateUtil.Int32); NHibernateHelper.GetSession().Flush(); return Count; }
如果不使用NHibernate的缓存功能,可以考虑使用CreateSQLQuery的方式删除,在这里忽略了。