文章目录
前言
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>