Collect one of the topics of NHIBERNATE Board

xiaoxiao2021-03-06  30

http://www.narchitecture.net/articles/wwlpia.aspx

Introduction to the main interfaces in the two NHB

ISESSIONISESSESSION is the main interface for users, mainly for operational operations, data loading, etc., supports database transactions, hidden complex implementation details of NHB, and ISESSIONFACTORY is created by ISessionFactory.

ISessionFactoryiseFactory is the core class within NHB, which is maintained to a persistent mechanism (database) connection and manages them, while saving all persistent object mappings. ISessionFactory is created by Configuration because it is very large if you create an ISessionFactory (you need to load mapping information), so this object typically uses the Singleton mode.

ItrarsActionITransaction is a NHB transaction interface, which is just a simple packaged database transaction. The transaction must be started by ISession.

ICRITERIAICRITERIA is an Expression data load interface, which is a relationship expression combination that generates the WHERE section of the SQL statement, and users need to indirectly call it over ISession.

IQueryiQuery is an HQL data load interface. HQL (Hibernate Query Language) is an NHB-oriented object-oriented data query language, which is similar to the database's SQL, but the function is more powerful! Like ICRITERIA, you also need to connect to indirectly via iSession.

Three-in-one operation 1. Session and session factories should be taken for persistence, you must first get iSession and ISessionFactory, we use a sessions class to encapsulate them, the properties and methods of the sessions class are static, it has a Factory property, with To return to ISessionFactory, there is a getSession method for obtaining a new iSession.

