Spring整合Hibernate映射关系注解版 -- 实例

关于延迟加载:

http://blog.csdn.net/z69183787/article/details/20049409

http://blog.csdn.net/z69183787/article/details/17136627

关于mappedby关键字 及一对多 更多的解释:

http://blog.csdn.net/z69183787/article/details/8197106

http://blog.csdn.net/z69183787/article/details/18615577


关系类型总结和对应的注解


1. Hibernate Annotation关系映射有下面几种类型:
1)一对一外键关联映射(单向)

2)一对一外键关联映射(双向)

3)一对一主键关联映射(不重要)在这不演示

在实际中很少用,使用注解@PrimaryKeyJoinColumn

意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用

注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML

映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。

因为在实际开发中一对一很少用。在实际开发中我机会没有用过,主键关联就更少了

4)多对一关联映射

5)一对多关联映射(单向)

6)一对多关联映射(双向)

7)多对多关联映射(单向)

8)多对多关联映射(双向)

 

2.介绍各种映射用法

1)一对一外键关联映射(单向)

@OneToOne(cascade=CascadeType.ALL)

@JoinColumn(name="userid",unique=true)

//一对一外键关联,使用@OneToOne,并设置了级联操作

//@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id

 //外键的值是唯一的(unique),不可重复,与另一类的主键一直

 

2)一对一外键关联映射(双向)

 Class1里与上面一样,  

   Class2:

@OneToOne(mappedBy="class2",cascade=CascadeType.ALL)

//一对一双向关联关系,使用@OneToOne

//注意:需要加上mappedBy="class2",如果不加上的话,

//Class2也会生成一个外键(class1_id)

//mappedby="class2"需要指向与他关联对象的一个属性

//说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的

//主体端负责维护联接列

//对于不需要维护这种关系的从表则通过mappedBy属性进行声明

//mappedBy的值指向主体的关联属性

//规律:只有是双向关联关系,都加上mappedby

    //cascade=CascadeType.ALL级联

 

4)多对一关联映射

在多的一端配置:

@ManyToOne(targetEntity=Organization.class)

@JoinColumn(name="orgid")

//多对一注解@ManyToOne

//targetEntity指定了关联对象

//@JoinColumn(name="orgid")指定生产的外键的字段名,默认是org_id

 

5)一对多关联映射(单向)


@OneToMany

@JoinColumn(name="orgid")

/**

 * 一对多注解@OneToMany(单向)

 * 如果只写@OneToMany的话,hibernate会建一张中间表来

 * 维护他们之间的关系,

 * 加上@JoinColumn(name="orgid"),则不会建中间表,他会在

 * 多的一端加上外键orgid,来维护他们之间的关系

 */

6)一对多关联映射(双向)

一端:


@OneToMany(mappedBy="org")

@JoinColumn(name="orgid")

/**

 * 一对多双向,在一的一端中设置mappedBy

 * 说明多的一端为主导

 * 如果指定了外键字段名称,则多的一端也需要指定相同的字段名称

 */

 

多端:

@ManyToOne

@JoinColumn(name="orgid")

/**

 * 一对多双向

 * 需要指定外键与一的一端给的外键名称一致,@JoinColumn(name="orgid")

 * 也可以不指定,如果在多的一端不指定,则一的一端也不能指定

 * 否则为生成两个外键

 */

 

7)多对多关联映射(单向)


 

@ManyToMany

/**

 * 多对多映射:注解@ManyToMany(单向)

 * 默认情况下,hibernate会自动的创建一张中间表,

 * 来维护多对多关系

 * 默认中间表的名称 :user_role中间表,字段的名称user_id role_id

 * 如果想更换表名和字段名称,注解如下:

 */

@JoinTable(name="t_u_r",

joinColumns={@JoinColumn(name="u_id")},

inverseJoinColumns={@JoinColumn(name="r_id")}

)

 

8)多对多关联映射(双向)  User端


@ManyToMany

/**

 * 多对多映射:注解@ManyToMany(单向)

 * 默认情况下,hibernate会自动的创建一张中间表,

 * 来维护多对多关系

 * 默认中间表的名称 :user_role中间表,字段的名称user_id role_id

 * 如果想更换表名和字段名称,注解如下:

 */

@JoinTable(name="t_u_r",

joinColumns={@JoinColumn(name="u_id")},

inverseJoinColumns={@JoinColumn(name="r_id")}

)

/**

 * @JoinTable(name="t_u_r",

 * 指定中间表的表名

 * joinColumns={@JoinColumn(name="u_id")},

 * 指定当前对象的外键

 * inverseJoinColumns={@JoinColumn(name="r_id")}

 * 指定关联对象的外键

 */

 

Role端

@ManyToMany(mappedBy="role")

/**

 * 多对多,双向关联映射

 */



1.多对多  -- 基于ACL的权限控制数据库设计3+2


数据表设计脚本

