省略配置文件中的映射信息,改用注解方式实现
1.删除表
因为前面的过程修改了product_的表结构,所以这里先把表product_删除
drop table product_;
2.Product.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.how2java.pojo">
<class name="Product" table="product_">
<id name="id" column="id">
<generator class="native">
</generator>
</id>
<property name="name" />
<property name="price" />
</class>
</hibernate-mapping>
3.使用注解的Product.java
package com.how2java.pojo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "product_")
public class Product {
int id;
String name;
float price;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "price")
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
3.修改hibernate.cfg.xml
<mapping resource="com/how2java/pojo/Product.hbm.xml" />
<!-- 修改为 -->
<mapping class="com.how2java.pojo.Product" />
4.使用TestHibernate进行hibernate的CRUD操作
类注解
在注解的Product类中,类声明前有两个注解
@Entity
@Table(name = "product_")
public class Product {
int id;
String name;
float price;
}
@Entity 表示这是一个实体类,用于映射表
@Table(name = "product_") 表示这是一个表,映射到表名"product_"
属性注解
属性注解配置在属性对应的Getter()方法前
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public int getId() {
return id;
}
@Id 表示这是主键
@GeneratedValue(strategy = GenerationType.IDENTITY) 表示自增长方式使用mysql自带的
@Column(name = "id") 表示映射到字段id
@Column(name = "name")
public String getName() {
return name;
}
@Column(name = "name") 表示映射到字段name
注: getName()即时不加上@Column(name="name"),也可以实现映射的效果
因为getName()方法默认会被认为是字段映射, 除非加上了@Transient 才表示不进行映射
多对一注解
1.将Category类修改为注解的
2.Product类中getCategory()前添加多对一映射注解
@ManyToOne
@JoinColumn(name="cid")
public Category getCategory() {
return category;
}
@ManyToOne 表示多对一关系
@JoinColumn(name="cid") 表示关系字段是cid
与xml配置的映射方式对比
<many-to-one name="category" class="Category" column="cid" />
3.修改hibernate.cfg.xml
<mapping resource="com/how2java/pojo/Category.hbm.xml" />
<!-- 修改为 -->
<mapping class="com.how2java.pojo.Category" />
一对多注解
在一对多注解的基础上,修改Category类
增加Set<Product>集合及其Getter()和Setter()
并在getProduct()前添加一对多映射注解
@OneToMany(fetch=FetchType.EAGER)
@JoinColumn(name="cid")
public Set<Product> getProducts() {
return products;
}
@OneToMany 表示一对多关系 fetch=FetchType.EAGER 表示不进行延迟加载(FetchType.LAZY表示进行延迟加载)
@JoinColumn(name="cid") 表示映射字段是cid
对比xml中的映射方式:
<set name="products" lazy="false">
<key column="cid" not-null="false" />
<one-to-many class="Product" />
</set>
测试用栗TestHibernate
package com.how2java.test;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Category;
import com.how2java.pojo.Product;
public class TestHibernate {
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
s.beginTransaction();
Category c = (Category) s.get(Category.class, 1);
s.getTransaction().commit();
s.close();
sf.close();
Set<Product> ps = c.getProducts();
for (Product p : ps) {
System.out.println(p.getName());
}
}
}
运行结果
多对多注解
1.在多对一注解的基础上,修改Product类
在getUser()前增加ManyToMany注解
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(
name="user_product",
joinColumns=@JoinColumn(name="pid"),
inverseJoinColumns=@JoinColumn(name="uid")
)
public Set<User> getUsers() {
return users;
}
2.修改Product.hbm.xml,增加
<set name="users" table="user_product" lazy="false">
<key column="pid" />
<many-to-many column="uid" class="User" />
</set>
3.修改User类,做对称修改
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(
name="user_product",
joinColumns=@JoinColumn(name="uid"),
inverseJoinColumns=@JoinColumn(name="pid")
)
public Set<Product> getProducts() {
return products;
}
4.修改User.hbm.xml,做对称修改
<set name="products" table="user_product" lazy="false">
<key column="uid" />
<many-to-many column="pid" class="Product" />
</set>
5.修改hibernate.cfg.xml,增加User类的映射
<mapping class="com.how2java.pojo.Product" />
<mapping class="com.how2java.pojo.Category" />
<mapping class="com.how2java.pojo.User" />
6.测试用栗TestHibernate
package com.how2java.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Product;
import com.how2java.pojo.User;
public class TestHibernate {
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
s.beginTransaction();
// //增加3个用户
Set<User> users = new HashSet();
for (int i = 0; i < 3; i++) {
User u =new User();
u.setName("user"+i);
users.add(u);
s.save(u);
}
//产品1被用户1,2,3购买
Product p1 = (Product) s.get(Product.class, 1);
p1.setUsers(users);
s.getTransaction().commit();
s.close();
sf.close();
}
}
XML配置方式:
优:容易编辑,配置比较集中,方便修改,在大业务量的系统里面,通过xml配置会方便后人理解整个系统的架构,修改之后直接重启应用即可
缺:比较繁琐,配置形态丑陋, 配置文件过多的时候难以管理
注解方式:
优:方便,简洁,配置信息和 Java 代码放在一起,有助于增强程序的内聚性
缺:分散到各个class文件中,所以不宜维护, 修改之后你需要重新打包,发布,重启应用
how2j站长个人体会:
小项目,参与人数不多,不复杂的用注解,开发快速
复杂项目,多人交互,配置量大,维护复杂度高的,用配置文件