Hibernate学习笔记-操作部分

Hibernate学习笔记-操作部分

教程来自:https://how2j.cn/

  • 使用JDBC做数据库相关功能开发会做很多重复性的工作,比如创建连接,关闭连接,把字段逐一映射到属性中。
    Hibernate把这一切都封装起来了,使得数据库访问变得轻松而简单,代码也更加容易维护。

一、Hibernate操作

1. 插入

hibernate的基本步骤是:

  1. 获取SessionFactory
  2. 通过SessionFactory 获取一个Session
  3. 在Session基础上开启一个事务
  4. 通过调用Session的save方法把对象保存到数据库
  5. 提交事务
  6. 关闭Session
  7. 关闭SessionFactory
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import bean.Person;

public class testHibernate {
	public static void main(String[] args) {

		SessionFactory sf = new Configuration().configure().buildSessionFactory();

		Session s = sf.openSession();
		s.beginTransaction();

		Person p = new Person();
		p.setName("郭");
		p.setAge(70);
		s.save(p);

		s.getTransaction().commit();
		s.close();
		sf.close();
	}

}

2. 获取

		Person pGet = (Person) s.get(Person.class, 355);

获取与插入都需要先使用Session开启事务,使用id获取需要知道id,并且需要类对象,获取后需要转型为对应的类。

3. 删除

Person pGet = (Person) s.get(Person.class, 355);
s.delete(pGet);

删除需要先获取id对应的对象。

4. 更新

Person pGet2 = (Person) s.get(Person.class, 532);
pGet2.setName("hahaha");
s.update(pGet);

5. hql查询

		String name = "guo";
		Query q = s.createQuery("from Person p where p.name like ?0");
		q.setParameter(0, "%" + name + "%");
		List<Person> ps = q.list();

查询使用HQL语句,这里进行模糊查询,可以看到查询语句中用的不是表名person而是类名称Person,?0表示插入地点,setParameter函数类似ps.setString。Query对象有list()函数可以返回模糊查询结果列表。

6. criteria查询

暂时没搞懂

7. sql查询

String sql = "select * from person p where p.name like '%" + name + "%'";
Query sqlq = s.createSQLQuery(sql);
List<Object[]> pl = sqlq.list();
for (Object[] os : pl) {
	for (Object o : os) {
		System.out.print(o + "\t");
	}
	System.out.println();
}

结果:
sql查询结果


二、Hibernate关系

实体类对象在Hibernate中有3种状态
分别是瞬时,持久和脱管

瞬时 指的是没有和hibernate发生任何关系,在数据库中也没有对应的记录,一旦JVM结束,这个对象也就消失了
持久 指得是一个对象和hibernate发生联系,有对应的session,并且在数据库中有对应的一条记录
脱管 指的是一个对象虽然在数据库中有对应的一条记录,但是它所对应的session已经关闭了

p.setName("郭");
//此时为瞬时状态
s.save(p);
//此时为持久状态
s.getTransaction().commit();
s.close();
//此时为脱管状态

1. 多对一

准备Category类:

package bean;

public class Category {

	private int id;
	private String name;

	public int getId() {
		return this.id;
	}

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

	public String getname() {
		return this.name;
	}

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

准备Category.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 package="bean">
    <class name="Category" table="category_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
    </class>
     
</hibernate-mapping>

这里会自动创建category_表,但必须在hibernate.cfg.xml中添加:

        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

表示使用MySQL55Dialect方言,这样才能自动创建表,并且添加外键的表与外键所在表的字符编码形式应该一样,比如都为utf-8。


为Person类添加Category属性

private Category category;

public Category getCategory() {
	return this.category;
}

public void setCategory(Category category) {
	this.category = category;
}

在Product.hbm.xml中设置Category 多对一关系映射
<many-to-one name="category" class="Category" column="cid"/>
<?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 package="bean">
    <class name="Person" table="person">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        <property name="age" />
        <property name="IQ" />
        <property name="energy" />
        <many-to-one name="category" class="Category" column="cid"/>
    </class>

</hibernate-mapping>

这里在运行时会自动在person表内创建cid列

2. 一对多

一对多的意思就是一个category对应多个person

在Category类里添加Set<Person>集合属性persons

private Set<Person> persons;
public Set<Person> getPersons() {
	return this.persons;
}

public void setPersons(Set<Person> persons) {
	this.persons = persons;
}

在Category.hbm.xml中添加one-to-many映射
        <set name="persons" lazy="false">
            <key column="cid" not-null="false"/>
            <one-to-many class="Person"/>
        </set>

<set 用于设置一对多(多对多也是他)关系,也可以用list,设置稍复杂点,这里使用简单的set来入门。
name=“products”   对应 Category类中的persons属性
lazy=“false”  表示不使用延迟加载。关于延迟加载,请参考关系的延迟加载
<key column=“cid” not-null=“false” />  表示外键是cid,可以为空
<one-to-many class=“Product” />  表示一对多所对应的类是Product




测试一对多关系:

package test;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import bean.Category;
import bean.Person;

public class testcategory {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();

