注解方式实现级联
时间:2022-06-17
本文章向大家介绍注解方式实现级联,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
级联
级联分为一对多,多对一单向,多对多双向关联。一般情况下,我们只会用到前两种情况,多对多用的较少。我这里使用省市区三级联查来实现级联的操作。简单来说,一对多就是一个省下面有多个市,一个市下面有多个县。多对一是刚好反过来的。
首先是使用配置文件的情况下,关联类,生成的hbm.xml文件中显示如下:
<hibernate-mapping>
<class name="com.qy.domain.Province" table="province" schema="java1807">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="code" column="code"/>
<property name="name" column="name"/>
<!--
name:当前类的属性名
column:从表中的外键名
foreign-key:主表中的被参照字段
property-ref:主表中被参照字段的属性名
class:从表的类
lazy:true 使用懒加载机制 默认
lazy:false 放弃懒加载
inverse:true 放弃主控权
inverse:false 默认
-->
<set name="cities" cascade="all" lazy="true" inverse="true">
<key column="provincecode" foreign-key="code" property-ref="code"></key>
<one-to-many class="com.qy.domain.City"></one-to-many>
</set>
</class>
</hibernate-mapping>
hibernate.hbm.xml配置如下:
<mapping class="com.qy.domain.Province"></mapping>
<mapping class="com.qy.domain.City"></mapping>
<mapping class="com.qy.domain.Area"></mapping>
使用注解:
就是把mapping配置文件跟换掉。注解方式不需要在xxx.hbm.xml把实体类与表进行映射。而采用在实体类中进行注解。
注意:
(1):如果实体类属性名与表字段名不一致的时候,要么都注解在属性前,要么都注解在get方法前。不能部分注解在属性前,部分注解在方法前。
(2):如果实体类属性名与表字段名一致的时候,可以部分注解在属性前,部分注解在方法前。
(3):如果在实体类中某些属性不注解:(属性和get都不写注解),默认为表字段名与实体类属性名一致。
(4):如果实体类的某个成员属性不需要对这个成员属性进行映射))
(5):表名称可以在实体类前进行注解。
(6):所有这些注解在:javax.persistence包下。而不是在hibernate包中
<mapping resource="Area.hbm.xml"/>
<mapping resource="City.hbm.xml"/>
<mapping resource="Province.hbm.xml"/>
实体类配置如下:
@Entity
@Table(name = "province",schema = "java1807")
public class Province implements Serializable {
private int id;
private String code;
private String name;
private Set<City> cities=new HashSet<>();
@Id
@Column(name ="id")
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="code")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade= CascadeType.ALL,mappedBy ="province")
public Set<City> getCities() {
return cities;
}
public void setCities(Set<City> cities) {
this.cities = cities;
}
public Province() {
}
public Province(int id, String code, String name) {
this.id = id;
this.code = code;
this.name = name;
}
@Override
public String toString() {
return "Province{" +
"id=" + id +
", code='" + code + ''' +
", name='" + name + ''' +
'}';
}
}
多对一关联
city.hbm.xml文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.qy.domain.City" table="city" schema="java1807">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="code" column="code"/>
<property name="name" column="name"/>
<!--
多对一关联
name:city中属性名province
colum:city表中对应的列名
class:属性名province对应的对象类
如果通过主键关联不需要配置property-ref
如果不通过主键关联需要配置property-ref:指向Province类中参照的属性名
cascade:save-update,强制级联更新
-->
<many-to-one name="province" class="com.qy.domain.Province" property-ref="code" cascade="all">
<column name="provincecode"></column>
</many-to-one>
</class>
</hibernate-mapping>
使用注解对city进行改进,实体类配置如下:
@Entity
@Table(name="city",schema = "java1807")
public class City {
private int id;
private String code;
private String name;
/*private String provincecode;*/
private Province province;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="code")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/* public String getProvincecode() {
return provincecode;
}
public void setProvincecode(String provincecode) {
this.provincecode = provincecode;
}*/
@ManyToOne(targetEntity = Province.class)
@JoinColumn(name="provincecode",referencedColumnName = "code")
public Province getProvince() {
return province;
}
public void setProvince(Province province) {
this.province = province;
}
@Override
public String toString() {
return "City{" +
"id=" + id +
", code='" + code + ''' +
", name='" + name + ''' +
'}';
}
}
这是我写的测试类,对级联进行增删查改功能。
public class Test2 {
@Test
public void testQuary(){
Session session = HibernateUtill.getCurrentSession();
List<Province> list = session.createQuery("from Province").list();
HibernateUtill.sessionClose(session);
}
@Test
public void testSave(){
Session session = HibernateUtill.getCurrentSession();
session.beginTransaction();
Province p = new Province();
p.setName("腾飞省");
p.setCode("830000");
Set<City> cities = new HashSet<City>();
City c1 = new City();
c1.setName("腾飞市1");
c1.setCode("830100");
City c2 = new City();
c2.setName("腾飞市2");
c2.setCode("830200");
cities.add(c1);
cities.add(c2);
p.setCities(cities);
session.save(p);
session.getTransaction().commit();
HibernateUtill.sessionClose(session);
}
@Test
public void testUpdate(){
Session session = HibernateUtill.getCurrentSession();
session.beginTransaction();
Province p = session.get(Province.class,39);
p.setName("腾飞市");
Set set = p.getCities();
Iterator it = set.iterator();
int i =1;
while(it.hasNext()){
City c = (City) it.next();
c.setName("腾飞"+i++);
}
session.update(p);
session.getTransaction().commit();
HibernateUtill.sessionClose(session);
}
@Test
public void testDelete(){
Session session = HibernateUtill.getCurrentSession();
session.beginTransaction();
Province p = session.get(Province.class,39);
session.delete(p);
session.getTransaction().commit();
HibernateUtill.sessionClose(session);
}
总结
注解相对于配置文件更加简单,但还是没有配置文件好理解,建议新手还是先回使用配置文件。
- Android新手之旅(2) 新手问题
- Android新手之旅(2) 新手问题
- Android新手之旅(9) 自定义的折线图
- 2018春节抢票攻略:不仅仅是12306微信小程序启用
- Android新手之旅(9) 自定义的折线图
- Android新手之旅(11) 在现有页面中插入新的view
- Docker容器学习梳理--容器间网络通信设置(Pipework和Open vSwitch)
- 温故而知新:Asp.Net中如何正确使用Session
- Android新手之旅(13) listview中数据重复的问题
- 温故而知新:HttpApplication,HttpModule,HttpContext及Asp.Net页生命周期
- proxy_pass反向代理配置中url后面加不加/的说明
- Android新手之旅(10) 嵌套布局
- C#代码也VB
- Docker容器学习梳理--SSH方式登陆容器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP使用glob方法遍历文件夹下所有文件的实例
- Python图像阈值化处理及算法比对实例解析
- 浅析Python 条件控制语句
- 浅谈Django前端后端值传递问题
- sklearn和keras的数据切分与交叉验证的实例详解
- django Model层常用验证器及自定义验证器详解
- PyQT5 实现快捷键复制表格数据的方法示例
- Python爬虫headers处理及网络超时问题解决方案
- python报错: 'list' object has no attribute 'shape'的解决
- Python应用实现双指数函数及拟合代码实例
- 浅谈django不使用restframework自定义接口与使用的区别
- 实例解析php的数据类型
- 实现PHP中session存储及删除变量
- php微信公众号开发之秒杀
- php fread函数使用方法总结