Hibernate框架-02-01-Hibernate单实体映射


持久化类的配置文件

class元素

<class> 元素用于指定类和表之间的映射。
name - 设定类名(包含路径);
table - 设定表名,默认以类名作表名。
<class>元素包含一个子元素及多个<property>子元素。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.hibernate.entity">
	<!-- 类与表的映射 -->
	<class name="User" table="USER">
		<!-- 上面的类名与数据库名之所以可以简写,是因为	hibernate-mapping package属性规定了文件所处的包名 -->
		<!-- 主键的映射,必选 -->
				
		
		
		<id name="id">
			<!-- 数据库的字段 -->
			<column name="ID"></column>
			<generator class="native"/>
		</id>		
		
		
	<!--column可以通过嵌套的形式放在id标签里面 ,和上面那种形式等价
		<id name="id" column="ID">
			<generator class="native"/>
		</id>	
	 -->			
		

		
		
		<!-- id标签只有一个,且必须在property标签上面 -->
		<property name="name" column="NAME" type="java.lang.String"></property>
		<property name="password" column="PASSWORD"></property>	
	</class>
	
</hibernate-mapping>


id元素

<id> 子元素设定持久化类的 OID(对象标识符) 和表的主键的映射关系。
column – 指定表字段的名称;
generator – 元素指定 OID 的生成器。

property元素

<property>子元素设定类的其它属性和表的字段的映射关系。
name – 对应类的属性名称;
type – 指定属性的类型;可选
column – 指定表字段的名称;
not-null – 指定属性是否允许为空。

type的String类型因为是引用类型,所以得用全线命名java.lang.String,但是基本类型不需要,直接写int,char 什么的就行

column也是可选的,前提是字段名与属性名时一致的。即name属性值与column属性值时一样的

增删改查操作的实现

在这里插入图片描述

package com.hibernate.ui;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.entity.User;
import com.hibernate.util.HibernateUtil;

public class Test {
    
    

	public static void main(String[] args) {
    
    
//		saveUser();
//		getUserById();
		updateUser();
		//deleteUser();
		
		//关闭SessionFactory
		HibernateUtil.closeSessionFactory();
	}
	
	
	/*
	 * 增添操作
	 * */
	public static void saveUser() {
    
    
		Session session = null;
		Transaction tx = null;
		
		try {
    
    
			//1. 打开Session
			session=HibernateUtil.openSession();
			//2. 开启数据库事务
			tx = session.beginTransaction();
			//3. 保存操作
			User user=new User();
			user.setName("李四");
			user.setPassword("LiSi");
			session.save(user);
			//4. 提交事务
			tx.commit();
		} catch (Exception e) {
    
    
			//捕获异常,事务回滚
			tx.rollback();
		} finally {
    
    
			//5. 关闭Sesson,回收资源
			session.close();
		}		

	}
	
	/*
	 * 查询操作
	 * */
	public static void getUserById() {
    
    
		//得到Session对象
		Session session=HibernateUtil.openSession();
		//参数1:要查询的对象类型,参数2:主键数值,最好是引用类型而不是基本类型
		User user=session.get(User.class,new Integer(2));
		System.out.println(user);
		//打印时候为了美观,记得重写User类的toString方法
		session.close();
	}
	
	/*
	 * 更新操作
	 * */
	public static void updateUser() {
    
    
		Session session = null;
		Transaction tx = null;
		
		try {
    
    
			//1. 打开Session
			session=HibernateUtil.openSession();
			//2. 开启数据库事务
			tx = session.beginTransaction();
			//3. 更新操作(先查询,再修改,最后更新)
			User user=session.get(User.class, new Integer(2));
			user.setPassword("LiSi-2");
			session.update(user);
			//update方法更新时候,那条数据的所有项都更新了,哪怕没有变化
			session.save(user);
			
			//4. 提交事务
			tx.commit();
		} catch (Exception e) {
    
    
			//捕获异常,事务回滚
			tx.rollback();
		} finally {
    
    
			//5. 关闭Sesson,回收资源
			session.close();
		}
	}
	
	/*
	 * 删除操作
	 * */	
	public static void deleteUser() {
    
    
		Session session = null;
		Transaction tx = null;
		
		try {
    
    
			//1. 打开Session
			session=HibernateUtil.openSession();
			//2. 开启数据库事务
			tx = session.beginTransaction();
			//3.删除操作(先找到,再删除),实际删除的是数据库中的那条记录
			User user=session.get(User.class, new Integer(1));
			session.delete(user);			
			//4. 提交事务
			tx.commit();
		} catch (Exception e) {
    
    
			//捕获异常,事务回滚
			tx.rollback();
		} finally {
    
    
			//5. 关闭Sesson,回收资源
			session.close();
		}
	}
	
	
	
	
}

单实体的属性映射

在这里插入图片描述

