1. 單一主鍵
這個是在我們生成的Student.hbm.xml中配置的:
<hibernate-mapping>
<class name="com.thr.bean.Student" table="STUDENT">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
我們將hbm2ddl.auto配置爲update
<property name="hbm2ddl.auto">update</property>
(1). assigned:由Java應用程序負責生成(手工賦值)
手工賦值就是我們之前所寫的那種方式:
Student s = new Student();
s.setName("李四");
s.setGender("男");
s.setBirthday(new Date());
s.setAddress("北京");
session.save(s); // 保存對象進入數據庫
這個方法執行第一次的時候是成功的,id自動給值0,但是執行第二次的時候就報錯了,應爲id默認還是0,就會主鍵衝突。
(2). native:由底層數據庫自動生成標識符,如果是MySQL就是increment,如果是Oracle就是sequence,等等
使用native的,如果不置頂id的話它默認會按照從1開始的自動增漲下去,所以當執行添加兩次數據後,不會報錯,並且id是1、2、3這樣子排列下去的。即使你手工指定了id的值,也是不起作用的,插入到數據庫中的值也是按照原來的遞增順序添加的。
2. 基本類型
Student.hbm.xml文件中
<property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
java.util.Date是Java中的格式,是包括年月日時分秒的。
type類型如果是date就是隻有年月日的格式。type類型如果是time就是隻有時分秒的格式。
type類型如果是timestamp就是包含年月日時分秒的格式。
date、time和timestamp這裏是hibernate的數據類型。
3. 對象類型
MySQL不支持標準SQL的CLOB類型,在MySQL中,用TEXT、MEDIUMTEXT和LONGTEXT類型來表示長度超過255的長文本數據。
給之前的Student類添加一個新的屬性:
private Blob picture;
注意,這裏需要導入的是java.sql.Blob類
然後需要刪除我們之前的Student.hbm.xml文件,重新生成一遍,然後編寫方法寫入數據庫:
@Test
public void testWriteBlob() throws Exception {
Student s = new Student(1, "張三", "男", new Date(), "西安");
// 先獲取照片文件
File f = new File("F:" + File.separator + "qtww.jpg");
InputStream is = new FileInputStream(f);
Blob image = Hibernate.getLobCreator(session).createBlob(is,
is.available());
s.setPicture(image);
session.save(s);
}
再寫一個讀取圖片文件到本地的方法:
@Test
public void testReadBlob() throws Exception {
// 這裏第二個參數是學生的主鍵
Student s = (Student) session.get(Student.class, 1);
Blob image = s.getPicture();
InputStream is = image.getBinaryStream();
File f = new File("D:/head.jpg");
f.createNewFile();
OutputStream os = new FileOutputStream(f);
byte[] buff = new byte[is.available()];
is.read(buff);
os.write(buff);
is.close();
os.close();
}
4. 組件屬性
實體類中的某個屬性屬於用戶自定義的類的對象。
增加新的Address實體類:
public class Address {
private String postcode;
private String phone;
private String address;
}
生成構造方法、get和set方法
修改Student類,加入這一個屬性。
修改Student.hbm.xml文件,刪除原來的address屬性,在<class>標籤內增加:
<component name="address" class="com.thr.bean.Address">
<property name="postcode" column="POSTCODE"></property>
<property name="phone" column="PHONE"></property>
<property name="address" column="ADDRESS"></property>
</component>
修改測試代碼:
@Test
public void testSaveStudent() {
// 生成學生對象
// Student s = new Student(1, "張三", "男", new Date(), "西安");
Student s = new Student();
s.setId(1000);
s.setName("李四");
s.setGender("男");
s.setBirthday(new Date());
// s.setAddress("北京");
Address address = new Address("710065", "0298856445", "西安市");
s.setAddress(address);
session.save(s); // 保存對象進入數據庫
}
運行後,我們發現在數據庫中,新增了3個varchar字段存放我們剛纔新建的那個實體類Address。
5. 單表CRUP操作實例
首先要修改策略爲update。
@Test
public void testGetStudent() {
Student s = (Student) session.get(Student.class, 1000);
System.out.println(s);
}
@Test
public void testLoadStudent() {
Student s = (Student) session.load(Student.class, 1000);
System.out.println(s);
}
@Test
public void testUpdateStudent() {
Student s = (Student) session.get(Student.class, 1000);
s.setGender("女");
System.out.println(s);
}
@Test
public void testDeleteStudent() {
Student s = (Student) session.get(Student.class, 1000);
session.delete(s);
System.out.println(s);
}
get和load的區別:
(1). 在不考慮緩存的情況下,get方法會在調用之後立即向數據庫發出sql語句,返回持久化對象。而load方法會在調用後返回一個代理對象,該代理對象只保存了實體對象的id,直到使用對象的非主鍵屬性時纔會發出sql語句。
(2). 查詢數據庫中不存在的數據時,get方法返回null,load方法拋出異常org.hibernate.ObjectNotFoundException。