/*
Navicat MySQL Data Transfer

Source Server         : mysql
Source Server Version : 50527
Source Host           : localhost:3306
Source Database       : shiro

Target Server Type    : MYSQL
Target Server Version : 50527
File Encoding         : 65001

Date: 2014-08-20 17:13:20
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `tbl_permission`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_permission`;
CREATE TABLE `tbl_permission` (
  `PERMISSION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `PERMISSION_NAME` varchar(45) DEFAULT NULL,
  `createdTime` datetime DEFAULT NULL,
  `lastVisitTime` datetime DEFAULT NULL,
  `status` int(11) NOT NULL,
  `role` tinyblob,
  PRIMARY KEY (`PERMISSION_ID`),
  UNIQUE KEY `PERMISSION_NAME_UNIQUE` (`PERMISSION_NAME`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_permission
-- ----------------------------
INSERT INTO `tbl_permission` VALUES ('1', 'see', null, null, '0', null);
INSERT INTO `tbl_permission` VALUES ('2', 'check', null, null, '0', null);
INSERT INTO `tbl_permission` VALUES ('3', 'add', null, null, '0', null);
INSERT INTO `tbl_permission` VALUES ('4', 'delete', null, null, '0', null);

-- ----------------------------
-- Table structure for `tbl_permission_role`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_permission_role`;
CREATE TABLE `tbl_permission_role` (
  `ROLE_ID` int(11) NOT NULL,
  `PERMISSION_ID` int(11) NOT NULL,
  PRIMARY KEY (`ROLE_ID`,`PERMISSION_ID`),
  KEY `FKCD309665B1C23A26` (`ROLE_ID`),
  KEY `FKCD3096659AEFBE86` (`PERMISSION_ID`),
  CONSTRAINT `FKCD3096659AEFBE86` FOREIGN KEY (`PERMISSION_ID`) REFERENCES `tbl_permission` (`PERMISSION_ID`),
  CONSTRAINT `FKCD309665B1C23A26` FOREIGN KEY (`ROLE_ID`) REFERENCES `tbl_role` (`ROLE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_permission_role
-- ----------------------------
INSERT INTO `tbl_permission_role` VALUES ('1', '1');
INSERT INTO `tbl_permission_role` VALUES ('1', '2');
INSERT INTO `tbl_permission_role` VALUES ('1', '3');
INSERT INTO `tbl_permission_role` VALUES ('2', '4');

-- ----------------------------
-- Table structure for `tbl_role`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_role`;
CREATE TABLE `tbl_role` (
  `ROLE_ID` int(11) NOT NULL AUTO_INCREMENT,
  `ROLE_NAME` varchar(45) DEFAULT NULL,
  `createdTime` datetime DEFAULT NULL,
  `lastVisitTime` datetime DEFAULT NULL,
  `status` int(11) NOT NULL,
  `user_id` varchar(255) NOT NULL,
  PRIMARY KEY (`ROLE_ID`),
  UNIQUE KEY `ROLE_NAME_UNIQUE` (`ROLE_NAME`),
  KEY `FKFE6A057B1C23A26` (`ROLE_ID`),
  CONSTRAINT `FKFE6A057B1C23A26` FOREIGN KEY (`ROLE_ID`) REFERENCES `tbl_role` (`ROLE_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_role
-- ----------------------------
INSERT INTO `tbl_role` VALUES ('1', 'admin', null, null, '0', '');
INSERT INTO `tbl_role` VALUES ('2', 'manager', null, null, '0', '');
INSERT INTO `tbl_role` VALUES ('3', 'employee', null, null, '0', '');
INSERT INTO `tbl_role` VALUES ('4', 'clerk', null, null, '0', '');

-- ----------------------------
-- Table structure for `tbl_role_user`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_role_user`;
CREATE TABLE `tbl_role_user` (
  `ROLE_ID` int(11) NOT NULL,
  `USER_ID` int(11) NOT NULL,
  `tbl_role_role_id` int(11) NOT NULL,
  `userSet_user_id` varchar(255) NOT NULL,
  PRIMARY KEY (`ROLE_ID`,`USER_ID`),
  KEY `FK9124A2B3B1C23A26` (`ROLE_ID`),
  KEY `FK9124A2B356ECFE06` (`USER_ID`),
  CONSTRAINT `FK9124A2B356ECFE06` FOREIGN KEY (`USER_ID`) REFERENCES `tbl_user` (`USER_ID`),
  CONSTRAINT `FK9124A2B3B1C23A26` FOREIGN KEY (`ROLE_ID`) REFERENCES `tbl_role` (`ROLE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_role_user
-- ----------------------------
INSERT INTO `tbl_role_user` VALUES ('1', '1', '0', '');
INSERT INTO `tbl_role_user` VALUES ('2', '1', '0', '');
INSERT INTO `tbl_role_user` VALUES ('3', '1', '0', '');

-- ----------------------------
-- Table structure for `tbl_user`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
  `USER_ID` int(11) NOT NULL AUTO_INCREMENT,
  `USER_USERNAME` varchar(45) NOT NULL,
  `USER_PASSWORD` char(32) NOT NULL,
  PRIMARY KEY (`USER_ID`),
  UNIQUE KEY `USER_USERNAME_UNIQUE` (`USER_USERNAME`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_user
-- ----------------------------
INSERT INTO `tbl_user` VALUES ('1', 'aa', 'aa');



多对多映射关系

用户表User.java

package com.jay.demo.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
/**
 * 使用Hibernate的注解方式配置映射关系
 * @author He
 *
 */

/*@Entity 注解将一个类声明为实体 Bean, @Id 注解声明了该实体Bean的标识属性。
 * 
 * 当前类是一个持久化类User,映射的表示User,所对应的数据库时shiro
 * name    ---  表名
 * catelog ---  数据库名
 * 这句:@Table(catalog="shiro",name="tbl_user") 可以省略
 */
@Entity
@Table(catalog="shiro",name="tbl_user")
public class User extends BaseModel{
	private String id;
	private String username;
	private String password;
	private Set<Role> roleSet = new HashSet<Role>();
	
	public User() {
	}

	// 主键 :@Id    主键生成方式:strategy = "increment"
    //映射表中id这个字段,不能为空,并且是唯一的
	@Id
	@GenericGenerator(name="generator",strategy="increment")
	@GeneratedValue(generator="generator")
	@Column(name="user_id",unique=true, nullable=false)
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Column(name="user_username")
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Column(name="user_password")
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST},
			targetEntity=com.jay.demo.bean.Role.class,
			fetch=FetchType.EAGER)
	@JoinTable(  
            name="tbl_role_user",
            joinColumns={@JoinColumn(name="user_id")},  
            inverseJoinColumns={@JoinColumn(name="role_id")}  
    )
	public Set<Role> getRoleSet() {
		return roleSet;
	}

	public void setRoleSet(Set<Role> roleSet) {
		this.roleSet = roleSet;
	}

	
}



角色表Role.java


package com.jay.demo.bean;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(catalog="shiro",name="tbl_role")
public class Role extends BaseModel implements Serializable {

	private static final long serialVersionUID = -4987248128309954399L;

	private Integer id;
	private String name;
	
	private Set<User> userSet = new HashSet<User>();
	
	private Set<Permission> permissionSet = new HashSet<Permission>();

	public Role() {
		super();
	}
	
	// --------------------------------------------------------------------------------

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Role other = (Role) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	// --------------------------------------------------------------------------------

	@Id
	@Column(name="role_id")
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name="role_name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST},
	targetEntity=com.jay.demo.bean.Permission.class,
	fetch=FetchType.EAGER)
	@JoinTable(  
    name="tbl_permission_role",
    joinColumns={@JoinColumn(name="role_id")},  
    inverseJoinColumns={@JoinColumn(name="permission_id")}  
)
	public Set<Permission> getPermissionSet() {
		return permissionSet;
	}

	public void setPermissionSet(Set<Permission> permissionSet) {
		this.permissionSet = permissionSet;
	}

	@ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST},
//			mappedBy="roleSet",
			targetEntity=com.jay.demo.bean.User.class)
	public Set<User> getUserSet() {
		return userSet;
	}

	public void setUserSet(Set<User> userSet) {
		this.userSet = userSet;
	}

}



权限表Permission.java


package com.jay.demo.bean;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import com.jay.demo.bean.Role;
@Entity
@Table(catalog="shiro",name="tbl_permission")
public class Permission extends BaseModel implements Serializable {

	private static final long serialVersionUID = -8025597823572680802L;

	private Integer id;
	private String name;
	
	private Role role;

	public Permission() {
		super();
	}

	// --------------------------------------------------------------------------------------

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Permission other = (Permission) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	// --------------------------------------------------------------------------------------

	@Id
	@Column(name="Permission_id")
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name="Permission_name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

}




2.一对多和多对一关系映射注解版



一的一方:Category.java

package com.jay.demo.bean;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(catalog="shiro",name="tbl_category")
public class Category extends BaseModel implements Serializable{

	private static final long serialVersionUID = 1812600303779451508L;
	
	private String id;
	private String categoryName;
	private Set<Product> products = new HashSet<Product>();
	
	public Category() {
		super();
	}
	
	@Id
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getCategoryName() {
		return categoryName;
	}
	public void setCategoryName(String categoryName) {
		this.categoryName = categoryName;
	}
	
	@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="category")
	public Set<Product> getProducts() {
		return products;
	}
	public void setProducts(Set<Product> products) {
		this.products = products;
	}
	
	
	
}



多的一方:Product.java

package com.jay.demo.bean;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(catalog="shiro",name="tbl_product")
public class Product extends BaseModel implements Serializable{

	private static final long serialVersionUID = -7663728419648348545L;
	
	private String id;
	private String productName;
	private String price;
	private Category category;
	private Date inDate;
	private long count;
	
