hibernate之insert和update控制实战

hibernate之insert和update控制实战

2016年02月03日 17:59:58

阅读数:5458

Hibernate在初始化阶段,会根据对象-关系映射文件生成预编译SQL语句。

1.insert,例如Customer类,初始化时根据映射文件生成预编译SQL

 

 
  1. insert into CUSTOMERS (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, DESCRIPTION, IMAGE, BIRTHDAY, REGISTERED_TIME, ID)

  2.  
  3. values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

 

2.update,生成的预编译SQL

 

 
  1. update CUSTOMERS set NAME=?, EMAIL=?, PASSWORD=?, PHONE=?, ADDRESS=?, SEX=?, IS_MARRIED=?, DESCRIPTION=?, IMAGE=?, BIRTHDAY=?,

  2.  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语句变成:

 

 

 
  1. update CUSTOMERS set NAME=?, EMAIL=?, PASSWORD=?, PHONE=?, SEX=?, IS_MARRIED=?, DESCRIPTION=?, IMAGE=?, BIRTHDAY=?, REGISTERED_TIME=?

  2. where ID=?

 

 

注意:控制insert和update映射属性如下:


5.实例演示,实例只做了property的update设置,别的自己根据表格列出的属性,修改后可以很容易测试出其作用

  --------实体类

 

 
  1. package com.lanhuigu.hibernate.entity;

  2.  
  3. import java.io.Serializable;

  4. import java.sql.Date;

  5. import java.sql.Timestamp;

  6.  
  7. public class Customer implements Serializable{

  8. private static final long serialVersionUID = -2934493050228154410L;

  9.  
  10. private Long id;

  11. private String name;

  12. private String email;

  13. private String password;

  14. private int phone;

  15. private boolean married;

  16. private String address;

  17. private char sex;

  18. private String description;

  19. private byte[] image;

  20. private Date birthday;

  21. private Timestamp registeredTime;

  22.  
  23. public Customer(){}

  24.  
  25. public Long getId() {

  26. return id;

  27. }

  28.  
  29. public void setId(Long id) {

  30. this.id = id;

  31. }

  32.  
  33. public String getName() {

  34. return name;

  35. }

  36.  
  37. public void setName(String name) {

  38. this.name = name;

  39. }

  40.  
  41. public String getEmail() {

  42. return email;

  43. }

  44.  
  45. public void setEmail(String email) {

  46. this.email = email;

  47. }

  48.  
  49. public String getPassword() {

  50. return password;

  51. }

  52.  
  53. public void setPassword(String password) {

  54. this.password = password;

  55. }

  56.  
  57. public int getPhone() {

  58. return phone;

  59. }

  60.  
  61. public void setPhone(int phone) {

  62. this.phone = phone;

  63. }

  64.  
  65. public boolean isMarried() {

  66. return married;

  67. }

  68.  
  69. public void setMarried(boolean married) {

  70. this.married = married;

  71. }

  72.  
  73. public String getAddress() {

  74. return address;

  75. }

  76.  
  77. public void setAddress(String address) {

  78. this.address = address;

  79. }

  80.  
  81. public char getSex() {

  82. return sex;

  83. }

  84.  
  85. public void setSex(char sex) {

  86. this.sex = sex;

  87. }

  88.  
  89. public String getDescription() {

  90. return description;

  91. }

  92.  
  93. public void setDescription(String description) {

  94. this.description = description;

  95. }

  96.  
  97. public byte[] getImage() {

  98. return image;

  99. }

  100.  
  101. public void setImage(byte[] image) {

  102. this.image = image;

  103. }

  104.  
  105. public Date getBirthday() {

  106. return birthday;

  107. }

  108.  
  109. public void setBirthday(Date birthday) {

  110. this.birthday = birthday;

  111. }

  112.  
  113. public Timestamp getRegisteredTime() {

  114. return registeredTime;

  115. }

  116.  
  117. public void setRegisteredTime(Timestamp registeredTime) {

  118. this.registeredTime = registeredTime;

  119. }

  120. }

 

 -------映射文件xxx.hbm.xml

 

 
  1. <?xml version="1.0"?>

  2. <!DOCTYPE hibernate-mapping PUBLIC

  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

  5. <!-- 1.hibernate-mapping对象关系映射的根元素,其它元素必须嵌套在此元素内 -->

  6. <hibernate-mapping package="com.lanhuigu.hibernate.entity"><!-- 2.package为实体类在哪个包下 -->

  7. <!--

  8. 3.class中name为持久化的实体类(Customer),table为映射到数据库中的表名(CUSTOMERS),

  9. 如果没有设置table,默认类名作为表名

  10. -->

  11. <class name="Customer" table="CUSTOMERS">

  12. <!--

  13. 4.以下配置属性解释:

  14. 4.1 name为实体类属性

  15. 4.2 column为映射到数据库中的字段名,如果没有配置column,默认使用name属性作为映射后数据库表字段名

  16. 4.3 type为字段类型,如果没有设置type,映射时自动采用实体类的java类型,对应映射数据库字段类型

  17. java类型映射到数据库类型参照表:

  18. java类型>>>>>>>>>>数据库类型

  19. string VARCHAR

  20. int INT

  21. character CHAR

  22. boolean BIT

  23. text TEXT

  24. binary BLOB

  25. date DATE

  26. timestamp TIMESTAMP

  27. 4.4 not-null设置该字段是否允许为null,

  28. 4.5 length设置字段的长度

  29. -->

  30. <!-- 设置主键 -->

  31. <id name="id" column="ID" type="long">

  32. <!-- 主键生成方式-->

  33. <generator class="increment"/>

  34. </id>

  35. <!-- 基本属性,基本属性必须设置在主键之口-->

  36. <property name="name" column="NAME" type="string" length="25" not-null="true" access="property"/>

  37. <property name="email" column="EMAIL" type="string" not-null="true" />

  38. <property name="password" column="PASSWORD" type="string" not-null="true" />

  39. <property name="phone" column="PHONE" type="int" />

  40. <property name="address" update="false" column="ADDRESS" type="string" />

  41. <property name="sex" column="SEX" type="character" />

  42. <property name="married" column="IS_MARRIED" type="boolean" />

  43. <property name="description" column="DESCRIPTION" type="text" />

  44. <property name="image" column="IMAGE" type="binary" />

  45. <property name="birthday" column="BIRTHDAY" type="date" />

  46. <property name="registeredTime" column="REGISTERED_TIME" type="timestamp" />

  47. </class>

  48.  
  49. </hibernate-mapping>