The test class code is as follows: [TestFixTure] Public class sessionsfixture {public void sessionsFixTure () {} [test] // can get the NHB session factory. Public void factorytest () {iSessionFactory sf = sessions.factory; ask, "Get sessionFactory Fail!");} [TEST] // The test can get NHB session. Public void getsessionTest () {iSession S = sessions.getations (); assert.isnotn (s, "get session fail!");}} There is no SESSIONS class yet, will not be compiled! Let's implement the sessions class.

Public class sessions {private static readonly object (); private static iSessionFactory_factory;

Public static sessions () {`}

Public static ISessionFactory Factory {get {if (_factory == null) {lock (lockObj) {if (_factory == null) {Cfg.Configuration cfg = new Cfg.Configuration (); cfg.AddAssembly (Assembly.GetExecutingAssembly ()) ; _Factory = cfg.buildsessionFactory ();}} // endsession ()}}}}}}}}} public static iSession getsession () {return factory.opensesis ();}} OK, now compiling, start NUNIT and select Generate Document NHibernateTest.exe, run test. We got the red strip, an error! It has not yet been added to NHibernate configuration information (when using NHibernate, you need to add NHibernate configuration information in the project's configuration file. About configuration information, as explained below). Add the following in the project's profile app.config (if you do not create one).

<" Specifies whether a SQL statement is displayed in log, for debug ->

-> Run again You can see green strips. In the code to get the session factory, I used the following code: if (_Factory == Null) {lock (lockobj) {if (_Factory == null) {// build sessionFactory code;}} // end lock} This is A typical Double Lock mode, used to generate thread secure Singletion objects.

2. Basic crud operations in many articles on NHB, including NHB tapes, business objects are only available as a data entity, it doesn't have any action! This is a typical approach in Java. And I hope that our business objects can complete the basic create / retrial / update / delete, ie CRUD operations, in the Rosemer business object, the customer (Customer business object, first create a test case, [ Testfixture] public class customerfixture {public customerfixture () {}

[TEST] // Test the CRUD operation of the Customer object. Public void testcrud () {Customer C = New Customer (); c.companyname = "company name"; c.contactname = "contact name"; c.address = "address"; c.create (); // Test Create .

Customer C2 = New Customer (C.Customerid); // Test Retrieve. Assert.Arequal (C2.CompanyName, "Company Name", "Save CompanyName Fail!");

C2.CompanyName = "Update name"; c2.update (); // test update.

Customer C3 = New Customer (C.Customerid) Assert.Arequal (C3.CompanyName, "Update Name", "Update CompanyName Fail!");

C3.delete (); // Test delete.}

Next, create a Customer business class,

Public Class Customer: BizObject {public customer () {} public customer (String existingID): Base (existingid) {}

#Region Persistent Properties.

private string _customerId = string.Empty; private string _companyName = string.Empty; private string _contactName = string.Empty; private string _contactTitle = string.Empty; private string _address = string.Empty; private string _city = string.Empty; private string _region = string.Empty; private string _postalCode = string.Empty; private string _country = string.Empty; private string _phone = string.Empty; private string _fax = string.Empty; public string CustomerId {get {return _customerId;} set { _customerId = value;}} public string CompanyName {get {return _companyName;} set {_companyName = value;}} public string ContactName {get {return _contactName;} set {_contactName = value;}} public string ContactTitle {get {return _contactTitle } Set {_contacttitle = value;}} public string address {get {return _address;} set {_address = value;}} public string city {Get {Return _city;} set {_city = value;}} public string Region {get {return _region;} set {_region = value;}} public string PostalCode {get {return _postalCode;} set {_postalCode = value;}} public string Country {get {return _country;} set {_country = value;}} public string Phone {get {return _phone;} set {_phone = value;}} public string Fax {get {return _fax;} set {_fax = value }}

In the Customer class, the CRUD operation is not implemented. These operations are implemented in the business object base class BizObject, the code is as follows: public class bizObject {public bizObject () {}

public BizObject (object existingId) {ObjectBroker.Load (this, existingId);} public virtual void Create () {ObjectBroker.Create (this);} public virtual void Update () {ObjectBroker.Update (this);} public virtual void DELETE () {ObjectBroker.delete (this);}}} bizObject is simple to forward data operations to the ObjectBroker class, where the purpose is to reduce the coupling between the business layer and NHB to facilitate the transplant between the persistence. Public class ObjectBroker {private objectBroker () {}

Public Static Void Load (Object Obj, Object ID) {iSession S = sessions.getations (); try or {s.close ();} finally {s.close ();}}

Public static void create (object obj) {iSession s = sessions.getations (); itrarsaction trans = null; try {trans = s.begintransaction (); s.save (obj); trans.Commit ();} finally {s .Close ();}}}

Public static void update (object obj) {iSession s = sessions.getations (); itrarsaction trans = null; try {trans = s.begintransaction (); s.Update (obj); trans.Commit ();} finally {s .Close ();}}}

Public static void delete (object obj) {iSession S = sessions.getations (); itrarsaction trans = null; try {trans = s.begintransaction (); s.delete (obj); trans.Commit ();} finally {s .Close ();}}} ObjectBroker has the necessary package for iSession. With ISession, you can simply complete the CRUD operation of the object.

Compile and run the test, CustomerFixture of TestCRUD still can not operate by exception information is:! NHibernateTest.Test.CustomerFixture.TestCRUD: NHibernate.ADOException: Could not save object ----> NHibernate.MappingException: No persisters for: NHibernateTest.Business. Customer is obvious because we have not written mapping files for the Customer object, and the NHB cannot operate on the Customer object.

The content of the Customer object mapping file is as follows: < Property name = "region" column = "region" type = "string" /> This mapping file is more simple in NHB.

Class's Name Specifies the full name of the business object and its assembly, Table specifies the name of the data table; ID is used to specify an object identifier (the primary key in the data table) and the usual way, the commonly used method Identity and assignment (Identity) and assigned, here you use assigned, you need to pay attention to the Unsaved-value property, which specifies the ID value when the object is not persisted, mainly for SaveorUpdate operation; Property is used to specify other mapping Data column; in ID and property, name specify the name of the attribute name, the name of the column specifies the data column, the type specifies the attribute type, note the type here is the type in NHB, not the data type in the .NET or database. In addition, the object mapping file name is named "Object Name .hbm.xml" specification, and finally change the operation to "embedded resources in the properties of the mapping file." Now recompilated the program and run the test, you can see the green strip!

Because the Product object will be used multiple times in the later case, create it here as the same steps as Customer. // Product unit test [TestFixTure] public class productfixture {public productFixture () {}

[TEST] // Test the CRUD operation of the Product object. Public void testcrud () {product p = new product (); p.ProductName = "test"; p.quantityperunit = "1 box 10"; p.Unitprice = 10.5m; p.create ();

Product P2 = New Product (p.ProductID); p2.Unitprice = 15.8m; p2.Update ();

Product P3 = New Product (p.ProductID); Assert.Arequal (P3.Unitprice, 15.8M, "Update Fail!");

P3.delete ();}}

// Product Object PUBLIC CLASS PRODUCT: BIZOBJECT {public product (): base () {} public product (int existing): base (existingid) {}

#Region Persistent Properties

Private int _ProductId = 0; private string _productname = string.empty; private int _supplierid = 0; // should be reconstructed using MANY-TO-ONE. Private int _categoryId = 0; // should be reconstructed using MANY-TO-ONE. private string _quantityPerUnit = string.Empty; private decimal _unitPrice = 0; private int _unitsInStock = 0; private int _unitsOnOrder = 0; private int _reorderLevel = 0; private bool _discontinued = false;

public int ProductId {get {return _productId;} set {_productId = value;}} public string ProductName {get {return _productName;} set {_productName = value;}} public int SupplierId {get {return _supplierId;} set {_supplierId = value;}} public int CategoryId {get {return _categoryId;} set {_categoryId = value;}} public string QuantityPerUnit {get {return _quantityPerUnit;} set {_quantityPerUnit = value;}} public decimal UnitPrice {get {return _unitPrice;} set {_unitPrice = value;}} public int UnitsInStock {get {return _unitsInStock;} set {_unitsInStock = value;}} public int UnitsOnOrder {get {return _unitsOnOrder;} set {_unitsOnOrder = value;}} public int ReorderLevel {get { Return_reorderlevel;} set {_reorderlevel = value;}} public bool discontinued {get {return_discontinued;} set {_discontinue D = Value;}} #endregion}

// Map file Compile and run the test, check the error until the unit test is passed. Note: Because in the database, the Products table with the categories table, the Supplier table has foreign key constraints, and must first remove these two constraints, the Product test case can pass, then we add these two constraints.

Now we have mastered the basic crud operation of NHB, and the whole process should be said to be relatively simple. Oh, no longer need to use objects such as Connection, DataAdapter, DataSet / DataReader, continue learning more complex mapping relationships in NHB. 3. One-to-one one-to-one is a common data model. It has two situations: one is primarykey association; the other is a ForeignKey association, when using a healthy To ensure its uniqueness. In the case of a primary key, there must be a primary key to be based on a primary key. NHB is to handle this situation in a special way, pay attention to the two master names must be the same name, and the exogenation association needs to define a property-refection in the one-to-one configuration, this property is currently version Not implemented in NHB. In Rossil business applications, do not need to use one-to-one mapping, here do not explain it, please refer to the article on my website, please refer to the article on my website.

4. Many-to-oneMany-to-one is a multi-to-one data model. It specifies that the MANY does not exist independently. I personally think that Many-to-One is the most useful in NHB to ensure data validity. One mapping that is written to the data table by controlling orphan records that can effectively use the MANY-TO-ONE. In Ross Wen Data, Product (product) and Category are multi-to-one relationship. Let's handle this mapping relationship, first let Category enable basic CRUD operations, steps, with only test cases, classes, and mapping files to be created in the way. [TextFixTure] Public class categoryFixTure {public categoryFixTure () {} [test] // Test the basic Crud operation. Public void textcrud () {category c = new category (); c.categoryName = "category1"; c.description = "category1"; c.create ();

Category C2 = New Category (c.categoryId); c2.categoryName = "test update"; c2.update ();

Category C3 = New Category (c.categoryID); Assert.Areequal (C3.CategoryName, "Test Updated", "Update Fail!"); C3.delete ();}} After the test case, the test is modified by the product. Each part. The Product test case is modified as follows: [TEST] // Test the CRUD operation of the Product object. Public void testcrud () {category c = null; try {c.categoryName = "test"; c.create ();

Product P = new product (); p.ProductName = "test"; p.quantityperunit = "1 box 10"; p.Unitprice = 10.5m; p.category = C; p.create ();

/ / For the provincial space, slightly ... (not deleted!)} Finally {if (c! = Null && c.categoryid> 0) c. Delete ();}} Product class makes the following modification: 1. Delete the categoryID field and the categoryId property; 2. Add the following code: public category category;} set {_category = value;}} private category _category; product mapping file is made as follows: here A MANY-TO-ONE tab is used to specify object information that is associated with one side of the ONE. Name Specifies the name of the one party in the object; Column specifies the name of the map column; unique specifies the one party; class specifies the full name of the one-class class, including the assembly name;

Re-compile the program, run the test case, see the green strip? Not going to remove the error according to the exception! I have seen the green strip. :)

Disclaimer: Because too many Many-to-One make the latter test code become extremely large (creating a class when creating an object), in the following code, I assume that the Product object is not to implement any MANY-TO -one mapped. If you are not afraid of trouble, please modify the test case after yourself.

5. One-to-Many is also a common data model that can be seen everywhere in the database designed in paradigm. This model can be dealt with through One-to-Many in NHB, while NHB also provides a cascaded update and deletion of functionality to ensure data integrity. In the Russen Trade Case, Customer and Order (orders), Order and OrderItem (order item) are a couple of relationships, it is worth noting that all one-to-many relationship should be implemented in NHB, depending on The actual demand situation, unnecessary uses One-to-MANY mapping only reduces the performance of NHB.

Let's first complete the CRUD operation separately, to create test cases and classes to create test cases and classes to process Customer methods above.

[TestFixTure] Public class ORDERFIXTURE {public orderfixture () {} [test] // Test the CRUD operation of the ORDER object. Public void testcrud () {ORDER O = New ORDER (); o.customerid = 1; o.employeeid = 1; o.ShippedDate = new datetime (2005, 3, 5); o.shipvia = 1; o.freight = 20.5m; o.shipname = "test name"; o.shipaddress = "test address"; o.create (); ORDER O2 = New Order (O.Reight = 21.5m; o2.shipaddress = " Update address "; o2.Update ();

ORDER O3 = New Order (O.orderid); Assert.Areequal (O3.Freight, 21.5m, "Update Order Fail!"); Assert.Areequal (O3.ShiPaddress, "Update Address", "Update Order Fail!") ;

O3.Delete ();} [TEST] // Test the CRUD operation of the ORDERITEM object. Public void testItemcrud () {ORDERITEM ITEM = New ORDERITEM (); item.ProductId = 1; item.productId = 1; item.Unitprice = 10.5m; item.quantity = 12; item.discount = 1; item.create () ;

ORDERITEM ITEM2 = New ORDERITEM (Item.ItemID); item2.quantity = 13; item2.update ();

ORDERITEM ITEM3 = New ORDERITEM (Item.ItemID); Assert.Areequal (item3.quantity, 13, "update OrderItem Fail!");

Item3.delete ();}} // ORDERPUBLIC Class Order: bizObject {public order (): base () {} public order (int existing): base (existing) {}

#Region Persistent Properties

Private int _Orderid = 0; private string _customerid = string.empty; // should use Many-to-one, you need to reconstruct private int _employeeid = 0; // should use Many-to-One, need to reconstruct private datetime _orderdate = DateTime.Now; private DateTime _requiredDate; private DateTime _shippedDate; private int _shipVia = 0; // use many-to-one, need to reconstruct private Decimal _freight = 0; private string _shipName = string.Empty; private string _shipAddress = string = String.empty; private string_shippostalcode = string.empty; private string _shipCountry = string.empty;

public int OrderId {get {return _orderId;} set {_orderId = value;}} public string CustomerId {get {return _customerId;} set {_customerId = value;}} public int EmployeeId {get {return _employeeId;} set {_employeeId = value;}} public DateTime OrderDate {get {return _orderDate;} set {_orderDate = value;}} public DateTime RequiredDate {get {return _requiredDate;} set {_requiredDate = value;}} public DateTime ShippedDate {get {return _shippedDate;} set {_shippedDate = value;}} public int ShipVia {get {return _shipVia;} set {_shipVia = value;}} public Decimal Freight {get {return _freight;} set {_freight = value;}} public string ShipName {get { Return _shipname;} set {_shipname = value;}} public string shipaddress {get {return _shipaddress;} set {_shipaddress = value;}} public string shipcity { get {return _shipCity;} set {_shipCity = value;}} public string ShipRegion {get {return _shipRegion;} set {_shipRegion = value;}} public string ShipPostalCode {get {return _shipPostalCode;} set {_shipPostalCode = value;}} Public string shipcountry {get {return _shipCountry;} set {_shipcountry = value;}}

#ENDREGON} // Order mapping file

// ORDERITEMPUBLIC CLASS ORDERITEM: BIZOBJECT {public OrderItem (): base () { } Public orderitem (int existing): base (existingid) {}

#Region Persistent Properties

Private int _itemid = 0; private int _OrderId = 0; //man-to-one, need to be reconstructed. private int _productId = 0; //many-to-one, need to be reconstructed. Private decimal _Unitprice = 0; private INT _quantity = 0; private double _discount = 0.0;

public int ItemId {get {return _itemId;} set {_itemId = value;}} public int OrderId {get {return _orderId;} set {_orderId = value;}} public int ProductId {get {return _productId;} set {_productId = value;}} public decimal UnitPrice {get {return _unitPrice;} set {_unitPrice = value;}} public int Quantity {get {return _quantity;} set {_quantity = value;}} public double Discount {get {return _discount;} Set {_discount = value;}}

#ENDREGON} // ORDERITEM mapping file <μD> < property name = "UnitPrice" column = "unitPrice" type = "Decimal" /> Because of the design reasons (the business object must be single-minded), we join an itemid field to ORDERDetails, which is a self-incremeric Jian, instead of the original Joint Jian Jian. Compile and run the test, check the error until the unit test is all passed. Note that the following modifications should be made in the database, the test case can pass 1. ORDERS tables with the Customers table, the Employess table, and the shippers table have foreign key constraints, you must temporarily delete them, then we add these three constraints; 2. The ORDER DETAILS is renamed ORDERDETAILS, and the space in the table name will result in NHB unable to resolve; 3. ORDERDETAILS Table With the Orders Table, the Products form has an outjural constraint, you must temporarily delete them, and we will add these constraints.

Now start reconstructing ORDERITEM test cases and objects, mainly to join the MANY-TO-ONE mapping.

First modify TestItemcrud as follows: [TEST] // Test the CRUD operation of the ORDERITEM object. Public void testItemcrud () {Order o = null; product p = null; try {order o = new order (); o.customerid = "aa001"; o.Employeeid = 1; o.create (); product P = New P.ProductName = "test"; p.Unitprice = 11.1m; p.create ();

ORDERITEM ITEM (); // item.orderid = 1; item.order = o; // item.productId = 1; item.product = P; item.Unitprice = 10.5m; item.quantity = 12; item .Discount = 1; item.create (); OrderItem item2 = new orderitem (item.ItemID); item2.quantity = 13; item2.update ();

ORDERITEM ITEM3 = New ORDERITEM (Item.ItemID); Assert.Areequal (item3.quantity, 13, "update OrderItem Fail!");

Item3.delete (); finally {if (o! = null && o.DERID> 0) o.delete (); if (p! = null && p.ProductID> 0) p.delete ();}}

Next, modify the ORDERITEM object, the change is as follows:

// private int _OrderID = 0; //man-to-one, need to be reconstructed .private order order; // private int _productid = 0; // many-to-one, need to reconstruct .private product products; delete ORDERID And ProductID attributes and add the following properties: public order order {get {return _order;} set {_order = value;}} public product product {get {r _product;} set {_product = value;}}

Compile the project to make sure it can pass, if there is an error, check if there is a spelling error.

Finally modify the mapping file of the ORDERITEM object, the change is as follows:

Press the instructions in the MANY-TO-ONE section to set MANY- To-one association. Re-generate the project to make the resource compilation process of the change in the process, run the TestItemcrud test case, then you should get a green strip, if it is a red bar, please check according to the error message.

Next, reconstruct the ORDER test case and object. Add a TestOrdRITEM to include: [test] public void testORDERDERITEM () {Product P = null; product p2 = null; try {p = new product (); p.ProductName = "test"; p.Unitprice = 11.1m; p.create (); p2 = new product (); p2.ProductName = "test2"; p2.Unitprice = 12.2m; p2.create ();

Order o = new order (); o.customerid = "aa001"; o.Employeeid = 1; o.create ();

ORDERITEM ITEM = New OrderItem (); item.product = p; item.Unitprice = 10; item.quantity = 5;

ORDERITEM ITEM2 = New ORDERITEM (); item2.product = p2; item2.Unitprice = 11; item2.quantity = 4;

O.Additem (item); o.additem (item2); o.create ();

ORDER O2 = New Order (O.Orderid); Assert.Inotnull (O2.Items, "Add Item Fail!"); Assert.Areequal (O2.Items.count, 2, "Add Item Fail!");

IENUMERATOR E = O2.Items.GeteNumerator (); E.MOVENEXT (); ORDERITEM ITEM3 = E.CURRENT AS ORDERITEM; O2.RemoveItem (Item3); O2.Update (); Order O3 = New Order (O.OrderID); Assert.Areequal (O3.Items.count, 1, "Remove Item Fail!");

O3.delete ();} finally {if (p! = null && p.ProductID> 0) P. Delete (); if (p2! = null && p2.productidID> 0) p2.delete ();}} In this test case, we encapsulate the addition and removal of ORDERITEM in the ORDER object, providing an iCollection type attribute Items for traversing OrderItem.

You can then modify the ORDER object, to add two methods and one properties, some auxiliary fields.public void address {if (_items == null) _Items = new arraylist (); item.order = this; _items.add item);} public void RemoveItem (OrderItem item) {_items.Remove (item);} public ICollection Items {return _items;} protected IList _Items {get {return _items;} set {_items = value;}} private IList _items;

In the code added above, there is a protected-modified _items property, which is used for one-to-man map, by NHB.

Finally modify the mapping file of the ORDER object, add the following one-to-man code: Here is a new tag BAG, BAG is used to collect mapping, and there is set, list, etc. in NHB, and their elements are substantially the same, but The corresponding .NET collection object is different, which will be detailed and compared to them. The BAG property is used to specify the name of the collection and the type of cascaded operation; the key element specifies the associated data column name; One-to-man specifies the full name of the MANY class, including the assembly name.

Compile the project again and run the test case, I got a diagnostic error message: NHibernateTest.test.orterfixture.testorderItem: Remove Item Fail! Expected: <2> But was: <1> From the source code, when executed When the UPDATE operation, cascaded operation does not delete the sub-objects we remove, and must be deleted! Cascade deletion just deletes the child object at the same time when deleting the parent object.

Modify the test example code code code as follows: o2.Update (); // This line does not change Item3.delete (); // Add this line code 6. Element Collection Element is a multi-to-many mapping, more The database is also a common data model, like users, groups, users and permissions, and more. Multi-to-many relationships need to be implemented through an intermediate table, ELEMENT is to read the value of a column in this intermediate table. In Rosem Business Applications, Employee and Territory are multi-to-many relationships, which are associated by the Employeeterritories table. For the code of the Employee and Territory objects, test cases, and mapping files, please refer to the above method, this is not listed here, and only the part of the test ELEMENT mapping is listed below. [TestFixTure] public class EmployeeFixTure () {// Other test .... [test] public territoryElementTest () {Employee E = new EMPLOYEEEEEEEEEEEEEEE (); E.FirstName = "first"; e.lastname = "last"; E .Addterritory (1000); E.Addterritory (1001); E.CREATE ();

Employee E2 = New Employee (E.employeeID); Assert.Inotnull (E2.Territories, "Add Territory Fail!"); Assert.Areequal (E2.Territories.count, 2, "Add Territory Fail!");

E2.Removeterritory (1000); E2.UPDATE ();

Employee E3 = New Employee (E.employeeid); Assert.Areequal (E3.Territories.count, 1, "Remove Territory Fail!"); E3.Delete ();}} In the above code, we add two Employee Methods and an attribute, which is similar to the processing method described in One-to-Many section. In the Employee class, to add the following code: public class Employee {// other fields, properties, method ... public void AddTerritory (int territoryId) {if (_territory == null) _territory = new ArrayList (); _territory.Add (territoryId);} public void RemoveTerritory (int territoryId) {_territory.Remove (teritoryId);} public ICollection Territories {get {return _territory;}} protected IList _Territories {get {return _territories;} set {_territories = value;}} }

Finally modify the mapping file of the Employee object, add the following: In the BAG tag, add a Table property that specifies a multi-to-many intermediate table. In the ELEMENT element, specify the column name to read and its type. Four data loading

EXPRESSION

Expression Data loading is implemented by the ICRITERIA interface, which cannot be directly constructed in the program, which must be obtained by iSession.createcriteria (Type). ICRITERIA is primarily stored in a set of Expression objects and a set of ORDER objects. When calling LIST execution queries, ICRITERIA combines the Expression object and the Order object to generate query statements inside the NHB, and then read it with DataLoader. Meet the record.

Some common methods in the iCriteria interface are listed below:

Add: EXPRESSION objects, this method can call multiple conditions multiple times; addorder: Add to the sorted field (Order object); List: Execute the query, return the object collection that meets the condition. SetMaxResults: Set the maximum number of results returned, available for paging; setFirstResult: Set the position returned by the first object, available for paging;

With the SetMaxResults and SetFirstResult methods, you can get the records of the specified range segment, which is equivalent to paging,! ! ! To explain, for the SQL Server database, it is used to implement the DataReader pointer to the firstResult position, then read the MaxResults record, and the performance is difficult to ensure the performance of the data is very large (more than 10W). .

All expression objects are inherited the Expression class, which is an abstract class, and is also a factory (Factory Method mode), which is used to create a derived Expression object, which hides the details of the derived class. (I have learned it!)

The following is listed in Several commonly used Expression objects:

EQEXPRESSION: The expression of equal judgment, is equivalent to PropertyName = Value, made by Expression.eq; GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: GTEXPRESSION: Equivalent to PropertyName> VALUE, made by Expression.gt; LIKEEXPIPRESSION: Similar judgment expression, equivalent PropertyName Like Value, made by Expression.like; AndExpression: Operation for two expressions, equivalent to expr1 and expens, gets from Expression.and; OREXPRESSION: OR operation of two expressions, equivalent to expr1 or expr2, Get from Expression.or; more Expression objects Please refer to the related document or source code.

The ORDER object is used to provide sorting information to the ICRITERIA interface. This class provides two static methods, which are ASC and DESC. As the name refer to create an orderless and descending Order object, for example, a ORDER object descended by update date (Updated) Using Order.Desc ("Updated"). Customer below to load data as an example will be described using Expression: test code follows, [TestFixture] public class CustomerSystemFixture {public CustomerSystemFixture () {} [Test] public void LoadByNameTest () {Expression expr = Expression.Eq ( "CompanyName", "Company name"); ilist custs = ObjectLoader.Find (expr, typeof (customer)); // Writage assertion. "" Company name "); PagerInfo Pi = New PagerInfo (0, 5); IList Custs = ObjectLoader.Find (Expr, TypeOf (Customer), PI); // Writage assertion in accordance with the desired results.} [Test] public void LoadByNameAndAddressTest () {Expression expr = Expression.Eq ( "CompanyName", "company name"); Expression expr2 = Expression.Eq ( "address", "address"); IList custs = ObjectLoader.Find (Expression.And ( EXPR, EXPR2), TYPEOF (CUSTOMER)); // Write assertion in accordance with the expected result.} [test] public void loadBynameoraddressTest () {expression expr = expression.eq ("CompR = Expression.eq) "Company"); Expression Expr2 = Expression.eq ("Address", "address"); ilist custs = ObjectLoader.Find (Expression.or (expr, expr2), typeof (customer)); // The desired result is not written in the code.} Top code is given, and the test cases loaded by more simple expressions are given, they all get data by calling the ObjectLoader object, ObjectLoader is our own data load. It simply encapsulates the data loading function in NHB. In addition, we also encapsulate paging data in a PagerInfo class to facilitate data delivery.

// PagerInfopublic class PagerInfo {private int firstResult; // start position private int maxReuslts; // Returns the maximum number of records public PagerInfo (int firstResult, int maxResults) {this.firstResult = firstReuslt; this.maxResults = maxResults;} public int firstResult {get {return firstResult;}} public int maxResults {get {return maxResults;}}} // ObjectLoaderpublic class ObjectLoader {private ObjectLoader () {} public static IList Find (Expression expr, type type) {return Find (expr, TYPE, NULL);} public static ilist find (Expression Expr, Type Type, PAGERINFO PI) {ISESSION S = sessions.getations (); try {ibriteria c = S.createcriteria (type); if (ex! = null) c .Add (ex); if (pi! = Null) {C.SetFirstResult (Pi.FirstResult); C.SETMAXRESULTS (PI.MAXRESULTS);} return c.list ();} finally {s.close ();} }} In the Find method, first get the ICRITERIA interface by session, then add an expression, pick up Check if you need to set paging data, and finally return the listed data. 2. HQL

HQL (Hibernate Query Language) is a dedicated query language of NHB, which is fully objects! That is to say, I only need to know that the object name and the attribute name can generate HQL, so no need to pay attention to the data sheet and column, the previously speaking query will eventually convert to HQL. There are two ways to perform HQL, one is the Find method of directly using the ISESSION, and the other is to use the iQuery interface. The iQuery interface provides some additional settings, the most important thing is to page, this is similar to the Icriteria, and some are the value of setting parameters. A set of classes in NHB is specifically used to complete data loading, which correspond to different data loading, such as entity loading, criteria loading, OneTomany loading, etc.

The following is the same as an example of loading Customer data as an example: add the following test cases in the above CustomersystemFixTure class: public class customersystemFixTure {String query = "from customer"; ilist custs = ObjectLoader.Find (Query, NULL); // Write assertion.} [TEST] public void loadPagerDataSt () {string query = "from customer"; PAGERINFO PI = New PagerInfo (0, 5); ilist custs = ObjectLoader.Find (query, null, pi);} [Test] public void LoadByName2Test () {string query = "from Customer c where c.CompanyName =: CompanyName"; paramInfos.Add (new ParameterInfo ( "CompanyName", "test name", TypeFactory.GetStringType ())); IList custs = ObjectLoader.Find (query, paramInfos); // write Assertion upon the desired results set} [Test] public void LoadByNameAndAddress2Test () {string query = "from. Customer c where c.companyname =: companyName and c.address =: address "; paraminfos.add (New ParameterInfo (" CompanyName ", Test Name, TypeFacto Ry.getstringType ()); paraminfos.add (New ParameterInfo ("Address", "Test Address", TypeFactory.getstringType ()); ilist custs = ObjectLoader.Find (query, paraminfos); // According to the expected result In the above test case, we also handle the data loaded with the ObjectLoader's Finder, and Find has a lot of overloaded versions, which are used for data loading. There is also a parameter information of the ParameterInfo class to store the HQL statement.

// ParamInfopublic class ParamInfo {private string name; // parameter name private object value; // parameter value private IType type; // Parameter Type public ParamInfo (string name, object value, IType type) {this.name = name; this .value = value;} public string name {get {return name;}} public object value {get {return value;}} public itype type {get {return type;}}} // Class Paraminfo was added to the following method ObjectLoader class: public class ObjectLoader {// .... public static IList Find (string query, ICollection paramInfos) {return Find (query, paramInfos, null);} public static IList Find (string query, ICollection paramInfos PagerInfo pi) {iSession S = sessions.getations (); try {iQuery q = s.createQuery; if (paraminfos! = Null) {ife (paraminfo info in paraminfos) {if (Info.value is iCollection) Q.SetParameterList (ICOLLECTION) IN Fo.Value, info.type); Else q.setparameter Pi.maxResults;} return}} finally {s.close ();}}} In the above Find method, create an iQuery through the HQL statement, then join the parameters, then set the paging data, and finally return The data listed.

Five affairs

Since the database is deal, the transaction is required, and the transaction can guarantee data integrity. In NHB, the ITransaction object is only simple to encapsulate only .NET's transaction objects (objects that implement the IDBTRANSAction interface).

Typical transaction processing using NHB looks like this (see iSession.CS) iSession sess = factory.opensesis (); transaction tx; try {tx = sess.begintransaction (); // do some work // .. TX.com (Exception E) {if (tx! = Null) TX.ROLLBACK (); throw e;} finally {sess.close ();} Transaction object is obtained by ISession's Begintractions, while transaction Start, if the execution is smooth, the transaction is submitted, otherwise the rollback transaction. When a business rule is implemented, this rule wants to change multiple business object status, then you need to use a transaction. The transaction guarantees that all changes are either saved, or all will not be saved!

In the Rossil business case, there is such a business rule: If the customer has an order for a product, the order quantity of the subscribed product should be added to the customer's product order, according to this business rule, create One test is for example:

[Testfixture] public class orderfixture {[test] public void ORDERTEST () {product p = new product (); p.Unitsonodract; p.create ();

ORDER O = New Order ();

ORDERITEM ITEM = New OrderItem (); item.order = O; item.Product = P; item.ordernum = 10;

Orderco.create (O);

Product P2 = New Product (p.ProductID); Assert.Areequal (p2.Unitsonorder, 30, "add to unitsonorder fail!");}}

转载请注明原文地址:https://www.9cbs.com/read-56170.html

New Post(0)