【Hibernate】(3)Hibernate單表操作

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。


發佈了80 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章