什么是关联(association)?
关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。例如:
class B{
private String name;
}
public class A{
private B b = new B;
public A(){}
}
关联的分类:关联可以分为一对一、一对多/多对一、多对多关联
关联是有方向的
Hibrnate一对多实现
数据库t_hibernate_order_item
t_hibernate_order
实现类和实现类配置
订单实体类
1 public class Order { 2 private Integer orderId; 3 private String orderNo; 4 //建立了关联关系 一个订单对应着多个订单 5 private List<OrderItem> orderItems=new ArrayList<>(); 6 private Integer initChildren =0;//0是懒加载 1:false 11 12 13 public Integer getInitChildren() { 14 return initChildren; 15 } 16 public void setInitChildren(Integer initChildren) { 17 this.initChildren = initChildren; 18 } 19 public List<OrderItem> getOrderItems() { 20 return orderItems; 21 } 22 public void setOrderItems(List<OrderItem> orderItems) { 23 this.orderItems = orderItems; 24 } 25 public Integer getOrderId() { 26 return orderId; 27 } 28 public void setOrderId(Integer orderId) { 29 this.orderId = orderId; 30 } 31 public String getOrderNo() { 32 return orderNo; 33 } 34 public void setOrderNo(String orderNo) { 35 this.orderNo = orderNo; 36 } 37 @Override 38 public String toString() { 39 return "Order [orderId=" + orderId + ", orderNo=" + orderNo + "]"; 40 } 41 42 43 }
订单实体类配置
1 <hibernate-mapping> 2 3 <class name="three.entity.Order" table="t_hibernate_order"> 4 <id name="orderId" type="java.lang.Integer" column="order_id"> 5 <generator class="increment" /> 6 </id> 7 <property name="orderNo" type="java.lang.String" column="order_no"> 8 </property> 9 <!-- 10 bag标签:是否横加载,默认是懒加载的 true 懒汉模式 11 name:类的关联属性名 12 cascade: 级联关系 级联新增与修改 13 inverse: 关联关系交给对方控制默认true,当前类不维护关联关系 14 15 16 子标签key: 17 colunn:主表的主键:从表的外键 18 子标签one—to-many: 19 class:外检对应的实体类 20 --> 21 <bag lazy="false" name="orderItems" cascade="save-update" inverse="true" > 22 <key column="oid"></key> 23 <one-to-many class="three.entity.OrderItem"/> 24 </bag> 25 26 </class> 27 28 </hibernate-mapping>
订单项实体类
1 public class OrderItem { 2 private Integer orderItemId; 3 private Integer productId; 4 private Integer quantity; 5 private Integer oid; 6 //建立关联关系 一个订单对应的是一个订单 7 private Order order; 8 9 10 public Order getOrder() { 11 return order; 12 } 13 public void setOrder(Order order) { 14 this.order = order; 15 } 16 public Integer getOrderItemId() { 17 return orderItemId; 18 } 19 public void setOrderItemId(Integer orderItemId) { 20 this.orderItemId = orderItemId; 21 } 22 public Integer getProductId() { 23 return productId; 24 } 25 public void setProductId(Integer productId) { 26 this.productId = productId; 27 } 28 public Integer getQuantity() { 29 return quantity; 30 } 31 public void setQuantity(Integer quantity) { 32 this.quantity = quantity; 33 } 34 public Integer getOid() { 35 return oid; 36 } 37 public void setOid(Integer oid) { 38 this.oid = oid; 39 } 40 @Override 41 public String toString() { 42 return "OrderItem [orderItemId=" + orderItemId + ", productId=" + productId + ", quantity=" + quantity 43 + ", oid=" + oid + "]"; 44 } 45 46 47 }
订单项配置
1 <hibernate-mapping> 2 <class name="three.entity.OrderItem" table="t_hibernate_order_item"> 3 <id name="orderItemId" type="java.lang.Integer" column="order_item_id"> 4 <generator class="increment" /> 5 </id> 6 <property name="productId" type="java.lang.Integer" column="product_id"> 7 </property> 8 <property name="quantity" type="java.lang.Integer" column="quantity"> 9 </property> 10 <property name="oid" type="java.lang.Integer" column="oid" insert="false" update="false"> 11 </property> 12 <many-to-one name="order" class="three.entity.Order" column="oid"></many-to-one> 13 </class> 14 </hibernate-mapping>
dao方法
1 public class DemoDao { 2 /** 3 * 为了测试关系型映射文件配置准确 4 * 讲解insert=false,update=false的用途 5 * @param order 6 * @return 7 */ 8 public Integer addOrder(Order order) { 9 Session session = SessionFactoryUtils.openSession(); 10 Transaction transaction = session.beginTransaction(); 11 Integer oid = (Integer)session.save(order); 12 transaction.commit(); 13 session.close(); 14 return oid; 15 } 16 17 public Integer addOrderItem(OrderItem orderItem) { 18 Session session = SessionFactoryUtils.openSession(); 19 Transaction transaction = session.beginTransaction(); 20 Integer otid = (Integer)session.save(orderItem); 21 transaction.commit(); 22 session.close(); 23 return otid; 24 } 25 26 27 28 /** 29 * 为了讲解懒加载的问题(hibernate3.0后所有查询方式默认采用的是懒加载方式) 30 * 1、查单个时存在问题,代理对象已经关闭 31 * 2、查多个存在问题,有性能的问题 32 * @param order 33 * @return 34 */ 35 public Order getOrder(Order order) { 36 Session session = SessionFactoryUtils.openSession(); 37 Transaction transaction = session.beginTransaction(); 38 Order o = session.get(Order.class, order.getOrderId()); 39 if(o != null && new Integer(1).equals(order.getInitChildren())) { 40 //强制加载关联对象 41 Hibernate.initialize(o.getOrderItems()); 42 // System.out.println(o.getOrderItems()); 43 } 44 transaction.commit(); 45 session.close(); 46 return o; 47 } 48 49 public List<Order> getOrderList() { 50 Session session = SessionFactoryUtils.openSession(); 51 Transaction transaction = session.beginTransaction(); 52 List<Order> list = session.createQuery("from Order").list(); 53 transaction.commit(); 54 session.close(); 55 return list; 56 } 57 58 /** 59 * z主表的数据不能随便删除,得先删除从表中对应信息,才能删除主表的信息。 60 * @param order 61 */ 62 public void delOrder(Order order) { 63 Session session = SessionFactoryUtils.openSession(); 64 Transaction transaction = session.beginTransaction(); 65 Order order2 = session.get(Order.class, order.getOrderId()); 66 for (OrderItem oi : order2.getOrderItems()) { 67 session.delete(oi); 68 } 69 session.delete(order2); 70 // session.delete(order); 71 transaction.commit(); 72 session.close(); 73 } 74 75 }
DemoDaoTest junit测试类
public class DemoDaoTest { private DemoDao demoDao =new DemoDao(); // @Before // public void setUp() throws Exception { // System.out.println("加载资源的"); // } // // @After // public void tearDown() throws Exception { // System.out.println("释放资源的"); // } @Test public void testAddOrder() { Order order=new Order(); order.setOrderNo("P20"); OrderItem orderItem=null; for(int i=0;i<6;i++) { orderItem =new OrderItem(); orderItem.setProductId(10+i); orderItem.setQuantity(20+i); //维护关联关系 orderItem.setOrder(order); order.getOrderItems().add(orderItem); } demoDao.addOrder(order); } @Test public void testAddOrderItem() { OrderItem orderItem=null; for(int i=0;i<6;i++) { orderItem =new OrderItem(); orderItem.setProductId(10+i); orderItem.setQuantity(20+i); //维护关联关系 Order order=new Order(); order.setOrderId(3); order.getOrderItems().add(orderItem); orderItem.setOrder(order); demoDao.addOrderItem(orderItem); } } @Test public void testGetOrder() { Order order=new Order(); order.setOrderId(4); order.setInitChildren(1); Order o=this.demoDao.getOrder(order); //failed to lazily initialize a collection of role: //three.entity.Order.orderItems, //could not initialize proxy - no Session //原因, 操作了两次数据库,当lazy=false的时候,会让hibernate执行完两次操作,session才会关闭 //当lazy=true 的时候,会让hibernate执行完一次操作,session就会关闭 //从上面看lazy=false更好 但是为什么hibernate默认让他等于true //出于性能的考虑 所以hibernate3.0出现lazy这个属性,并让他默认等于true,也就是说不加载关联属性 List<OrderItem> orderItems=o.getOrderItems(); for(OrderItem orderItem : orderItems) { System.out.println(orderItem); } System.out.println(o); } @Test public void testGetOrderList() { List<Order> orderList=this.demoDao.getOrderList(); for(Order order : orderList) { for(OrderItem orderItem : order.getOrderItems()) { System.out.println(orderItem); } System.out.println(order); } } @Test public void testDelOrder() { Order order=new Order(); order.setOrderId(4); this.demoDao.delOrder(order); } }
以上有详细的代码,大家可以去测试测试
hibernate框架一对多 的执行原理:
1 hibernate框架一对多 的执行原理: 2 3 1、对hibernate. cfg. xml进行建模,等到sessionfactory对象2、并且拿到mapping resource里 的内容3、拿到了Order . hbm . xm1配置文佳 4 5 4、可以再次建模,拿到了three . entity. Order,以及t_ hibernate_ order 6 7 类属性、以及表列段 8 9 5、生成动态的sql. select orderId, orderNo from t_hibernate_order; 10 11 孰行sql最終得到meterDat a源数据模型 12 13 orderId, orderNo 14 1 P15 15 5 P67 16 7 P78 17 8 P1019 18 9 P20 19 20 6、Order o1 = Class. forName( "three . entity . Order") . newInstance(0): 21 22 o1. setOrderId(1); 23 o1. setOrderNo(p1) 24 25 最終得到: 26 List<Order> list = new ArrayList();1ist.add(o1); 27 最終1ist中的所有order突例都有値了; (这里只是出来里面的非外键列段,原理完全跟basedao一样) 28 7.处理关联关系:orderIems 哦i的three.entity.OrderItem 29 30 通过one-to-many这个标签以及class对应的全路径名会找对 应的全路径名队员的专属类 31 也就是找到了Order.item.xml这个文件,拿到了他之后就可以拿到table t_hibernate_order_item 32 8.select * from t_hibernate_order_item; 33 34 最终得到了一个list<OrderItem> orderItems 35 9.给order的关联关系属性赋值 36 List<Order> List=new ArrayList(); 37 for(Order o : list){ 38 o.setOrderItems(orderItems); 39 }