当我们创建一个数据表时,有时需要为数据表中的字段指定默认值,如下代码:
create table users(
id int not null primary key identity(1,1),
email varchar(128) unique not null,
name varchar(128) not null,
pwd varchar(128) not null,
photo varchar(128) default 'default.gif',
sex varchar(16),
visited int default 0,
online tinyint default 0,
registerDate datetime ,
loginDate datetime,
level tinyint default 1,
locked tinyint default 0
)
但是在SSH项目中想数据表中插入数据时,我们会发现,这些默认值并没有在数据表中自动生成。出现这个问题的原因是:没有在users的映射文件中加入dynamic-insert=”true”的设置。如果改成:
<hibernate-mapping>
<class name="com.domain.Users" table="users" schema="dbo" dynamic-insert="true" catalog="xiaonei">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
......
</class>
</hibernate-mapping>
下面详细介绍一下dynamic-insert的使用:
Hibernate在初始化的时候,默认按照配置为表预定义insert,delete,update,select(by id)的SQL语句放在session中。其中insert,update,select操作都是对表的所有字段操作。如果在一个表有很多字段的时候,在做初次insert的时候有比较多的字段为空值,或者经常update某少部分字段,应该在配置文件的元素上将dynamic-insert和dynamic-update设置为true,其默认值都为false。
1,在 dynamic-insert没有设置的时候
<hibernate-mapping>
<class name="com.domain.Users" table="users" schema="dbo" catalog="xiaonei">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
......
</class>
</hibernate-mapping>
我们在进行insert操作时,例如action中有如下代码:
//取出表单信息
UserForm userForm = (UserForm) form;
Users user = new Users();
user.setEmail(userForm.getEmail());
user.setLoginDate(new java.util.Date());
user.setName(userForm.getName());
user.setPwd(userForm.getPwd());
user.setRegisterDate(new java.util.Date());
user.setSex(userForm.getSex());
//保存用户
userServiceInter.save(user);
这时后台会打出如下语句:
Hibernate: insert into xiaonei.dbo.users (email, name, pwd, sex, registerDate, loginDate,mobile, msn,music, movie, ……) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ……)
即将user表中的所有字段显示,即便这些字段是空值。
2,将dynamic-insert设置为true,同样的保存,hibernate会动态生成SQL语句,没有值的字段不会出现在insert语句中.
Hibernate: insert into xiaonei.dbo.users (email, name, pwd, sex, registerDate, loginDate) values (?, ?, ?, ?, ?, ?)
而且还会把设置了默认值的字段,将默认值insert到表中。
dynamic-update的使用原理同dynamic-insert。
Hibernate这种动态更新的特性是利用在对象从数据库加载到hibernate session的时候保存了一份快照,做insert和update操作时就会与这个快照做比较,只更新被改动过的值。