		Session s = sf.openSession();
		s.beginTransaction();

//		Category c = new Category();
//		c.setName("c1");
//		s.save(c);
//
//		Person p = (Person) s.get(Person.class, 400);
//		p.setCategory(c);
//		s.update(p);
		Category c = (Category) s.get(Category.class, 2);
		Set<Person> ps = c.getPersons();
		for (Person p : ps) {
			System.out.println(p);
		}
		s.getTransaction().commit();
		s.close();
		sf.close();
	}
}

测试结果:
一对多结果



3.多对多

测试多对多关系
多对多关系相当于一个人可以在各个学校中读小学、初中、高中,每所学校也是各个人的母校,即多对多的关系。many-to-many
要实现多对多关系,必须有一张中间表 person_school 用于维护 Person和School之间的关系

下面是School类,包含name、id、Person集合

package bean;

import java.util.Set;

public class School {
	private int id;
	private String name;
	private Set<Person> persons;

	public String getName() {
		return this.name;
	}

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

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

	public int getId() {
		return this.id;
	}

	public Set<Person> getPersons() {
		return this.persons;
	}

	public void setPersons(Set<Person> persons) {
		this.persons = persons;
	}
}

下面是Person类,包含各个属性以及一个School集合

package bean;

import java.util.Set;

public class Person {
	private String name;
	private int age;
	private int IQ;
	private int energy;
	private int id;
	private Category category;
	private Set<School> schools;

	static String copyright;

	// 使用static修饰代码块时,类对象被JVM被加载时就会执行,
	//且只会加载一次。不加static则会在每次实例化时执行
	static {
		System.out.println("Person类对象初始化 copyright by Arlen");
		copyright = "由Arlen所有权";
	}

	public Person() {

	}

	// 增加一个初始化name的构造方法
	public Person(String name) {

		this.name = name;
	}

	public Person(String name, int age) {

		this.name = name;
		this.age = age;
	}

	public Person(String name, int age, int iq) {

		this.name = name;
		this.age = age;
		this.IQ = iq;
	}

	public String getName() {
		return this.name;
	}

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

	public int getIQ() {
		return this.IQ;
	}

	public void setIQ(int iq) {
		this.IQ = iq;
	}

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

	public int getId() {
		return this.id;
	}

	public int getAge() {
		return this.age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getEnergy() {
		return this.energy;
	}

	public void setEnergy(int energy) {
		this.energy = energy;
	}

	public Category getCategory() {
		return this.category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public Set<School> getSchools() {
		return this.schools;
	}

	public void setSchools(Set<School> schools) {
		this.schools = schools;
	}

添加School.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 package="bean">
    <class name="School" table="school">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        
        <set name="persons" table="person_school" lazy="false">
            <key column="sid"/>
            <many-to-many column="pid" class="Person"/>
        </set>
    </class>

</hibernate-mapping>

<set>段设置了映射关系,name属性表示School里的persons集合,table属性表示中间表,lazy表示懒加载。

<key column>设置为’sid’,表示school的主键’id’与中间表中’sid’外键关联。

<many-to-many>段column设置为’pid’,中间表中表示Person的主键’id’与中间表的’pid’外键关联。

在Person.hbm.xml中添加多对多映射

<set name="schools" table="person_school" lazy="false">
    <key column="pid"/>
    <many-to-many column="sid" class="School"/>
</set>

测试中间表

package test;

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

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import bean.Person;
import bean.School;

public class testManyToMany_School {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();

		Session s = sf.openSession();
		s.beginTransaction();

		// 增加3个人物
		Set<Person> persons = new HashSet();
		for (int i = 0; i < 3; i++) {
			Person p = new Person();
			p.setName("user" + i);
			persons.add(p);
			s.save(p);
		}

		// 学校1是人物1、2、3的母校
		//School s1 = new School();
	    //s1.setName("HUST");
		//s.save(s1);
		School s2 = (School) s.get(School.class, 1);

		s2.setPersons(persons);
		s.save(s2);
		s.getTransaction().commit();
		s.close();
		sf.close();
	}
}

console结果
多对多console结果
mysql结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值