Hibernate之one-to-many XML 篇一

工作之余弄了一下Hibernate的ORM关系,不敢说深入,只当作学习之后的一点点总结:
Hibernate在J2EE的Web开发中已经使用得比较广泛了,为此了解Hibernate的一些常用操作是非常必要的。下面将通过简单的事例来了解Hibernate ont-to-many/many-to-one双向配置、inverse、cascade的常用配置:
一、首现创建简单的数据库Table:user<用户>以及book<图书> 这里假设user与book的关系是一对多,创建代码如下:
MySql下:
(1)创建user Table:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `uid` int(11) NOT NULL auto_increment,
  `uname` varchar(255) NOT NULL,
  PRIMARY KEY  (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=latin1;
(2)创建book Table:
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
  `bid` int(11) NOT NULL auto_increment,
  `bname` varchar(20) NOT NULL,
  `buid` int(11) NOT NULL,
  PRIMARY KEY  (`bid`),
  KEY `FK_USER` (`buid`),
  CONSTRAINT `FK_USER` FOREIGN KEY (`buid`) REFERENCES `user` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1;

二、编写相印的Entity Class,这里用的是XML配置方法,有关Annotation将在以后的文章中发表,
(1)User Entity:
public class User implements java.io.Serializable {
// Fields
private Integer uid;
private String uname;
private Set books = new HashSet(0); //one-to-many关系,作为one的一方使用Set来存储many方的数据表示

// Constructors

public User() {
}
get....
set...方法
}

(2)Book Entity:
public class Book implements java.io.Serializable {
// Fields
private Integer bid;
private User user; //one一方的实体对象<数据库关系是通过外键来关联,即:book表中有user 表的ID外键>
private String bname;

// Constructors
public Book() {
}

get....
set...方法
}

三、有关ORM隐射文件:
(1)User.hbm.xml:


(2)Book.hbm.xml:
     

  
           
           
       
        
       
       
         
       
        
       
           
       
   

好,至此上面的配置已经完成,下面是测试代码:
一、测试级联添加:
public static void ontToManyAdd_User() {
//获取Session/并打开事务
SessionFactory factory = HibernateSessionFactory.getSessionFactory();
Session session = factory.openSession();
Transaction st = session.beginTransaction();
try {

//创建User对象
User user = new User();
user.setUname("A");

//创建Book对象,并存储至Set集合中
Set book_set = new HashSet();
Book book1 = new Book();
book1.setBname("Java");
Book book2 = new Book();
book2.setBname("C++");
Book book3 = new Book();
book3.setBname("Net");

book_set.add(book1);
book_set.add(book2);
book_set.add(book3);
//设置Book对象中的User对象属性 注意:一定要设置该属性如果不设定,将不能级联添加Book
book1.setUser(user);
book2.setUser(user);
book3.setUser(user);

user.setBooks(book_set);

session.save(user);
st.commit();
System.out.println("添加成功!");
} catch (Exception e) {
System.out.println(e.getMessage());
st.rollback();
} finally {
session.close();
}
}
上面的代码测试结果如下:
Hibernate: insert into hibernate_db.user (uname) values (?)
Hibernate: insert into hibernate_db.book (buid, bname) values (?, ?)
Hibernate: insert into hibernate_db.book (buid, bname) values (?, ?)
Hibernate: insert into hibernate_db.book (buid, bname) values (?, ?)
添加成功!
在上面的代码以及配置中需要注意的有一下几点:
<1>、
book1.setUser(user);
book2.setUser(user);
book3.setUser(user);
设置book对象中的User对象属性,因为数据库中book表中的uid字段为not null所以此时需要为Book Entity中的User 对象设置属性,如果不设置则会出现一下错误:
Hibernate: insert into hibernate_db.user (uname) values (?)
Hibernate: insert into hibernate_db.book (buid, bname) values (?, ?)
could not insert: [com.model.Book]
提示不能insert Book对象中。
<2>、
User.hbm.xml中的 cascade的配置,这个属性可以简单的理解为:"级联操作的类型" ,这里 的cascade="all" 意思是:不管当前操作User对象是增删改还是查 都将对User中的books这个集合进行级联操作,当然还可以设为其他的属性值,如:save-update、、、、cascade的使用场合:当操作其中一个或者一些元素,但是又需要级联到操作到另外一个元素时就需要为此配置。比方说这里的User对象:当添加一个User时需要级联添加N个Book那么就需要为User中的Book集合对象books设定cascade属性,当然在Book中也是设定cascade属性去级联操作User对象。

二、
测试级联查询:
public static void ontToManySelect() {
SessionFactory factory = HibernateSessionFactory.getSessionFactory();
Session session = factory.openSession();
try {
//获取User对象
User user = (User) session.get(User.class, 27);
System.out.println("User_Name:" + user.getUname());
//session.close(); //代码1
if (user != null) {
//获取User对象中的books集合数据
Iterator iter = user.getBooks().iterator();
while (iter.hasNext()) {
Book b = iter.next();
System.out.println("\t Book_Name:" + b.getBname());
}
}

} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
session.close();
}
}
在上面的级联查询代码中有一个细节需要我们注意的:
User.hbm.xml 中 Set 里面的lazy属性配置,其含义是懒加载,作用可以简单的理解为:“当加载一个或者一些元素的时候 是否也相印的加载这个元素中相关联的其他元素”,在Hibernate默认的配置中lazy的属性值是true,即:不主动去加载其相关的元素,这样有个好处,那就是在我们需要的时候才去查询,怎么才算是需要的时候呢?比方说上面的:Iterator iter = user.getBooks().iterator();这里当我们使用到User对象中相关联元素的时候,Hibernate才会发出Sql语句去查询。但是这样也会遇到一个问题:那就是 当在用到相关对象之前 (如:注释中的代码1),Hibernate的Session如果关闭了那么就不能再获取到该对象了。这个时候如果再在视图层或者后台中读取其相关的属性时就会出现:
Session was already closed 错误
所以在使用中还得看各自的需求来配置lazy。



上面已经简述完了one-to-many以及many-to-one的双向关系,其实还是有许多的东西需要我们实际操作中才会遇到以及学习到。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值