SSH入門Hibernate篇(1)——編寫第一個hibernate程式
前言
hibernate用於把物件模型 表示的物件對映到基於 SQL 的關係模型資料結構中去,採用完全面向物件的 方式來操作資料庫;主要作用是簡化應用的資料持久層程式設計,不僅能管理 Java 類到數 據庫表的對映,還提供資料查詢和獲取資料的方法。
第一個hibernate程式
1.匯入hibernate核心jar包
網盤下載連結
將它們複製到web工程的WEB-INF/lib目錄中
如果需要進行測試,則還需要junit4.0.jar包
2.構造持久化類(普通的JavaBean)
持久化類是指需要被hibernate持久化到資料庫中的例項所對應的類。在這裡這些類就是普通的java類,因此我們也稱之為POJO。
持久化類的規則:
1.必須有一個無參的構造方法
2.必須有一個唯一標識屬性(和資料庫表的主鍵對應)
3.其中的每個屬性都必須提供setXxx()方法和getXxx()方法
4.持久化類的屬性最好不要用簡單資料型別,例如使用Integer而不是int。(這點並不是必須的)
示例:Item.java
package cn.edu.zjut.po;
public class Item {
public Item() {
// TODO Auto-generated constructor stub
}
private String itemID;
private String name;
private String description;
private double cost;
public String getItemID() {
return itemID;
}
public void setItemID(String itemID) {
this.itemID = itemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getCost () {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
}
3.持久化類對應的對映檔案*.hbm.xml——和持久化類放在同一目錄下
一個類對應一個對映檔案,用於對應持久化類和資料庫中的表
例:Item.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.edu.zjut.po.Item" table="item" schema="dbo">
<id name="itemID" type="java.lang.String">
<column name="ISBN" length="20"/>
<generator class="assigned"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="title" length="60" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="100" />
</property>
<property name="cost" type="java.lang.Double">
<column name="cost" length="100" />
</property>
</class>
</hibernate-mapping>
說明:
這裡的文件型別定義檔案為hibernate-mapping-3.0.dtd,不同hibernate版本的dtd檔案是不同的。
<hibernate-mapping>
是xml檔案的根元素,其下可以有多個class元素- 一個
<class>
對應一個持久化類,name後面是類的具體名稱,table後面是對應資料庫表的名稱,schema是擁有者(??),總之如果不寫schema的話就要寫成table=“dbo.item”,此外class元素下還可以有catalog屬性,用於指定資料表所在的資料庫。(如果這裡指定的和配置檔案中指定的資料庫不一樣,那麼參照??地方的) - 一個class元素下必須有且只有一個id元素,和資料表中的主鍵相匹配,可以沒有property元素,但若有id元素必須在property元素之前進行定義。
- id和property後的name對應的是持久化類中的屬性,而column的name是表中的列名
- id的generator元素,assigned:自行分配,這也是沒有指定generator元素時的預設生成策略。除了assigned之外還可以設定為increment,自動增加,每次增量為1.
4.hibernate配置檔案*.cfg.xml,連線資料庫
每一個對映檔案都要在配置檔案中進行註冊。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="HibernateSessionFactory">
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;DatabaseName=hibernatedb</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">123456</property>
<mapping resource="cn/edu/zjut/po/Customer.hbm.xml" />
<mapping resource="cn/edu/zjut/po/Item.hbm.xml" />
</session-factory>
</hibernate-configuration>
- hibernate.connection.driver_class:設定連線資料庫的驅動,在這裡我用的是sql server
- hibernate.connection.url:設定所需連線資料庫服務的url
- hibernate.connection.username:連線資料庫的使用者名稱
- hibernate.connection.password:連線資料庫的密碼
在這裡我們可以和之前不用hibernate時配置的區域性資料來源進行一下對比(非常相像):
<?xml version="1.0" encoding="utf-8"?>
<Context reloadable = "true">
<Resource
name="jdbc/sqlserver"
type="javax.sql.DataSource"
maxActive="4"
maxIdle="2"
maxWait="10000"
username="sa"
password="123456"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://localhost:1433;DatabaseName=webHomework"/>
</Context>
5.dao類——操作資料庫
例如:ItemDao
package cn.edu.zjut.dao;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import cn.edu.zjut.po.Item;
public class ItemDao {
public List findAll() {
//建立Configuration物件,得到配置檔案的資訊
Configuration cfg= new Configuration() .configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf = cfg.buildSessionFactory(sr);
Session session = sf.openSession();
//Transaction tx = session.beginTransaction();
//tx.commit();
try {
String queryString = "from Item";//這裡是from 實體類名 而不是資料表名,這句話代表查詢全部
Query queryObject = session.createQuery(queryString);
return queryObject.list();
}catch(RuntimeException re){
throw re;
}finally {
session.close();
}
}
}
hibernate進行持久化操作離不開SessionFactory物件,這個物件是整個資料庫對映關係編譯後的記憶體映象,該物件通常由Configuration物件產生。
呼叫SesssionFactory物件的OpenSession()方法可以獲得一個Session類的例項。Session介面提供了操作資料庫的各種方法。
6.service類、action類等和struts中相同
ItemService.java:
package cn.edu.zjut.service;
import java.util.ArrayList;
import java.util.List;
import cn.edu.zjut.dao.ItemDao;
import cn.edu.zjut.po.Item;
public class ItemService {
public ItemService() {
}
public List getAllItems() {
ItemDao itemDao = new ItemDao();
List items = itemDao.findAll();
return items;
}
}
ItemAction:
package cn.edu.zjut.action;
import java.util.List;
import cn.edu.zjut.service.ItemService;
public class ItemAction{
private List items;
ItemService itemServ;
public String getAllItems() {
itemServ = new ItemService();
if(itemServ.getAllItems() != null) {
items = itemServ.getAllItems();
return "success";
}
return "fail";
}
public List getItems() {
return items;
}
}
注意這裡的getItems很重要,不然在跳轉之後的頁面就無法獲取items的值
跳轉之後的頁面itemList.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<th>編號</th><th>書名</th><th>說明</th><th>單價</th>
</tr>
<s:iterator value="items">
<tr>
<td><s:property value="itemID"/></td>
<td><s:property value="name"/></td>
<td><s:property value="description"/></td>
<td><s:property value="cost"/></td>
</tr>
</s:iterator>
</table>
</body>
</html>
7.如果採用複合主鍵
假設item需要itemID和name組成複合主鍵,那麼需要把itemID和name寫到一個類裡面,然後讓這個主鍵類作為Item類的屬性。
ItemPK.java
package cn.edu.zjut.po;
import java.io.Serializable;
public class ItemPK implements Serializable{
public ItemPK() {
// TODO Auto-generated constructor stub
}
private String itemID;
private String name;
public String getItemID() {
return itemID;
}
public void setItemID(String itemID) {
this.itemID = itemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Item.java:
package cn.edu.zjut.po;
public class Item {
public Item() {
// TODO Auto-generated constructor stub
}
private ItemPK ipk;
private String description;
private double cost;
public Item(ItemPK ipk, String description, double cost) {
super();
this.ipk = ipk;
this.description = description;
this.cost = cost;
}
//省略setter和getter方法
item.hbm.xml的改動:
<!-- 這是不採用複合主鍵時的寫法
<id name="itemID" type="java.lang.String">
<column name="ISBN" length="20"/>
<generator class="assigned"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="title" length="60" />
</property>
-->
<!-- 採用複合主鍵 -->
<composite-id name="ipk" class="cn.edu.zjut.po.ItemPK">
<key-property name="itemID" column="ISBN"/>
<key-property name="name" column="title"/>
</composite-id>
itemList.jsp:
<body>
<table border="1">
<tr>
<th>編號</th><th>書名</th><th>說明</th><th>單價</th>
</tr>
<s:iterator value="items">
<tr>
<td><s:property value="ipk.itemID"/></td>
<td><s:property value="ipk.name"/></td>
<td><s:property value="description"/></td>
<td><s:property value="cost"/></td>
</tr>
</s:iterator>
</table>
</body>