在 hibernate 中映射到 varchar 和 nvarchar
如果数据库中有 2 列,例如。
code varchar(3)
name nvarchar(50)
如何告诉hibernate传递varchar来通过代码搜索?
在 hibernate 映射中,字符串被映射到 nvarchar 并产生如下查询:
Select code, name From table where code=N'AAA' (instead of code='AAA')
这非常糟糕,因为它导致索引扫描而不是索引查找操作(扫描所有索引节点而不是直接转到请求的节点),
因为代码在数百万行中使用以及在几个索引和外键中,将其从 varchar 更改为 nvarchar 会导致性能下降(更多 IO 操作,因为 nvarchar 使用的空间是 varchar 的两倍)。
有没有办法告诉hibernate根据数据库类型而不是Java类型进行映射?
谢谢
If there are 2 columns in database, eg.
code varchar(3)
name nvarchar(50)
How to tell hibernate to pass varchar for searching by code?
In the hibernate mappings string is mapped to nvarchar and it produces queries like:
Select code, name From table where code=N'AAA' (instead of code='AAA')
This is very bad as it causes index scan instead of index seek operation (scanning all index nodes instead of directly going to requested one)
As code is used in millions of rows as well as in several indexes and foreign keys, changing it from varchar to nvarchar will cause performance degradation (more IO operations as nvarchar uses twice more space than varchar).
Is there any way to tell hibernate to do mapping according to database type, not to Java type?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
也许你已经解决了这个问题,但我也遇到了类似的问题。
解决索引扫描问题
我正在使用 jTDS JDBC 驱动程序,并通过添加:到 jTDS 连接字符串的末尾来
。 它可能无法解决您的问题,因为通过这样做,jTDS 将仅使用 VARCHAR(不再使用 NVARCHAR)。
另外,我必须禁用准备好的 SQL,因为 Hibernate 在生成查询时使用“like”而不是“=”,并且通过使用“like”与变量(SELECT ... WHERE column LIKE @var)结合使用会导致索引扫描(MSSQL 2000)。
Probably you already solved this, but I had a similar problem.
I'm using jTDS JDBC driver and I solved the index scan problem by adding:
to the end of the jTDS connection string.
Probably it would not had solved your problem because by doing this, jTDS will only use VARCHAR (no NVARCHAR anymore).
Also, I had to disable the prepared SQL, because Hibernate is using 'like' instead of '=' when generating the queries and by using 'like' combined with a variable (SELECT ... WHERE column LIKE @var) causes an index scan (MSSQL 2000).
我假设您正在谈论 NHibernate 而不是 Hibernate,因为后者在其默认 SqlServer 方言中不使用 nvarchar。
解决问题的方法是在映射中将列类型指定为“AnsiString”:
看看 这篇文章了解更多详细信息。
I'm assuming you're talking about NHibernate rather than Hibernate because the latter does not use nvarchar in its default SqlServer dialect.
The way to solve your problem is to specify column type as "AnsiString" in your mapping:
Take a look at this post for more details.
在 hibernate reveng 文件中添加上述代码。
Add the above code in the hibernate reveng file.
在 hibernate.properties 中设置属性 hibernate.connection.defaultNChar=false。
您可以将表隐藏在视图后面或使用 nstring 类型。 此类型在 hibernate-core 4.x 中可用。 在 hibernate-core 3.6.10.Final 中,您需要定义自定义类型 nstring - 请参阅 url 中的注释:
获取 Hibernate 和 SQL服务器可以很好地使用 VARCHAR 和 NVARCHAR。
In hibernate.properties set the property hibernate.connection.defaultNChar=false.
You can either hide your tables behind views or use nstring type. This type is available in hibernate-core 4.x. In hibernate-core 3.6.10.Final you will need to define the custom type nstring - see the comment in the url:
Getting Hibernate and SQL Server to play nice with VARCHAR and NVARCHAR.