NHibernate code parsing-SqlCommand-SqlBuilder Template StringTokenizer

Source: Internet
Author: User
SqlBuilder is used to construct SQL statements for SELECT, INSERT, DELETE, and UPDATE. The class diagram is as follows:

1. SqlBaseBuilder
It mainly supports WHERE clause generation. NH may generate col1 =? Such a WHERE condition may also generate col1 =? AND col2 =? Such combination conditions (the user does not need to cyclically process the columns and attribute IType corresponding to the CollectionType, which is handled by SqlBaseBuilder ). The process for generating these WHERE condition clauses is encapsulated in SqlBaseBuilder.
2. There is no WHERE clause in the INSERT statement, so SqlInsertBuilder does not inherit from SqlBaseBuilder. SqlUpdateBuilder, SqlDeleteBuilder, and so on will all have the WHERE clause, so they all inherit from SqlBaseBuilder.
The principle of NH is that the SQL statements in the intermediate processing process are basically expressed as SqlString objects. SQL statements are generated by SqlString only before execution, therefore, the production of these SqlBuilder classes is a complete SqlString object in SQL syntax, so they all implement the ISqlStringBuilder interface. WhereBuilder is only used to construct WHERE condition clauses in other places (SqlBaseBuilder is an abstract class). Its output is not a complete SQL statement, so the ISqlStringBuilder interface is not implemented, use the WhereClause method to return the SqlString of the where Condition Clause.
3. Differences between SqlSelectBuilder and SqlSimpleSelectBuilder
SqlSelectBuilder is used to construct a slightly complex SQL statement, which may contain JOIN clauses and subqueries. SqlSimpleSelectBuilder is only used to construct simple SQL statements. Why is this? I don't think it is necessary. Is it the product of NH upgrade and expansion or the author's randomness?

SqlUpdateBuilder test code {
Configuration cfg = new Configuration ();
ISessionFactory factory = cfg. BuildSessionFactory ();
ISessionFactoryImplementor factoryImpl = (ISessionFactoryImplementor) factory;

SqlUpdateBuilder update = new SqlUpdateBuilder (factoryImpl );
Update. SetTableName ("ItemTable ");
// Test AddColumn (string columnName, object val, ILiteralType literalType)
Update. AddColumn ("TestCol", "my test", (nhib.pdf. Type. ILiteralType) NHibernateUtil. AnsiString );

// Test AddColumns (string [] columnNames, bool [] updateable, IType propertyType)
Update. AddColumns (new string [] {"Col0"}, null, NHibernateUtil. AnsiString );
Update. AddColumns (new string [] {"Col1"}, null, NHibernateUtil. Int32 );

// Test SetIdentityColumn (string [] columnNames, IType identityType)
Update. SetIdentityColumn (new string [] {"UserID"}, NHibernateUtil. Guid );

// Test AddWhereFragment (string [] columnNames, IType type, string op)
Update. AddWhereFragment (new string [] {"CreateTime"}, NHibernateUtil. DateTime, "> ");

// Test ToSqlString ()
// String SQL = update. ToSqlString (). ToString ();
SqlString sqlstring = update. ToSqlString ();

SqlStringFormatter formater = new SqlStringFormatter (ISqlParameterFormatter) (factoryImpl. ConnectionProvider. Driver ));
Sqlstring. Visit (formater );
String SQL = formater. GetFormattedText ();

String sqlExpected = "UPDATE ItemTable SET TestCol = 'my test', Col0 = @ p0, Col1 = @ p1 WHERE UserID = @ p2 AND CreateTime> @ p3 ";
Assert. AreEqual (sqlExpected, SQL, "SQL String ");
}

SqlSelectBuilder test code {
Configuration cfg = new Configuration ();
ISessionFactory factory = cfg. BuildSessionFactory ();

ISessionFactoryImplementor factoryImpl = (ISessionFactoryImplementor) factory;
SqlSelectBuilder select = new SqlSelectBuilder (factoryImpl );

Select. SetSelectClause ("pi. PlantCode, pi. ItemCode, pi. SafeStock ");
Select. SetFromClause ("PlantItem", "pi ");
Select. SetOuterJoins (
New SqlString ("inner join Plant p ON p. PlantCode = pi. PlantCode left outer join Item I ON I. ItemCode = pi. ItemCode "),
New SqlString ("I. ItemType = 'A '"));
Select. SetOrderByClause ("pi. PlantCode ASC, pi. ItemCode DESC ");
Select. SetGroupByClause ("pi. PlantCode, pi. ItemCode ");
Select. SetWhereClause ("pi", new string [] {"Status"}, NHibernateUtil. YesNo );

String SQL = select. ToSqlString (). ToString ();
String expected = "SELECT pi. plantCode, pi. itemCode, pi. safeStock FROM PlantItem pi inner join Plant p ON p. plantCode = pi. plantCode left outer join Item I ON I. itemCode = pi. itemCode WHERE I. itemType = 'A' AND pi. status =? Group by pi. PlantCode, pi. ItemCode order by pi. PlantCode ASC, pi. ItemCode DESC ";
Assert. AreEqual (sqlExpected, SQL, "SQL String ");
}

4. Util \ StringTokenizer
This function is similar to the string. Split () function. It is extended and can return the delimiter. It implements the IEnumerable interface and reads parts after splitting in enumeration mode. This class is used in the Template.
5. Template
Add a string label before the column name in the SQL statement. Replace the column Name Reference brackets (note that not two single quotes) with the column Name Reference ending symbol specified by Dialect.
Example :{
Dialect dialect = new MsSql2000Dialect ();
String whereFragment = "col1 = 'v'al' 1 'and 'C _ 1' = 1 ";
String SQL = Template. RenderWhereStringTemplate (whereFragment, dialect );
// SQL: $ PlaceHolder $. col1 = 'v 'al' 1' and $ PlaceHolder $. [c_1] = 1
WhereFragment = "select col1, col2 from itemtable as I where col1 = 'v'al' 1 'and 'C _ 1' = 1 ";
SQL = Template. RenderWhereStringTemplate (whereFragment, dialect );
// SQL: select $ PlaceHolder $. col1, $ PlaceHolder $. col2 from itemtable as I where $ PlaceHolder $. col1 = 'v 'al' 1' and $ PlaceHolder $. [c_1] = 1
}

Purpose: After a string tag is inserted, the string tag can be replaced at an appropriate position, for example, when an alias is used for the table.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.