hibernate之insert和update控制实战
2016年02月03日 17:59:58
阅读数:5458
Hibernate在初始化阶段,会根据对象-关系映射文件生成预编译SQL语句。
1.insert,例如Customer类,初始化时根据映射文件生成预编译SQL
-
insert into CUSTOMERS (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, DESCRIPTION, IMAGE, BIRTHDAY, REGISTERED_TIME, ID) -
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2.update,生成的预编译SQL
-
update CUSTOMERS set NAME=?, EMAIL=?, PASSWORD=?, PHONE=?, ADDRESS=?, SEX=?, IS_MARRIED=?, DESCRIPTION=?, IMAGE=?, BIRTHDAY=?, -
REGISTERED_TIME=? where ID=?
3.delete,生成预编译SQL
delete from CUSTOMERS where ID=?
注意:以上SQL语句中的?号代表的是JDBC中PreparedStatement中的参数。所有这些SQL语句存放在SessionFactory中,当Session调用save(),update(),
delete(),load()方法时,从缓存中根据找到对应的SQL,同时,将具体参数绑定在具体位置,然后执行SQL。
4.控制insert和update分析
根据上面Hibernate默认打印出来的SQL语句可以看出,每一个SQL语句执行时,都包括了数据库表中的所有字段,这种行为,有时候不是我们想要的,
比如,我们想让表中的某个字段永远都更新不到,如果我们自己写SQL,不把这个目标字段更新就行了,但是Hibernate需要采取一定手段,才能达到
我们的目标,SQL从映射文件而来,解决问题还得回到映射文件上去。
要想解决问题,很简单,比如我们不想更新address,可以在映射文件中加一个update属性,设置成false:
<property name="address" update="false" column="ADDRESS" type="string" />
当我们再次执行更新时,从Hibernate打印的SQL能够看出,更新语句中少了刚才设置成不让更新的ADDRESS=?字段,SQL语句变成:
-
update CUSTOMERS set NAME=?, EMAIL=?, PASSWORD=?, PHONE=?, SEX=?, IS_MARRIED=?, DESCRIPTION=?, IMAGE=?, BIRTHDAY=?, REGISTERED_TIME=? -
where ID=?
注意:控制insert和update映射属性如下:

5.实例演示,实例只做了property的update设置,别的自己根据表格列出的属性,修改后可以很容易测试出其作用
--------实体类
-
package com.lanhuigu.hibernate.entity; -
import java.io.Serializable; -
import java.sql.Date; -
import java.sql.Timestamp; -
public class Customer implements Serializable{ -
private static final long serialVersionUID = -2934493050228154410L; -
private Long id; -
private String name; -
private String email; -
private String password; -
private int phone; -
private boolean married; -
private String address; -
private char sex; -
private String description; -
private byte[] image; -
private Date birthday; -
private Timestamp registeredTime; -
public Customer(){} -
public Long getId() { -
return id; -
} -
public void setId(Long id) { -
this.id = id; -
} -
public String getName() { -
return name; -
} -
public void setName(String name) { -
this.name = name; -
} -
public String getEmail() { -
return email; -
} -
public void setEmail(String email) { -
this.email = email; -
} -
public String getPassword() { -
return password; -
} -
public void setPassword(String password) { -
this.password = password; -
} -
public int getPhone() { -
return phone; -
} -
public void setPhone(int phone) { -
this.phone = phone; -
} -
public boolean isMarried() { -
return married; -
} -
public void setMarried(boolean married) { -
this.married = married; -
} -
public String getAddress() { -
return address; -
} -
public void setAddress(String address) { -
this.address = address; -
} -
public char getSex() { -
return sex; -
} -
public void setSex(char sex) { -
this.sex = sex; -
} -
public String getDescription() { -
return description; -
} -
public void setDescription(String description) { -
this.description = description; -
} -
public byte[] getImage() { -
return image; -
} -
public void setImage(byte[] image) { -
this.image = image; -
} -
public Date getBirthday() { -
return birthday; -
} -
public void setBirthday(Date birthday) { -
this.birthday = birthday; -
} -
public Timestamp getRegisteredTime() { -
return registeredTime; -
} -
public void setRegisteredTime(Timestamp registeredTime) { -
this.registeredTime = registeredTime; -
} -
}
-------映射文件xxx.hbm.xml
-
<?xml version="1.0"?> -
<!DOCTYPE hibernate-mapping PUBLIC -
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" -
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -
<!-- 1.hibernate-mapping对象关系映射的根元素,其它元素必须嵌套在此元素内 --> -
<hibernate-mapping package="com.lanhuigu.hibernate.entity"><!-- 2.package为实体类在哪个包下 --> -
<!-- -
3.class中name为持久化的实体类(Customer),table为映射到数据库中的表名(CUSTOMERS), -
如果没有设置table,默认类名作为表名 -
--> -
<class name="Customer" table="CUSTOMERS"> -
<!-- -
4.以下配置属性解释: -
4.1 name为实体类属性 -
4.2 column为映射到数据库中的字段名,如果没有配置column,默认使用name属性作为映射后数据库表字段名 -
4.3 type为字段类型,如果没有设置type,映射时自动采用实体类的java类型,对应映射数据库字段类型 -
java类型映射到数据库类型参照表: -
java类型>>>>>>>>>>数据库类型 -
string VARCHAR -
int INT -
character CHAR -
boolean BIT -
text TEXT -
binary BLOB -
date DATE -
timestamp TIMESTAMP -
4.4 not-null设置该字段是否允许为null, -
4.5 length设置字段的长度 -
--> -
<!-- 设置主键 --> -
<id name="id" column="ID" type="long"> -
<!-- 主键生成方式--> -
<generator class="increment"/> -
</id> -
<!-- 基本属性,基本属性必须设置在主键之口--> -
<property name="name" column="NAME" type="string" length="25" not-null="true" access="property"/> -
<property name="email" column="EMAIL" type="string" not-null="true" /> -
<property name="password" column="PASSWORD" type="string" not-null="true" /> -
<property name="phone" column="PHONE" type="int" /> -
<property name="address" update="false" column="ADDRESS" type="string" /> -
<property name="sex" column="SEX" type="character" /> -
<property name="married" column="IS_MARRIED" type="boolean" /> -
<property name="description" column="DESCRIPTION" type="text" /> -
<property name="image" column="IMAGE" type="binary" /> -
<property name="birthday" column="BIRTHDAY" type="date" /> -
<property name="registeredTime" column="REGISTERED_TIME" type="timestamp" /> -
</class> -
</hibernate-mapping>
-------hibernate.cfg.xml
-
<!DOCTYPE hibernate-configuration PUBLIC -
"-//Hibernate/Hibernate Configuration DTD 3.0//EN" -
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> -
<!-- hibernate-configuration为hibernate配置头文件 --> -
<hibernate-configuration> -
<!-- 配置session-factory, -
SessionFactory是Hibernate的工厂类, -
该类负责Hibernate的配置和Hiberante的Session接口中save(),update(),delete(),load(),find()的操作 -
--> -
<session-factory> -
<!-- 1.数据库连接配置 --> -
<!-- 数据库连接url --> -
<property name="connection.url">jdbc:mysql://192.168.200.12:3306/hbtest</property> -
<!-- 数据库连接用户名 --> -
<property name="connection.username">root</property> -
<!-- 数据库连接口令 --> -
<property name="connection.password">root123</property> -
<!-- 数据库连接驱动 --> -
<property name="connection.driver_class">com.mysql.jdbc.Driver</property> -
<!-- 数据库方言 --> -
<property name="dialect">org.hibernate.dialect.MySQLDialect</property> -
<!-- 数据库连接池大小配置 --> -
<property name="connection.pool_size">1</property> -
<!-- 配置使用二级缓存的类 --> -
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> -
<!-- 一次读的数据库记录数 --> -
<property name="jdbc.fetch_size">50</property> -
<!-- 设定对数据库进行批量删除条数 --> -
<property name="jdbc.batch_size">30</property> -
<!-- 2.是否打印sql配置 --> -
<property name="show_sql">true</property> -
<!-- 3.对象-映射关系文件的位置 --> -
<mapping resource="com/lanhuigu/hibernate/entity/Customer.hbm.xml" /> -
</session-factory> -
</hibernate-configuration>
-----设置前和设置后只需把property中的update去掉或增加,或者设置成true或false,再根据控制台打印的SQL十分清楚地看到明显的差距,效果十分明显。
-
package com.lanhuigu.hibernate.test; -
import org.hibernate.Session; -
import org.hibernate.SessionFactory; -
import org.hibernate.Transaction; -
import org.hibernate.cfg.Configuration; -
import org.hibernate.tool.hbm2ddl.SchemaExport; -
import com.lanhuigu.hibernate.entity.Customer; -
public class TestHibernate { -
public static void main(String[] args) { -
SessionFactory sessionFactory; -
Configuration configuration = new Configuration().configure(); -
sessionFactory = configuration.buildSessionFactory(); -
//自动建表(create) -
//SchemaExport export = new SchemaExport(configuration); -
//export.create(true, true); -
Session session = sessionFactory.openSession(); -
Transaction tr = session.beginTransaction(); -
//保存(insert) -
/*Customer customer = new Customer(); -
customer.setId(new Long(1)); -
customer.setName("test"); -
customer.setEmail("123456789@qq.com"); -
customer.setPassword("123456"); -
customer.setAddress("世外桃源"); -
session.save(customer);*/ -
//更新(update) -
Customer customer = new Customer(); -
customer.setId(new Long(1)); -
customer.setName("test"); -
customer.setEmail("123456789@qq.com"); -
customer.setPassword("222222"); -
customer.setAddress("世外桃源"); -
session.update(customer); -
//删除(delete) -
/*Customer customer = new Customer(); -
customer.setId(new Long(1)); -
customer.setName("test"); -
customer.setEmail("123456789@qq.com"); -
customer.setPassword("222222"); -
customer.setAddress("世外桃源"); -
session.delete(customer);*/ -
tr.commit(); -
session.close(); -
} -
}
结果分析:
通过两种情况得到的SQL,可以清楚地看到SQL中ADDRESS=?有无区别。
注意:
1.测试前,请搭建好自己的hibernate开发环境,导入hibernate必须包和对应数据库驱动包
2.记得建表--插入数据--再做更新,避免报空指针异常或其它异常。(可以根据测试类,根据我代码注释,从建表到更新,一个代码一个代码的放开;)
3.测试更新时,记得修改映射文件xxx.hbm.xml
4.根据表格中列出的映射属性,对应修改,可以看到对应的作用结果。
本文介绍Hibernate框架中如何通过配置实现对数据库表中特定字段的插入和更新操作控制,特别是在实体类映射文件中如何利用update属性来指定哪些字段参与更新。
678

被折叠的 条评论
为什么被折叠?



