zoukankan      html  css  js  c++  java
  • NHibernate使用sql自定义函数&HQL使用sql自定义函数:NHibernate-自定义方言

    前提:近日使用了NHibernate的IUserType自定义类型,用于对字段进行处理(取完数据对数据处理),由于部分情况下需要使用sql语句进行查询,则用到了mysql自定义函数,使用HQL不指明自定义函数的话会报错,无法查询数据。

    NHibernate使用自定义函数配置:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using NHibernate.Dialect;
     6 using NHibernate.Dialect.Function;
     7 namespace Training.Models.Util
     8 {
     9     public class Enstr_MySqlDialect : NHibernate.Dialect.MySQLDialect
    10     {
    11         public Enstr_MySqlDialect()
    12         {
    13             //SQLFunctionTemplate函数第一个参数是函数的输出类型,varchar对应NHibernate.NHibernateUtil.String
    14             //?1代表第一个参数,?2代表第二个参数,以下函数都是只需一个参数,所以写成nc_enstr(?1)
    15 
    16            this.RegisterFunction("nc_enstr", new SQLFunctionTemplate(NHibernate.NHibernateUtil.String, "nc_enstr(?1)"));
    17            this.RegisterFunction("nc_destr", new SQLFunctionTemplate(NHibernate.NHibernateUtil.String, "nc_destr(?1)"));
    18            this.RegisterFunction("ch_enstr", new SQLFunctionTemplate(NHibernate.NHibernateUtil.String, "ch_enstr(?1)"));
    19            this.RegisterFunction("ch_destr", new SQLFunctionTemplate(NHibernate.NHibernateUtil.String, "ch_destr(?1)"));
    20         }
    21     }
    22 }
    自定义方言Dialect:继承MySQLDialect
    <?xml version='1.0' encoding='utf-8'?>
    <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
      <session-factory name="NHibernateTest">
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
        <property name="connection.connection_string">Server=127.0.0.1;Database=test1;User ID=root;Password=123456</property>
        <property name="dialect">TestMysqlDialect.Util.Enstr_MySqlDialect,TestMysqlDialect</property>
      </session-factory>
    </hibernate-configuration>
    View Code

    其中<property name="dialect">TestMysqlDialect.Util.Enstr_MySqlDialect,TestMysqlDialect</property>

    内容为自定义方言,内容由逗号,分隔,格式为:自定义方言,程序集名称;(NHibernate配置填写自定义类型的时候基本都是这个规范“自定义类型,程序集名称”)

    使用NHibernate内置方言不需要程序集名称;参考:https://www.cnblogs.com/kissdodog/archive/2013/02/21/2919873.html

    例:<property name="dialect">NHibernate.Dialect.MySQLDialect</property>

     至此,配置自定义方言就配置好了,HQL中就可以使用自定义函数了。

    HQL使用自定义函数

     public IList<tableModel> getTableModelList(tableModel model)
            {
                ISession iSession = null;
                try
                {
                    iSession = openSession();
                    string sql = "select ta from tableModel as ta where ta.email like concat('%',nc_enstr('" + model.email+ "'),'%')";
                    IQuery qry = iSession.CreateQuery(sql);
                    
                    IList<tableModel> list = qry.List<tableModel>();
                    return list;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    this.closeSession(iSession);
                }
            }
    HQL使用自定义函数

    其中nc_enstr(str)为数据库函数,tableModel 为要表的映射model,因为我这是个like,使用数据库函数会降低查询效率,所以改了一版将参数进行处理后再like;

    将sql改成:string sql = "select ta from tableModel as ta where ta.email like '%" + new CharEncar.MEncry().SenMEncry(model.email, CharEncar.MEncry.encry_type.type_nc) + "%'";

    (个人备忘1:使用了自定义数据类型的处理函数,详情看上一篇)(个人备忘2:CharEncar是将自定义类型做了封装,便于其他项目复制)

    个人注释:(与本文无关,个人备忘。好长时间不写代码了,都不会写了(´╥ω╥`)

    HQL使用自定义函数测试代码:

     public IList<tableModel> getTableModelList(tableModel model)
            {
                ISession iSession = null;
                try
                {
                    iSession = openSession();
                    string sql1 = "select nc_enstr('13800138000') from tableModel as ta where ta.id=1 ";
                    IQuery query1 = iSession.CreateQuery(sql1);
                    var v_1 = query1.List();
    
                    string sql2 = "select nc_destr('" + v_1[0] + "') from tableModel as ta where ta.id=1";
                    query1 = iSession.CreateQuery(sql2);
                    var v_2 = query1.List();
    
                    string sql3 = "select ch_enstr('张三李四') from tableModel as ta where ta.id=1";
                    query1 = iSession.CreateQuery(sql3);
                    var v_3 = query1.List();
    
                    string sql4 = "select ch_destr('" + v_3[0] + "') from tableModel as ta where ta.id=1";
                    query1 = iSession.CreateQuery(sql4);
                    var v_4 = query1.List();
                    reuturn null;//测试代码,所以返回null
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    this.closeSession(iSession);
                }
            }
    HQL使用测试代码

    也可以使用sql语句进行查询,由于需要对取回的值进行处理,而且model映射字段名和变量名不一致所以使用HQL方便些。

    sql查询:

      public IList<tableModel> getTableModelList(tableModel model)
            {
                ISession iSession = null;
                try
                {
                    iSession = openSession(); 
                    string sql = "select ta.id,ta.name,ta.email from te_table as ta where ta.email like concat('%',nc_enstr('" + model.email+"'),'%')";
                    IQuery qry = iSession.CreateSQLQuery(sql);//.AddEntity("ta",typeof(tableModel));
                    qry.SetResultTransformer(Transformers.AliasToBean(typeof(TableModel)));
                    IList<tableModel> list = qry.List<tableModel>();
                    return list;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    this.closeSession(iSession);
                }
            }
    sql查询
    IQuery qry = iSession.CreateSQLQuery(sql).AddEntity("ta",typeof(tableModel));//这种方式需要使用 "select * from table"方式查询,或者是查询全部字段列表“select id,name,sex,…… from table”,不然会报错。

    以下是查询部分字段的方式:sql语句使用“select id,name from table”,不可使用“select * from table”;其中SetResultTransformer(Transformers.AliasToBean(typeof(tableModel)))是为指定字段做映射;(查询部分字段映射不会使用自定义type,是按照sql中的字段名称进行的映射,查询全部字段(select * 和select全部字段)会使用自定义type)

     IQuery qry = iSession.CreateSQLQuery(sql).SetResultTransformer(Transformers.AliasToBean(typeof(tableModel)));
                    //IQuery qry = iSession.CreateSQLQuery(sql)
                    //qry.SetResultTransformer(Transformers.AliasToBean(typeof(tableModel)));

    HQL查询部分字段,需要在model的构造函数内定义查询的部分字段,且顺序要相同。

    比如 "select new tableModel(id,name) from tableModel as ta" 需要在tableModel 里定义顺序相同的,

       public tableModel(int id, string name) { 
            this.id = id;  
            this.name = name;  
        }  

    如果再有查询其他字段的HQL则又要定义一个不同参数的构造函数,很不便捷,还不如使用sql来的快。

    仅供参考,内容中会引用部分博友的文章。(侵删)
  • 相关阅读:
    判断用户分辨率调用不同的CSS样式文件
    译文:创建性感的CSS
    CSS控制文字的显示与隐藏时引出的Bug
    设计规范的理想
    浏览器不兼容的源头
    图片垂直居中的使用技巧
    CSS命名规范
    5.2 微格式
    如何在本地使用 Yahoo! BrowserPlus
    如何让 Firefox 2 和 Firefox 3 版本并存
  • 原文地址:https://www.cnblogs.com/zeran/p/10906715.html
Copyright © 2011-2022 走看看