-------hibernate.cfg.xml

 

 

 
  1. <!DOCTYPE hibernate-configuration PUBLIC

  2. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

  3. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

  4. <!-- hibernate-configuration为hibernate配置头文件 -->

  5. <hibernate-configuration>

  6. <!-- 配置session-factory,

  7. SessionFactory是Hibernate的工厂类,

  8. 该类负责Hibernate的配置和Hiberante的Session接口中save(),update(),delete(),load(),find()的操作

  9. -->

  10. <session-factory>

  11. <!-- 1.数据库连接配置 -->

  12. <!-- 数据库连接url -->

  13. <property name="connection.url">jdbc:mysql://192.168.200.12:3306/hbtest</property>

  14. <!-- 数据库连接用户名 -->

  15. <property name="connection.username">root</property>

  16. <!-- 数据库连接口令 -->

  17. <property name="connection.password">root123</property>

  18. <!-- 数据库连接驱动 -->

  19. <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

  20. <!-- 数据库方言 -->

  21. <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

  22. <!-- 数据库连接池大小配置 -->

  23. <property name="connection.pool_size">1</property>

  24.  
  25. <!-- 配置使用二级缓存的类 -->

  26. <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

  27. <!-- 一次读的数据库记录数 -->

  28. <property name="jdbc.fetch_size">50</property>

  29. <!-- 设定对数据库进行批量删除条数 -->

  30. <property name="jdbc.batch_size">30</property>

  31.  
  32. <!-- 2.是否打印sql配置 -->

  33. <property name="show_sql">true</property>

  34.  
  35. <!-- 3.对象-映射关系文件的位置 -->

  36. <mapping resource="com/lanhuigu/hibernate/entity/Customer.hbm.xml" />

  37.  
  38. </session-factory>

  39. </hibernate-configuration>

 

-----设置前和设置后只需把property中的update去掉或增加,或者设置成true或false,再根据控制台打印的SQL十分清楚地看到明显的差距,效果十分明显。

 

 
  1. package com.lanhuigu.hibernate.test;

  2.  
  3. import org.hibernate.Session;

  4. import org.hibernate.SessionFactory;

  5. import org.hibernate.Transaction;

  6. import org.hibernate.cfg.Configuration;

  7. import org.hibernate.tool.hbm2ddl.SchemaExport;

  8.  
  9. import com.lanhuigu.hibernate.entity.Customer;

  10.  
  11. public class TestHibernate {

  12. public static void main(String[] args) {

  13. SessionFactory sessionFactory;

  14. Configuration configuration = new Configuration().configure();

  15. sessionFactory = configuration.buildSessionFactory();

  16. //自动建表(create)

  17. //SchemaExport export = new SchemaExport(configuration);

  18. //export.create(true, true);

  19. Session session = sessionFactory.openSession();

  20. Transaction tr = session.beginTransaction();

  21. //保存(insert)

  22. /*Customer customer = new Customer();

  23. customer.setId(new Long(1));

  24. customer.setName("test");

  25. customer.setEmail("123456789@qq.com");

  26. customer.setPassword("123456");

  27. customer.setAddress("世外桃源");

  28.  
  29. session.save(customer);*/

  30.  
  31. //更新(update)

  32. Customer customer = new Customer();

  33. customer.setId(new Long(1));

  34. customer.setName("test");

  35. customer.setEmail("123456789@qq.com");

  36. customer.setPassword("222222");

  37. customer.setAddress("世外桃源");

  38.  
  39. session.update(customer);

  40.  
  41. //删除(delete)

  42. /*Customer customer = new Customer();

  43. customer.setId(new Long(1));

  44. customer.setName("test");

  45. customer.setEmail("123456789@qq.com");

  46. customer.setPassword("222222");

  47. customer.setAddress("世外桃源");

  48.  
  49. session.delete(customer);*/

  50.  
  51. tr.commit();

  52. session.close();

  53. }

  54. }


结果分析:

 

通过两种情况得到的SQL,可以清楚地看到SQL中ADDRESS=?有无区别。

注意:

1.测试前,请搭建好自己的hibernate开发环境,导入hibernate必须包和对应数据库驱动包

2.记得建表--插入数据--再做更新,避免报空指针异常或其它异常。(可以根据测试类,根据我代码注释,从建表到更新,一个代码一个代码的放开;)

3.测试更新时,记得修改映射文件xxx.hbm.xml

4.根据表格中列出的映射属性,对应修改,可以看到对应的作用结果。

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值