如果实体化类里没有相应的get与set方法是,就会找不到对性的数据进而无法实现实例化,这是Hibernate的默认访问对象属性的方法
在这里插入图片描述

实体类属性与表字段不对称时映射

在这里插入图片描述

需要查询非直接数据库数据时

在这里插入图片描述

例如,在user表中添加了totalOrders属性,需要查询订单表中的所有消费总额。

先创建订单数据库表,orders,属性为:
在这里插入图片描述

在这里插入图片描述
然后在user用户对象中增添上totalPrice属性,并设置相应的get与set方法,并且重写构造方法与toString方法,
在持久化类的配置文件中增添相应的属性

在这里插入图片描述

因为修改的是查询操作,所以在测试类中每当使用查询操作时候就可以看到效果了。
在这里插入图片描述

Hibernate的初始化

在这里插入图片描述
在这里插入图片描述

单实体的对象标识符映射

在这里插入图片描述

自然组件:例如学生的学号,具有一定的实际意义。
代理主键方式更常见。

在这里插入图片描述

Hibernate对象标识符 OID (区分对象)

在这里插入图片描述

帮助Hibernate区分在内存中这两个对象是不是同一个对象。

在这里插入图片描述
U1查询时第一次,内存无,是真正的查询
U2会判断内存有无结果,因为U1=U2所以,U2不查询,直接赋U1值

在这里插入图片描述
因为包装里面都是引用类型,所以为了方便定义OID时候采用包装器类型。

因为主键唯一,所以OID也唯一。

映射文件中OID的配置

在这里插入图片描述
generator 规定了OID的生成方式

Hibernate 自带了很多种标识符生成器:

increment  采用 Hibernate 数值递增的方式;
identity 采用数据库提供的自增长方式;
assigned 主键由应用逻辑产生;
---------上面三种是重点

sequence 采用数据库提供的序列方式;
hilo 通过hi/lo算法   // Hibernate 5.0 以后不支持;,高低位算法
seqhilo 通过hi/lo算法;
native 自动选择合适的标识符生成器;
uuid.hex 通过uuid算法。

increment标识符适用范围

在这里插入图片描述

由Hibernate程序生成;

在这里插入图片描述

先查数据库主键最大值,最大值+1在存入数据库新的数据。
SQL语句里有拼接的主键

identity标识符适用范围

在这里插入图片描述

在这里插入图片描述

SQL语句里没有ID字段,因为数据库可以自动递增主键

assigned 标识符适用范围

由程序内部赋值,插入之前需要手动赋值,不赋值的话不会执行插入语句。
这种方式强烈不建议,人为操作可能出现重复。
在这里插入图片描述
在这里插入图片描述

在程序内部赋值

注解映射单实体

注解映射配置的时候,只需要修改实体化类就可以,不用再创建实体化类的配置文件了。
不推荐,因为不美观,不清晰,重点还是上面的XML配置

在这里插入图片描述

@Entity:声明一个实体类。

@Table(name="table_name"):为实体类指定对应的数据库表。name就是表的名字

@Id:声明实体类的OID属性。

@GeneratedValue(generator="increment_generator"):声明OID的生成策略。

@GenericGenerator(name="increment_generator", strategy="increment"):使用Hibernate提供的生成策略。
先定义生成器,选择生存策略,然后被上面的注解调用。

映射什么属性,就加上什么Column注解
属性名与数据库字段名一致时也可以省略
在这里插入图片描述

配置映射文件源

在这里插入图片描述

package com.hibernate.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
//声明一个实体类
@Table(name="CUSTOMER")
//为实体类指定对应的数据库


public class Customer {
    
    
	private Integer id;
	private String name;
	private int age;

	//创建两个构造方法,一个有参数,一个无参数,缺一不可
	public Customer() {
    
    
		super();
	}
	public Customer(Integer id, String name, int age) {
    
    
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	
	
	@Id
	//定义生成策略与别名,注意位置,在get,set方法之上
	@GeneratedValue(generator = "linshi")
	//应用下面定义的策略
	@GenericGenerator(strategy="increment",name = "linshi")
	//私有属性的get set方法
	
//	@Column(name="id")  主键id自增长,所以可以注释掉
	public Integer getId() {
    
    
		return id;
	}
	public void setId(Integer id) {
    
    
		this.id = id;
	}
	@Column(name="name")
	public String getName() {
    
    
		return name;
	}
	public void setName(String name) {
    
    
		this.name = name;
	}
	@Column(name="age")
	public int getAge() {
    
    
		return age;
	}
	public void setAge(int age) {
    
    
		this.age = age;
	}
	
	
	
	
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

@Override
	public String toString() {
    
    
		return "Customer [sum=" + sum + "]";
	}


	@Formula(value="(select sum(o.age) from customer as o where o.id>10)")
	public int getSum() {
    
    
		return sum;
	}
	public void setSum(int sum) {
    
    
		this.sum = sum;
	}

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44627608/article/details/114294553