用Hibernate查询有下划线的表字段遇到的问题

本文介绍了一个物流项目中使用Seam+Spring+Hibernate技术栈遇到的问题:当使用包含下划线的字段作为查询条件时,Hibernate无法正确解析。通过在SQL语句中增加别名的方式解决了此问题。
正在用Seam+Spring+Hibernate开发一个物流相关的项目,下午QA发现了一个这样的问题:
当用某些字段作为条件查找的时候,会出错。后来经过查看Hibernate的log日志,发现Hibernate产生的Sql语句中凡是有下划线的都没有正确解析到:比如:

Entity Class Snippet:
private Float ctnnweight;
private Float ctngweight;

private Integer quantityPerCtn;
.............................
@Column(name = "quantity_per_ctn")
public Integer getQuantityPerCtn() {
return quantityPerCtn;
}

Action Class Snippet:
models = this.shippingDatabase
.createQuery(
"select distinct m from Model m left outer join m.agiles agile order by m.name asc")
.setMaxResults(pageSize).setFirstResult(page * pageSize).list();

..................................
..................................
if (!bUnw) {
sql.append(" and unitnweight=:unitnweight");
}
if (!bUgw) {
sql.append(" and unitgweight=:unitgweight");
}

if (!bQpre) {
sql.append(" and quantityPerCtn=:quantityPerCtn");
}

Table Structure:
id: varchar(255)
unitnweight: int
unitgweight: int
quantity_per_ctn: int

如果用unitnweight或unitgweight作为查询条件的或,没有问题。但是如果用quantityPerCtn的话,就会出现问题了。查看Hibernate产生的Sql语句中,发现Hibernate没有把quantityPerCtn正确映射成quantity_per_ctn。后来把sql修改为:

if (!bUnw) {
sql.append(" and m.unitnweight=:unitnweight");
}
if (!bUgw) {
sql.append(" and m.unitgweight=:unitgweight");
}

if (!bQpre) {
sql.append(" and m.quantityPerCtn=:quantityPerCtn");
}

注意,这个时候在每个field前加上了一个别名,就能够正确映射表的字段明了。因为前两个Entity类的field名和表的字段名是一样的,所以不同经过映射也能正确查找,而第三个field和数据表的字段名不对应,而又没有映射到的话,就会出现问题了。不过好像Hibernate在处理下划线的时候经常会出现问题,不知道用了以上方法之后能不能解决,还是另有他因,本人是个新手,有n多东西都还在探索当中啊,要多多努力加油!
这有个文章,或许有时候可以参考一下:
[quote]
控制时间 发表于: 2007-7-23 07:35 来源: 创意空间
很多朋友问我在使用Hibernate技术的时候如何解决数据下划线映射问题。网上有很多已经指出了解决方法!但是很多人还是不能搞定。我这里就把方法直接点说出来!给大家共享!
通过Hibernate映射数据后会发现带有下划线的字段被映射成了别的东西。比如有一个字段名称是这样的“u_name”那么Hibernate映射后其名称就变成了UName,观察对应的XML文件其中是这么定义的“<property name="UName" column="u_name" type="string" not-null="true" />”。打开相应的类文件查看。初次看完这个类后会发现没有问题,但是添加数据的时候会出错,错误如下:“Could not find a getter for UName in class com.table.Tone”错误说明了在com.table.Tone这个类里面找不到UName。
处理方法如下:1.修改XML文件将“UName”更换成“uname”注意是小写(当然这个名字可以自己定义了)。然后把对应类里面的私有成员变量 “private String UName;”改成“private String uname”并且替换所有名称为“UName”的地方。很多朋友到这里就卡住了,因为这样修改完毕后还是会报“Could not find a getter for UName in class com.table.Tone”错误。因为你只是修改了一半而已。2.还要替换与“UName”相关的set与get方法名称。(如果要问我为什么?那么我就要说你不了解Hibernate的处理机制就不要是用Hibernate了。浪费工具)。这样就完成了!运行吧!呵呵!
如果还有什么疑问可以跟贴!
[/quote]
Hibernate 提供了自动管理数据库表结构的功能,可以通过配置实现数据库表的创建和更新操作。要实现通过代码自动添加数据库表字段,需要结合 `hibernate.hbm2ddl.auto` 配置项以及实体类字段的定义,Hibernate 会根据实体类的结构自动更新数据库表的字段。 ### 自动添加数据库表字段的配置 Hibernate 的 `hibernate.hbm2ddl.auto` 属性用于控制数据库表的生成和更新策略。当设置为 `update` 时,Hibernate 会在启动时自动检测实体类与数据库表结构之间的差异,并更新数据库表结构,包括新增字段[^1]。 ```xml <property name="hibernate.hbm2ddl.auto">update</property> ``` 该配置会确保 Hibernate 在应用启动时,根据实体类的字段定义,自动在对应的数据库表中添加缺失的字段。例如,如果实体类中新增了一个字段,而数据库表中没有对应的列,Hibernate 会自动添加该字段对应的列。 ### 实体类字段定义与数据库表字段映射 为了确保 Hibernate 能够正确识别并添加字段,实体类中的字段需要通过注解或 XML 映射文件与数据库表列进行绑定。以下是一个使用 JPA 注解的示例: ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "username") private String username; @Column(name = "email") private String email; // 新增字段 @Column(name = "phone") private String phone; // Getters and Setters } ``` 当应用启动时,如果数据库表 `users` 中不存在 `phone` 字段Hibernate 会根据 `hibernate.hbm2ddl.auto=update` 的配置,自动在 `users` 表中添加 `phone` 列。 ### 注意事项 - **字段类型匹配**:确保实体类字段的 Java 类型与数据库列的 SQL 类型兼容。例如,`String` 类型通常映射为 `VARCHAR`,而 `LocalDate` 类型映射为 `DATE`。 - **字段顺序**:Hibernate 不会保证数据库表字段的顺序与 Java 类字段的顺序一致,因此在手动编写 SQL 语句时,应明确指定字段名称[^2]。 - **避免手动修改表结构**:当使用 `update` 策略时,应避免手动修改数据库表结构,以免与实体类定义不一致,导致 Hibernate 更新失败。 ### 示例代码 以下是完整的 Hibernate 配置文件示例,用于启用自动更新数据库表的功能: ```xml <!-- hibernate.cfg.xml --> <hibernate-configuration> <session-factory> <!-- 数据库连接信息 --> <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">password</property> <!-- SQL 方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property> <!-- 自动更新表结构 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 显示 SQL 语句 --> <property name="hibernate.show_sql">true</property> <!-- 注册实体类 --> <mapping class="com.example.model.User"/> </session-factory> </hibernate-configuration> ``` 通过上述配置,Hibernate 会在应用启动时自动检测 `User` 类中的字段变化,并在数据库表中添加相应的字段。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值