	@Id
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getProductName() {
		return productName;
	}
	public void setProductName(String productName) {
		this.productName = productName;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}
	@ManyToOne
	public Category getCategory() {
		return category;
	}
	public void setCategory(Category category) {
		this.category = category;
	}
	public Date getInDate() {
		return inDate;
	}
	public void setInDate(Date inDate) {
		this.inDate = inDate;
	}
	public long getCount() {
		return count;
	}
	public void setCount(long count) {
		this.count = count;
	}
	public Product() {
		super();
	}
	
	
}



一对多注解版的例子


首先是在hibernate.cfg.xml中引入要映射的class

 

<?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>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=GBK</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">sa</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="com.sszd.hibernate.Reader"/>
        <mapping class="com.sszd.hibernate.Book"/> 
    </session-factory>
</hibernate-configuration>


 

我们分别看看reader.java和book.java文件

Reader.java
 
package com.sszd.hibernate;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="reader")
public class Reader {
 @Id
 @Column(name="ID")
 @GeneratedValue(strategy=GenerationType.AUTO)
 private int id;
 @Column(name="MENO")
 private String meno;
 @Column(name="NAME")  
 private String name;
 @OneToMany(mappedBy = "reader", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 private Set<Book> books = new HashSet<Book>();
 public Reader()
 {
 }
 public Set getBooks() {
  return books;
 }
 public void setBooks(Set books) {
  this.books = books;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getMeno() {
  return meno;
 }
 public void setMeno(String meno) {
  this.meno = meno;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}
 
book.java
 
package com.sszd.hibernate;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="book")
public class Book {
 @Id
 @Column(name="ID")
 @GeneratedValue(strategy=GenerationType.AUTO) 
 private int id;
 @Column(name="TITLE")
 private String title;
 @ManyToOne(cascade = CascadeType.ALL, optional = false)
 @JoinColumn(name="rea_id", referencedColumnName="id")//外键为sut_id,与student中的id关联
 private Reader reader;
 public int getId() {
  return id;
 }
 public Reader getReader() {
  return reader;
 }
 public void setReader(Reader reader) {
  this.reader = reader;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
}
 
接下来是我们的本地测试用例
 
 
package com.sszd.main;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sszd.hibernate.Book;
import com.sszd.hibernate.Reader;
public class ReaderToBooks {
 private static  SessionFactory sessionFactory;
 
      public static void main(String[] args) {
 
   sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
 
Session session = sessionFactory.openSession();
 
Reader r = new Reader();
 
r.setName("Reader zhang");
 
Book b1 = new Book();
 
b1.setTitle("title1");
 
Book b2 = new Book();
 
b2.setTitle("title2");
 
b1.setReader(r);
b2.setReader(r);
r.getBooks().add(b1);
r.getBooks().add(b2);
 
Transaction trx = session.beginTransaction();
 
session.save(r);
 
trx.commit();
 
session.close();
}
}


一对多实例二


student:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  */  
  4. package com.wonders.task.sample.bo;  
  5.   
  6. import javax.persistence.CascadeType;  
  7. import javax.persistence.Column;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.GeneratedValue;  
  10. import javax.persistence.Id;  
  11. import javax.persistence.JoinColumn;  
  12. import javax.persistence.ManyToOne;  
  13. import javax.persistence.Table;  
  14.   
  15. import org.hibernate.annotations.GenericGenerator;  
  16.   
  17. /**  
  18.  * @ClassName: Student  
  19.  * @Description: TODO(这里用一句话描述这个类的作用)  
  20.  * @author zhoushun  
  21.  * @date 2014年2月27日 上午11:48:30  
  22.  *   
  23.  */  
  24.   
  25. @Entity   
  26. @Table(name="Z_STUDENT")   
  27. public class Student {  
  28.     private String id;  
  29.     private String name;  
  30.     private Clazz clazz;  
  31.       
  32.       
  33.     @Id  
  34.     @GeneratedValue(generator="system-uuid")  
  35.     @GenericGenerator(name="system-uuid", strategy = "uuid")  
  36.     @Column(name = "ID")  
  37.     public String getId() {  
  38.         return id;  
  39.     }  
  40.     public void setId(String id) {  
  41.         this.id = id;  
  42.     }  
  43.       
  44.     @Column(name = "NAME", length = 500)  
  45.     public String getName() {  
  46.         return name;  
  47.     }  
  48.     public void setName(String name) {  
  49.         this.name = name;  
  50.     }  
  51.       
  52.     @ManyToOne(cascade={CascadeType.ALL})           
  53.     @JoinColumn(name="class_id")     //student类中对应外键的属性:classid   
  54.     public Clazz getClazz() {  
  55.         return clazz;  
  56.     }  
  57.     public void setClazz(Clazz clazz) {  
  58.         this.clazz = clazz;  
  59.     }  
  60.       
  61.       
  62. }  

classes:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  */  
  4. package com.wonders.task.sample.bo;  
  5.   
  6. import java.util.Set;  
  7.   
  8. import javax.persistence.CascadeType;  
  9. import javax.persistence.Column;  
  10. import javax.persistence.Entity;  
  11. import javax.persistence.GeneratedValue;  
  12. import javax.persistence.Id;  
  13. import javax.persistence.OneToMany;  
  14. import javax.persistence.Table;  
  15.   
  16. import org.hibernate.annotations.GenericGenerator;  
  17.   
  18.   
  19. /**  
  20.  * @ClassName: Clazz  
  21.  * @Description: TODO(这里用一句话描述这个类的作用)  
  22.  * @author zhoushun  
  23.  * @date 2014年2月27日 上午11:48:47  
  24.  *   
  25.  */  
  26. @Entity   
  27. @Table(name="Z_CLASS")   
  28. public class Clazz implements java.io.Serializable{  
  29.     /** 
  30.      *  
  31.      */  
  32.     private static final long serialVersionUID = -6224738252966513441L;  
  33.     private String id;  
  34.     private String name;  
  35.     private Set<Student> set;  
  36.       
  37.     @Id  
  38.     @GeneratedValue(generator="system-uuid")  
  39.     @GenericGenerator(name="system-uuid", strategy = "uuid")  
  40.     @Column(name = "ID")  
  41.     public String getId() {  
  42.         return id;  
  43.     }  
  44.     public void setId(String id) {  
  45.         this.id = id;  
  46.     }  
  47.       
  48.     @Column(name = "NAME", length = 500)  
  49.     public String getName() {  
  50.         return name;  
  51.     }  
  52.     public void setName(String name) {  
  53.         this.name = name;  
  54.     }  
  55.       
  56.     @OneToMany(cascade=CascadeType.ALL,mappedBy="clazz")   
  57.        //@OneToMany(cascade=CascadeType.ALL,mappedBy="clazz",fetch=FetchType.EAGER) 关闭延迟加载。          
  58.     public Set<Student> getSet() {  
  59.         return set;  
  60.     }  
  61.     public void setSet(Set<Student> set) {  
  62.         this.set = set;  
  63.     }  
  64.       
  65.       
  66.       
  67. }  


main:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  */  
  4. package com.wonders.task.sample.main;  
  5.   
  6. import java.util.HashSet;  
  7. import java.util.Set;  
  8.   
  9. import javax.annotation.Resource;  
  10.   
  11. import org.hibernate.Hibernate;  
  12. import org.hibernate.Session;  
  13. import org.springframework.context.ApplicationContext;  
  14. import org.springframework.context.annotation.Scope;  
  15. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  16. import org.springframework.orm.hibernate3.HibernateTemplate;  
  17. import org.springframework.stereotype.Service;  
  18. import org.springframework.transaction.annotation.Propagation;  
  19. import org.springframework.transaction.annotation.Transactional;  
  20.   
  21. import com.wonders.schedule.util.SpringBeanUtil;  
  22. import com.wonders.task.sample.ITaskService;  
  23. import com.wonders.task.sample.bo.Clazz;  
  24. import com.wonders.task.sample.bo.Student;  
  25.   
  26. /**  
  27.  * @ClassName: TestMain  
  28.  * @Description: TODO(这里用一句话描述这个类的作用)  
  29.  * @author zhoushun  
  30.  * @date 2014年2月27日 下午12:18:44  
  31.  *   
  32.  */  
  33.   
  34. @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)  
  35. /* 功能模块入口点,beanid即数据库配置中的name */  
  36. @Service("testMain")  
  37. @Scope("prototype")  
  38. public class TestMain {  
  39.     private HibernateTemplate hibernateTemplate;  
  40.       
  41.     public HibernateTemplate getHibernateTemplate() {  
  42.         return hibernateTemplate;  
  43.     }  
  44.       
  45.     //注入hibernateTemplate  
  46.     @Resource(name="hibernateTemplate")  
  47.     public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {  
  48.         this.hibernateTemplate = hibernateTemplate;  
  49.     }  
  50.       
  51.     public void test(){  
  52.         Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();  
  53.         Clazz c2 = (Clazz) session.get(Clazz.class"8a81a97c4471c661014471c669360002");  
  54.         //Clazz c2 = (Clazz) main.getHibernateTemplate().get(Clazz.class, "8a81a97c4471c661014471c669360002");  
  55.         Hibernate.initialize(c2.getSet());  
  56.           
  57.         System.out.println("11111111111111111111111");  
  58.         //session.close();  
  59.         Set<Student> sss =  c2.getSet();  
  60.         System.out.println("22222222222222222");  
  61.         for(Student s: sss){  
  62.               
  63.             System.out.println(s.getName());  
  64.         }  
  65.     }  
  66.       
  67.     public static void main(String[] args){  
  68.         ApplicationContext applicationContext = null;    
  69.         String[] fileUrl = new String[]{"classpath*:applicationContext*.xml"};    
  70.         applicationContext = new ClassPathXmlApplicationContext(fileUrl);    
  71.           
  72.         Student s1 = new Student();  
  73.         Student s2 = new Student();  
  74.         Clazz c1 = new Clazz();  
  75.         c1.setName("1班");  
  76.         s1.setName("z1");  
  77.         s1.setClazz(c1);  
  78.         s2.setName("z2");  
  79.         s2.setClazz(c1);  
  80.         Set<Student> set = new HashSet<Student>();  
  81.         set.add(s1);set.add(s2);  
  82.         c1.setSet(set);  
  83.         TestMain main = (TestMain)SpringBeanUtil.getBean("testMain");  
  84.         //main.getHibernateTemplate().save(c1);  
  85.           
  86. //      Session session = main.getHibernateTemplate().getSessionFactory().openSession();  
  87. //      Clazz c2 = (Clazz) session.get(Clazz.class, "8a81a97c4471c661014471c669360002");  
  88. //      //Clazz c2 = (Clazz) main.getHibernateTemplate().get(Clazz.class, "8a81a97c4471c661014471c669360002");  
  89. //      Hibernate.initialize(c2.getSet());  
  90. //        
  91. //      System.out.println("11111111111111111111111");  
  92. //      session.close();  
  93. //      Set<Student> sss =  c2.getSet();  
  94. //      System.out.println("22222222222222222");  
  95. //      for(Student s: sss){  
  96. //            
  97. //          System.out.println(s.getName());  
  98. //      }  
  99.         main.test();  
  100.         //main.getHibernateTemplate().delete(c2);  
  101.     }  
  102. }  


级联保存

方法1:自动维护两表关系,mappedby 为被拥维护方,即对应的student为维护方

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student s1 = new Student();  
  2.         Student s2 = new Student();  
  3.         Clazz c1 = new Clazz();  
  4.         c1.setName("1班");  
  5.         s1.setName("z1");  
  6.         s1.setClazz(c1);  
  7.         s2.setName("z2");  
  8.         s2.setClazz(c1);  
  9.         TestMain main = (TestMain)SpringBeanUtil.getBean("testMain");  
  10.         main.getHibernateTemplate().save(s1);  
  11.         main.getHibernateTemplate().save(s2);  


方法2:手动维护,两方都需要set对应对方的变量

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student s1 = new Student();  
  2.         Student s2 = new Student();  
  3.         Clazz c1 = new Clazz();  
  4.         c1.setName("1班");  
  5.         s1.setName("z1");  
  6.         s1.setClazz(c1);  
  7.         s2.setName("z2");  
  8.         s2.setClazz(c1);  
  9.         Set<Student> set = new HashSet<Student>();    
  10.         set.add(s1);set.add(s2);  
  11.         c1.setSet(set);  
  12.         TestMain main = (TestMain)SpringBeanUtil.getBean("testMain");  
  13.         main.getHibernateTemplate().save(c1);  

关于延迟加载:

http://blog.csdn.net/z69183787/article/details/20049409

http://blog.csdn.net/z69183787/article/details/17136627

关于mappedby关键字 及一对多 更多的解释:

http://blog.csdn.net/z69183787/article/details/8197106

http://blog.csdn.net/z69183787/article/details/18615577



一对一基于主键的注解版关系映射


hibernate中一对一的关联有两种方式:一种是采用外键关联,另外一种是采用主键关联。 

项目中用到Hibernate(annotation注解方式)构建实体类,其中有一对一主键双向关联。期间遇到一些问题,现在贴出来探讨探讨。 一个帖子内容类(PostText)对应一个帖子信息类(Post),主要目标是在存储帖子或者帖子内容时,关联的对象也被存储。具体代码如下:

 

Java代码   收藏代码
  1. <span style="color: #0000ff;">Post类</span>  
Java代码   收藏代码
  1. @Entity  
  2. @Table(name = "posts")  
  3. public class Post implements Serializable {  
  4.   
  5.     @Id  
  6.     @GeneratedValue(strategy = GenerationType.AUTO) <span style="color: #ff0000;">//主键生成器</span>  
  7.     @Column(name="post_id",unique=true)  
  8.     private int id;  
  9.     @Column(name ="topic_id",nullable=false)  
  10.     private int topicId;  
  11.     @Column(name ="forum_id",nullable=false)  
  12.     private int forumId;  

 

Java代码   收藏代码
  1.     @OneToOne(cascade=CascadeType.ALL)  
  2.     @PrimaryKeyJoinColumn<span style="color: #ff0000;">//这个注解只能写在主(生成ID)的一端</span>  
  3. private PostText postText;  
Java代码   收藏代码
  1. <span style="color: #008000;">/*相应的get和set方法。。。*/ </span>  
Java代码   收藏代码
  1. <span style="color: #0000ff;">PostText类</span>   

  

Java代码   收藏代码
  1. @Entity  
  2. @Table(name = "jforum_posts_text")  
  3. public class PostText implements Serializable {  
  4.   
  5.     @Id  
  6.     @GenericGenerator(name ="pkGenerator",strategy="foreign" ,parameters={@Parameter(name="property",value="post")})  
  7.     @GeneratedValue(generator="pkGenerator")  
  8.     <span style="color: #ff0000;">//post_text的ID是根据post的ID来赋值的,这里需要设置ID生成器的策略为foreign,参数中指定post_text的ID是使用post对象中的ID</span>  
  9.     private int id;  
  10.     @Column(name ="post_text",nullable=true)  
  11.     private String text;  
  12.     @Column(name ="post_subject",nullable=true)  
  13.     private String subject;  
  14.     @OneToOne(cascade=CascadeType.ALL, mappedBy="postText")  <span style="color: #ff0000;">// 一对一</span>  
  15.     private Post post;  





各种关系映射总结



1.一对一主键关联  
这个在实际项目中用的比较少,大部分是通过用外键做关联的,这里用用户和手机号举个例子,用户和手机号是一对一的关系,代码如下:  
User实体 
Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Users implements Serializable{  
  6.   
  7.       private static final long serialVersionUID = 1381652232198529039L;  
  8.     private int id;  
  9.     private String username;  
  10.     private String password;  
  11.     private CellphoneNumber phoneNumber;  
  12.     public CellphoneNumber getPhoneNumber() {  
  13.         return phoneNumber;  
  14.     }  
  15.     public void setPhoneNumber(CellphoneNumber phoneNumber) {  
  16.         this.phoneNumber = phoneNumber;  
  17.     }  
  18.     public int getId() {  
  19.         return id;  
  20.     }  
  21.     public void setId(int id) {  
  22.         this.id = id;  
  23.     }  
  24.     public String getUsername() {  
  25.         return username;  
  26.     }  
  27.     public void setUsername(String username) {  
  28.         this.username = username;  
  29.     }  
  30.     public String getPassword() {  
  31.         return password;  
  32.     }  
  33.     public void setPassword(String password) {  
  34.         this.password = password;  
  35.     }  
  36.   
  37.       
  38. }  


手机号实体 
Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class CellphoneNumber implements Serializable {  
  6.       
  7.     private static final long serialVersionUID = -1029364968566042141L;  
  8.       
  9.     private Integer cellPhoneId;  
  10.     private String number;  
  11.     private String attribution;//手机归属地  
  12.     private String cellphonoeType;//移动或者联通  
  13.     private Users user ;  
  14.     public Users getUser() {  
  15.         return user;  
  16.     }  
  17.     public void setUser(Users user) {  
  18.         this.user = user;  
  19.     }  
  20.     public Integer getCellPhoneId() {  
  21.         return cellPhoneId;  
  22.     }  
  23.     public void setCellPhoneId(Integer cellPhoneId) {  
  24.         this.cellPhoneId = cellPhoneId;  
  25.     }  
  26.     public String getNumber() {  
  27.         return number;  
  28.     }  
  29.     public void setNumber(String number) {  
  30.         this.number = number;  
  31.     }  
  32.     public String getAttribution() {  
  33.         return attribution;  
  34.     }  
  35.     public void setAttribution(String attribution) {  
  36.         this.attribution = attribution;  
  37.     }  
  38.     public String getCellphonoeType() {  
  39.         return cellphonoeType;  
  40.     }  
  41.     public void setCellphonoeType(String cellphonoeType) {  
  42.         this.cellphonoeType = cellphonoeType;  
  43.     }  
  44.       
  45.     @Override  
  46.     public boolean equals(Object anotherObject){  
  47.         if(anotherObject == null || anotherObject.getClass() != this.getClass()){  
  48.             return false;  
  49.         }  
  50.         if(this == anotherObject){  
  51.             return true;  
  52.         }  
  53.           
  54.         CellphoneNumber another = (CellphoneNumber) anotherObject;  
  55.         if(another.cellPhoneId.equals(this.cellPhoneId)){  
  56.             return true  ;  
  57.         }  
  58.           
  59.         return false;  
  60.     }  
  61.       
  62.     public int hashCode(){  
  63.           
  64.         return cellPhoneId.hashCode();  
  65.     }  
  66.       
  67.       
  68. }  

users映射文件
Xml代码   收藏代码
  1.    <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping >  
  7.   
  8.         <class name="com.own.model.Users"  table="users"  dynamic-update="true"  dynamic-insert="true"     >  
  9.             
  10.            <id name="id"  column="id" >  
  11.               <generator class="native"></generator>  
  12.            </id>  
  13.              
  14.             <property name="username"  column="username"   ></property>    
  15.             <property name="password"  column="password" type="string"  ></property>    
  16.               
  17.             <!-- 这里是一对一映射 级联为所有 -->  
  18.             <one-to-one name="phoneNumber" class="com.own.model.CellphoneNumber" cascade="all"  >  
  19.               
  20.             </one-to-one>      
  21.               
  22.         </class>  
  23. </hibernate-mapping>  

cellPhone映射文件
Xml代码   收藏代码
  1.    <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping >  
  7.   
  8.         <class name="com.own.model.CellphoneNumber"  table="cellphone"  dynamic-update="true"  dynamic-insert="true"   >  
  9.            <!-- 这里设置外键关联 -->  
  10.            <id name="cellPhoneId"  column="id" >  
  11.               <generator class="foreign">  
  12.                   <!-- 这里设置用引用user实体的主键  -->  
  13.                 <param name="property">user</param>  
  14.               </generator>  
  15.            </id>  
  16.             <property name="number"  column="cellphoneNumber" ></property>    
  17.             <property name="attribution"  column="attribution"   ></property>    
  18.             <property name="cellphonoeType"  column="numberType"   ></property>    
  19.             <!-- 加上外键约束  ,使Cellphone的主键引用user表行的主键 -->  
  20.             <one-to-one name="user" constrained="true"  class="com.own.model.Users"  ></one-to-one>  
  21.         </class>  
  22. </hibernate-mapping>  

在调用时,要设置关联关系
Java代码   收藏代码
  1. Users u = new Users();    
  2.     u.setPassword("admin@1973");  
  3.     u.setUsername("floatSnow");  
  4.     CellphoneNumber cellphone = new CellphoneNumber();  
  5.     cellphone.setAttribution("北京");  
  6.     cellphone.setCellphonoeType("中国移动");  
  7.     cellphone.setNumber("13476534589");  
  8.     //设置双向关联关系  
  9.     u.setPhoneNumber(cellphone);  
  10.     cellphone.setUser(u);  


jpa中使用@PrimaryKeyJoinColumn  

Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3.   
  4. import java.io.Serializable;  
  5.   
  6. import javax.persistence.CascadeType;  
  7. import javax.persistence.Column;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.GeneratedValue;  
  10. import javax.persistence.Id;  
  11. import javax.persistence.OneToOne;  
  12. import javax.persistence.PrimaryKeyJoinColumn;  
  13. import javax.persistence.Table;  
  14. @Entity  
  15. @org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)  
  16. @Table(name="users")  
  17. public class Users implements Serializable{  
  18.     private static final long serialVersionUID = 1381652232198529039L;  
  19.     private int id;  
  20.     private String username;  
  21.     private String password;  
  22.     private CellphoneNumber cellphone;  
  23.       
  24.     @OneToOne(cascade={CascadeType.ALL})  
  25.     @PrimaryKeyJoinColumn  
  26.     public CellphoneNumber getCellphone() {  
  27.         return cellphone;  
  28.     }  
  29.     public void setCellphone(CellphoneNumber cellphone) {  
  30.         this.cellphone = cellphone;  
  31.     }  
  32.     @Id  
  33.     @GeneratedValue  
  34.     @Column(name="id")  
  35.     public int getId() {  
  36.         return id;  
  37.     }  
  38.     public void setId(int id) {  
  39.         this.id = id;  
  40.     }  
  41.       
  42.     @Column(name="username")  
  43.     public String getUsername() {  
  44.         return username;  
  45.     }  
  46.       
  47.     public void setUsername(String username) {  
  48.         this.username = username;  
  49.     }  
  50.       
  51.     @Column(name="password")  
  52.     public String getPassword() {  
  53.         return password;  
  54.     }  
  55.       
  56.     public void setPassword(String password) {  
  57.         this.password = password;  
  58.     }  
  59.   
  60.       
  61. }  


2.一对一外键关联  
hibernate xml文件映射,在这里使用manyToOne而不是我们想像的oneToOne,还有在  user表中加一个外键,引用另一个表的主键,这里设置双向关系,在项目中根据情况而定是否设置双向关系  
映射文件 
Xml代码   收藏代码
  1.   <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping >  
  7.         <class name="com.own.model.Users"  table="users"  dynamic-update="true"  dynamic-insert="true" >  
  8.            <id name="id"  column="id" >  
  9.               <generator class="native"></generator>  
  10.            </id>  
  11.             <property name="username"  column="username"   ></property>    
  12.             <property name="password"  column="password" type="string"  ></property>   
  13.             <!-- 加上唯一约束,使这个关系成为真正的一对一 -->   
  14.             <many-to-one name="phoneNumber" cascade="all" class="com.own.model.CellphoneNumber"  column="cell_id"    
  15.               unique="true"  >  
  16.             </many-to-one>  
  17.         </class>  
  18. </hibernate-mapping>  
  19.   
  20.    


jpa 映射使用oneToone,@joinColumn有两个属性 name 和 referencedColumnName 
,name是表示表中外键的列名,referencedColumnName表示外键引用的表的列名。 
user实体
Java代码   收藏代码
  1.    @OneToOne(cascade={CascadeType.ALL})  
  2.    @JoinColumn(name="cell_id",referencedColumnName="id")  
  3. public CellphoneNumber getCellphone() {  
  4.     return cellphone;  
  5. }  

手机实体类 
 
Java代码   收藏代码
  1.    
  2.  @OneToOne(mappedBy="cellphone")  
  3. ublic Users getU() {  
  4. return u;  

3.一对一可选关联  
有的时候我们的外键是可选的,也就是说user表的外键是可以为空的,这个时候我们可以把这中可选的关联映射到一张表,加一张中间表,表示实体的对应关系 
Users实体映射文件
 
Xml代码   收藏代码
  1.   <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping >  
  7.         <class name="com.own.model.Users"  table="users"  dynamic-update="true"  dynamic-insert="true" >  
  8.            <id name="id"  column="id" >  
  9.               <generator class="native"></generator>  
  10.            </id>  
  11.             <property name="username"  column="username"   ></property>    
  12.             <property name="password"  column="password" type="string"  ></property>   
  13.             <!-- 加上唯一约束,使这个关系成为真正的一对一 -->   
  14.             <!-- optional 告诉hibernate这个关系是可选的 ,当这个属性为空时,可以不插入关联表 -->  
  15.             <join table="user_cellphoneNumber"      >  
  16.               <key column="user_id"    unique="true"  />  
  17.                <many-to-one name="phoneNumber"  cascade="save-update"      class="com.own.model.CellphoneNumber"   column="cell_id"    
  18.               unique="true"     >  
  19.             </many-to-one>  
  20.             </join>  
  21.         </class>     
  22. </hibernate-mapping>  

jpa注解把属性映射到两张表,通过使用@SecondaryTable,使属性映射到一张中间表。  
Java代码   收藏代码
  1.    package com.own.model;  
  2.   
  3.   
  4. import java.io.Serializable;  
  5.   
  6. import javax.persistence.CascadeType;  
  7. import javax.persistence.Column;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.GeneratedValue;  
  10. import javax.persistence.Id;  
  11. import javax.persistence.JoinColumn;  
  12. import javax.persistence.OneToOne;  
  13. import javax.persistence.PrimaryKeyJoinColumn;  
  14. import javax.persistence.SecondaryTable;  
  15. import javax.persistence.Table;  
  16.   
  17. import org.hibernate.transaction.JOnASTransactionManagerLookup;  
  18. @Entity  
  19. @org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)  
  20. @Table(name="users")  
  21. @SecondaryTable(name="user_cellphoneNumber",pkJoinColumns={@PrimaryKeyJoinColumn(name="user_id",referencedColumnName="id")})  
  22. public class Users implements Serializable{  
  23.     private static final long serialVersionUID = 1381652232198529039L;  
  24.     private int id;  
  25.     private String username;  
  26.     private String password;  
  27.     private CellphoneNumber cellphone;  
  28.     @OneToOne(cascade={CascadeType.ALL})  
  29.     @JoinColumn(table="user_cellphoneNumber",name="cell_id",referencedColumnName="id")  
  30.     public CellphoneNumber getCellphone() {  
  31.         return cellphone;  
  32.     }  
  33.     public void setCellphone(CellphoneNumber cellphone) {  
  34.         this.cellphone = cellphone;  
  35.     }  
  36.     @Id  
  37.     @GeneratedValue  
  38.     @Column(name="id")  
  39.     public int getId() {  
  40.         return id;  
  41.     }  
  42.     public void setId(int id) {  
  43.         this.id = id;  
  44.     }  
  45.       
  46.     @Column(name="username")  
  47.     public String getUsername() {  
  48.         return username;  
  49.     }  
  50.       
  51.     public void setUsername(String username) {  
  52.         this.username = username;  
  53.     }  
  54.       
  55.     @Column(name="password")  
  56.     public String getPassword() {  
  57.         return password;  
  58.     }  
  59.       
  60.     public void setPassword(String password) {  
  61.         this.password = password;  
  62.     }  
  63.   
  64.       
  65. }       

4.一对多关联  
一对多关联通过oneToMany和ManyToMany映射,这里的多段在java里用一个集合set来表示,这个用商品category和货物Goods来举例子。 
one端实体Category 映射xml 

Xml代码   收藏代码
  1.  <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping >  
  7.         <class name="com.own.model.Category"  table="category"  dynamic-insert="true" dynamic-update="false"      >  
  8.            <id name="category_id"  column="id" >  
  9.               <generator class="native"></generator>  
  10.            </id>  
  11.             <property name="categoryName"  column="category_name" type="string"  ></property>   
  12.                
  13.             <set name="goodsSet" inverse="true"  cascade="save-update"   >    <!-- 用key column 的名字表示关联表的外键的名称  -->  
  14.                <key column="category_id"    />   
  15.                <one-to-many  class="com.own.model.Goods"   />   
  16.               </set>   
  17.         </class>  
  18. </hibernate-mapping>  

many端的映射文件  
Java代码   收藏代码
  1.     <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping   >  
  7.         <class name="com.own.model.Goods"  table="goods"  dynamic-insert="true" dynamic-update="false"      >  
  8.            <id name="id"  column="goods_id" >  
  9.               <generator class="native"></generator>  
  10.            </id>  
  11.             <property name="price"  column="goods_price" type="double"  ></property>    
  12.             <property name="goodsName"  column="goods_name" type="string"  ></property>    
  13.             <property name="goodsDescription"  column="goods_description" type="string"  ></property>    
  14.             <many-to-one name="category"      fetch="join"    class="com.own.model.Category"  column="category_id"      >  
  15.             </many-to-one>  
  16.         </class>  
  17.    
  18. </hibernate-mapping>  

jpa元数据注解 
Category实体
 
Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.HashSet;  
  5. import java.util.Set;  
  6.   
  7. import javax.persistence.CascadeType;  
  8. import javax.persistence.Column;  
  9. import javax.persistence.Entity;  
  10. import javax.persistence.GeneratedValue;  
  11. import javax.persistence.Id;  
  12. import javax.persistence.OneToMany;  
  13. import javax.persistence.Table;  
  14.   
  15. @Entity  
  16. @org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)  
  17. @Table(name="category")  
  18. public class Category implements Serializable {  
  19.     private static final long serialVersionUID = 1L;  
  20.     private Integer category_id;  
  21.     private String categoryName;  
  22.     private Set<Goods> goodsSet = new HashSet<Goods>();   
  23.       
  24.     @OneToMany(mappedBy="category",cascade={CascadeType.ALL})  
  25.     public Set<Goods> getGoodsSet() {  
  26.         return goodsSet;  
  27.     }  
  28.     public void setGoodsSet(Set<Goods> goodsSet) {  
  29.         this.goodsSet = goodsSet;  
  30.     }  
  31.     @Id  
  32.     @GeneratedValue  
  33.     @Column(name="id")  
  34.     public Integer getCategory_id() {  
  35.         return category_id;  
  36.     }  
  37.     public void setCategory_id(Integer categoryId) {  
  38.         category_id = categoryId;  
  39.     }  
  40.       
  41.     @Column(name="category_name")  
  42.     public String getCategoryName() {  
  43.         return categoryName;  
  44.     }  
  45.     public void setCategoryName(String categoryName) {  
  46.         this.categoryName = categoryName;  
  47.     }  
  48.   
  49.       
  50.       
  51. }  


Goods实体
Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3.   
  4. import java.io.Serializable;  
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.GeneratedValue;  
  8. import javax.persistence.GenerationType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.JoinColumn;  
  11. import javax.persistence.ManyToOne;  
  12. import javax.persistence.Table;  
  13.   
  14. @Entity  
  15. @org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)  
  16. @Table(name="goods")  
  17. public class Goods implements Serializable {  
  18.     private static final long serialVersionUID = 1L;  
  19.     private Integer id;  
  20.     private  String goodsName;  
  21.     private Double price;  
  22.     private String goodsDescription;      
  23.     private Category category;  
  24.     @ManyToOne  
  25.     @JoinColumn(name="category_id",referencedColumnName="id")  
  26.     public Category getCategory() {  
  27.         return category;  
  28.     }  
  29.   
  30.     public void setCategory(Category category) {  
  31.         this.category = category;  
  32.     }  
  33.   
  34.     public Goods(){}  
  35.       
  36.     @Id  
  37.     @GeneratedValue(strategy=GenerationType.AUTO)  
  38.     @Column(name="goods_id")  
  39.     public Integer getId() {  
  40.         return id;  
  41.     }  
  42.       
  43.     public void setId(Integer id) {  
  44.         this.id = id;  
  45.     }  
  46.       
  47.     @Column(name="goods_name",length=40,nullable=false)  
  48.     public String getGoodsName() {  
  49.         return goodsName;  
  50.     }  
  51.     public void setGoodsName(String goodsName) {  
  52.         this.goodsName = goodsName;  
  53.     }  
  54.       
  55.     @Column(name="goods_price")  
  56.     public Double getPrice() {  
  57.         return price;  
  58.     }  
  59.     public void setPrice(Double price) {  
  60.         this.price = price;  
  61.     }  
  62.       
  63.     @Column(name="goods_description")  
  64.     public String getGoodsDescription() {  
  65.         return goodsDescription;  
  66.     }  
  67.     public void setGoodsDescription(String goodsDescription) {  
  68.         this.goodsDescription = goodsDescription;  
  69.     }  
  70.   
  71.       
  72.     @Override  
  73.     public boolean equals(Object o) {  
  74.           
  75.         if(o == null || o.getClass() != this.getClass()){  
  76.             return false;  
  77.         }  
  78.           
  79.         if(o == this){  
  80.             return true;  
  81.         }  
  82.           
  83.         Goods goods = (Goods) o;  
  84.           
  85.         if(id == null ? goods.id == null : this.id.equals(goods.id)){  
  86.             return true;  
  87.         }  
  88.           
  89.           
  90.         return false;  
  91.     }  
  92.       
  93.     /*@Override 
  94.     public int hashCode() { 
  95.         //return this.id.hashCode(); 
  96.         return  
  97.     }*/  
  98.       
  99. }  


5.多对多关联  
多对多关联用manyToMany来映射,这里用学生和选的课程,它们是多对多的关联,多对对 
关联通常需要一张中间表,这个表就两字段,学生id和课程id(这里中间表就两个字段) 
在java中用两set集合来表示 
student 映射文件
 
Xml代码   收藏代码
  1.   <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5.   
  6. <hibernate-mapping >  
  7.         <class name="com.own.model.Student"  table="student"  dynamic-update="true"  dynamic-insert="true" >  
  8.            <id name="studentId"  column="id" >  
  9.               <generator class="native"></generator>  
  10.            </id>  
  11.             <property name="studentName"  column="student_name"   ></property>    
  12.             <property name="studentNum"  column="student_no" type="string"  ></property>   
  13.             <set name="cosrseSet"    table="student_course"  >  
  14.            <!--  引用当前实体主键的外键名称   -->     
  15.           <key  column="student_id"   />  
  16.               <many-to-many column="course_id"  class="com.own.model.Course"   ></many-to-many>  
  17.             </set>  
  18.         </class>  
  19. </hibernate-mapping>  

course映射文件
Xml代码   收藏代码
  1.   <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  5. <hibernate-mapping   >  
  6.         <class name="com.own.model.Course"  table="course"  dynamic-update="true"     dynamic-insert="true" >  
  7.            <id name="courseId"  column="id" >  
  8.               <generator class="native"></generator>  
  9.            </id>  
  10.             <property name="courseName"  column="course_name"   ></property>    
  11.             <property name="courseNum"   column="course_no"  ></property>   
  12.               
  13.           <set name="studentSet"  inverse="true"  cascade="all"    table="student_course"    >  
  14.               <key  column="course_id"   />  
  15.               <many-to-many column="student_id"  class="com.own.model.Student"   ></many-to-many>  
  16.            </set>  
  17.         </class>  
  18. </hibernate-mapping>  

jpa元数据 
Student实体
Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.HashSet;  
  5. import java.util.Set;  
  6. import javax.persistence.Column;  
  7. import javax.persistence.Entity;  
  8. import javax.persistence.GeneratedValue;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.JoinColumn;  
  11. import javax.persistence.JoinTable;  
  12. import javax.persistence.ManyToMany;  
  13. import javax.persistence.Table;  
  14. @Entity  
  15. @Table(name="student")  
  16. public class Student implements Serializable {  
  17.       
  18.     private static final long serialVersionUID = 1L;  
  19.     private Integer studentId;  
  20.     private String studentName;  
  21.     private String studentNum;  
  22.     private Set<Course> cosrseSet = new HashSet<Course>();  
  23.     @ManyToMany  
  24.     @JoinTable(name="student_course",joinColumns={@JoinColumn(name="student_id")},  
  25.                inverseJoinColumns={@JoinColumn(name="course_id")})  
  26.     public Set<Course> getCosrseSet() {  
  27.         return cosrseSet;  
  28.     }  
  29.     public void setCosrseSet(Set<Course> cosrseSet) {  
  30.         this.cosrseSet = cosrseSet;  
  31.     }  
  32.       
  33.     @Id  
  34.     @GeneratedValue  
  35.     @Column(name="id")  
  36.     public Integer getStudentId() {  
  37.         return studentId;  
  38.     }  
  39.     public void setStudentId(Integer studentId) {  
  40.         this.studentId = studentId;  
  41.     }  
  42.       
  43.     @Column(name="student_name")  
  44.     public String getStudentName() {  
  45.         return studentName;  
  46.     }  
  47.     public void setStudentName(String studentName) {  
  48.         this.studentName = studentName;  
  49.     }  
  50.       
  51.     @Column(name="student_no")  
  52.     public String getStudentNum() {  
  53.         return studentNum;  
  54.     }  
  55.     public void setStudentNum(String studentNum) {  
  56.         this.studentNum = studentNum;  
  57.     }  
  58.   
  59. }  

Course实体
Java代码   收藏代码
  1.   package com.own.model;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import java.util.HashSet;  
  6. import java.util.Set;  
  7.   
  8. import javax.persistence.Column;  
  9. import javax.persistence.Entity;  
  10. import javax.persistence.GeneratedValue;  
  11. import javax.persistence.Id;  
  12. import javax.persistence.ManyToMany;  
  13. import javax.persistence.Table;  
  14. @Entity  
  15. @Table(name="course")  
  16. public class Course implements Serializable {  
  17.     private static final long serialVersionUID = 1L;  
  18.     private Integer courseId;  
  19.     private String courseNum;  
  20.     private String courseName;  
  21.     private Set<Student> studentSet = new HashSet<Student>();  
  22.       
  23.     @ManyToMany(mappedBy="cosrseSet")  
  24.     public Set<Student> getStudentSet() {  
  25.         return studentSet;  
  26.     }  
  27.     public void setStudentSet(Set<Student> studentSet) {  
  28.         this.studentSet = studentSet;  
  29.     }  
  30.     @Id  
  31.     @GeneratedValue  
  32.     @Column(name="id")  
  33.     public Integer getCourseId() {  
  34.         return courseId;  
  35.     }  
  36.     public void setCourseId(Integer courseId) {  
  37.         this.courseId = courseId;  
  38.     }  
  39.       
  40.     @Column(name="course_no")  
  41.     public String getCourseNum() {  
  42.         return courseNum;  
  43.     }  
  44.     public void setCourseNum(String courseNum) {  
  45.         this.courseNum = courseNum;  
  46.     }  
  47.       
  48.     @Column(name="course_name")  
  49.     public String getCourseName() {  
  50.         return courseName;  
  51.     }  
  52.     public void setCourseName(String courseName) {  
  53.         this.courseName = courseName;  
  54.     }  
  55.   
  56.   /* @Override 
  57.    public boolean equals(Object o) { 
  58.      if(o == null || o.getClass() != Course.class){ 
  59.          return false; 
  60.      } 
  61.           
  62.      if(o == this){ 
  63.          return true;  
  64.      } 
  65.         
  66.      Course another = (Course)o; 
  67.      if(courseId == null ? another.courseId == null : courseId.equals(another.courseId)){ 
  68.          return true; 
  69.      } 
  70.       
  71.      return  false; 
  72.      
  73.   } 
  74.  
  75.   @Override 
  76.    public int hashCode() { 
  77.     return super.hashCode(); 
  78.      // return 1; 
  79.   }*/  
  80.      
  81.       
  82. }  


在多对对关联的情况下,用的是set集合,实体要实现hashcode和equals,不然在更新关联表的时候会更新不了,比如学生不在选择这门课程,从set集合中remove掉这个课程,然后更新这个学生实体,代码如下,在不实现hashcode和equals更新不会成功,只有实现了才可以,hibernate返回了自己写的集合,PersistenceSet而不是HashSet,这也是为什么我们在实体中写set接口,不能写HashSet ... = new HashSet,要用 Set ... = new HashSet 。
Java代码   收藏代码
  1. tc = session.beginTransaction();  
  2.    Student s1 = (Student) session.get(Student.class,9) ;  
  3.          Course c = new Course();  
  4.         s1.getCosrseSet().remove(c);  
  5.         session.update(s1);//更新学生的选课  
  6. tc.commit();  


最后讲解一下cascade和inverse这两个属性,刚用hibernate的时候也比较不理解,首先这两个属性没有任何关系,cascade表示级联,就是被关联的一段,比如cascade='save-update',级联保存和更新,在设置了cascade的端,保存这个对象,会一并保存关联的一端,省去了我们写保存关联端的代码,inverse表示有谁来维护关联,在一段设置inverse=true,则有关联对来维护关联关系,比如上面的例子,在course端设置了inverse=true,则有student来维护中间表,只有当插入student的时候,才向中间表插入数据,如果都设置inverse=true则会插入重复数据,如果不设置,则会出错,在jpa元数据注解中 用mappedBy来表示有那方来维护关联关系

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSH2框架是结合了Spring3.2、Struts2.3.4和Hibernate4.2三个框架的一种开发模式。它的目标是将这三个框架的优势结合起来,实现更高效、更方便的开发方式。 首先,Spring框架作为SSH2的核心框架,提供了Spring IOC容器和AOP特性。Spring能够管理对象的生命周期,简化了大量的配置和代码。它还提供了声明式事务管理和面向切面编程能力,极大地简化了事务处理和异常处理。 其次,Struts2作为SSH2的MVC框架,提供了强大的请求处理和表单验证功能。它基于标签和表达式语言,可以直接将页面元素和后台数据进行绑定,大大减少了前端和后台开发的工作量。Struts2还支持拦截器,能够方便地进行权限控制和请求的预处理。 最后,Hibernate作为SSH2的ORM框架,提供了面向对象的数据库访问方式。Hibernate能够将Java对象和数据库表进行映射,并提供了强大的查询和缓存功能。使用Hibernate,开发者可以将精力集在业务逻辑上,而不需要过多关注数据库操作的细节。 通过整合Spring、Struts2和Hibernate,SSH2框架能够极大地简化企业级应用的开发过程。开发者可以更专注于业务逻辑的设计和实现,而不需要关心框架的集成和配置。同时,SSH2框架还提供了良好的扩展性和灵活性,可以根据项目需求进行定制和拓展。 总而言之,SSH2框架是一种结合了Spring、Struts2和Hibernate的开发模式,通过整合三个框架的优势,提供了更高效、更方便的开发方式。它简化了项目的配置和集成,提高了开发效率,是开发企业级应用的优秀选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值