Java 39---Hibernate框架(2)

导读

1.HQL查询
2.Hibernate命名查询,对原生SQL的支持,Criteria(了解)
3.集合属性
4.一对多,多对一及多对多关系
5.乐观锁与悲观锁
6.缓存:提高效率
7.Hibernate注解使用

HQL查询

工程结构
在这里插入图片描述
Book.java,
Book.hbm.xml,
HBUtil.java,
hibername.cfg.xml与基本查询一致

HQLTest.java

package com.hala.test;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;


import com.hala.dao.BookDao;
import com.hala.entity.Book;
import com.hala.util.HBUtil;

public class HQLTest {

	private Session session=null;
	private Transaction ts=null;
	private BookDao bd=new BookDao();
	
	@BeforeEach
	public void before() {
		// 1,2步在HBUtil类中封装执行
		// 3.创建session
		session = HBUtil.getSession();
		// 4.开启事务
		ts=session.beginTransaction();
		
	}
	
	
//	@Test
	public void deleteByPrice() {
		System.out.println(bd.deleteByPrice(session, 100));
	}
	
//	@Test
	public void queryNameAndPrice() {
		List<Object[]> books=bd.queryNameAndPrice(session);
		for (Object[] obj : books) {
			System.out.println("书名:"+obj[0]+" 价格:"+obj[1]);
		}
	}
	
//	@Test
	public void queryCountByAuthor() {
		List<Object[]> objs=bd.queryCountByAuthor(session);
		for (Object[] obj : objs) {
			System.out.println("作者:"+obj[1]+" 作品数量:"+obj[0]);
		}
	}
	
//	@Test
	public void queryPage() {
		List<Book> books=bd.queryPage(session, 1, 2);
		
		for (Book book : books) {
			System.out.println(book);
		}
	}
	
//	@Test
	public void addIntroductions() {
		Book book=(Book)session.get(Book.class,2);
		book.getIntroductions().add("wonderful!");
		book.getIntroductions().add("beautiful!!!");
		book.getIntroductions().add("extraordinary");
		
		session.save(book);
	}
	
	@AfterEach
	public void after() {
		//6.Hibernate不自动提交事务,需要手动
		ts.commit();
		//关闭会话
		session.close();
		//关闭会话工厂
		HBUtil.closeFactory();
	}
}

Book.Dao.java

package com.hala.dao;


import java.util.List;

import org.hibernate.Session;
import org.hibernate.query.Query;

import com.hala.entity.Book;

public class BookDao {
	
	/**
	 * 根据价格删除数据
	 * @param session price
	 * @return
	 */
	public int deleteByPrice(Session session,double price) {
		String hql="delete from Book where price>= ?1";
		Query query=session.createQuery(hql);
		//占位符下标从0开始
		query.setParameter(1, price);
		return query.executeUpdate();
	}

	/**
	 * 根据名字更改价格
	 * @param session
	 * @param name
	 * @param price
	 * @return
	 */
	public int updateByname(Session session,String name,double price) {
		String hql="update Book set price= :price where author= :author";
		Query query=session.createQuery(hql);
		query.setParameter("price", price);
		query.setParameter("author", name);
		return query.executeUpdate();
	}
	
	
	/**
	 * 查询所有(结果是一个集合)
	 * @param session
	 * @return
	 */
	public List<Book> queryAll(Session session){
		String hql="from Book";//相当于select * from book;
		Query query=session.createQuery(hql);
		return query.list();//可以执行查询语句,并将查询结果封装到list中
	}
	
	
	/**
	 * 根据id查询(结果只有一个)
	 * @param session
	 * @param id
	 * @return
	 */
	public Book queryById(Session session,int id) {
		String hql="from Book where id= :id";
		Query query=session.createQuery(hql).setParameter("id",id);
		return (Book)query.uniqueResult();//当查询结果只有单行时使用
	}
	
	
	/**
	 * 统计Book表里记录个数
	 * @param session
	 * @return
	 */
	public long queryCount(Session session){
		String hql="select count(1) from Book";
		return (long)session.createQuery(hql).uniqueResult();
	}
	
	/**
	 * 只查询名称和价格
	 * @param session
	 * @return
	 */
	public List<Object[]> queryNameAndPrice(Session session){
		//利用二维数组的思维
		String hql="select name,price from Book";
		return session.createQuery(hql).list();
	}
	
	/**
	 * 查询每个作者作品数量(分组查询)
	 * @param session
	 * @return
	 */
	public List<Object[]> queryCountByAuthor(Session session){
		String hql="select count(1),author from Book group by author";
		return session.createQuery(hql).list();
	}
	
	/**
	 * 分页查询
	 * 每当我们点击一页时,只查询这一页的数据
	 * hhibernate的分页方法对所有数据库都适用
	 * @param session
	 * @param currentPage :当前页数
	 * @param pageSize :每页显示多少条
	 * @return
	 */
	public List<Book> queryPage(Session session,int currentPage,int pageSize){
		String hql="from Book";
		List<Book> list=session.createQuery(hql)
				.setFirstResult((currentPage-1)*pageSize)//设置从第几条开始查,从0开始
				.setMaxResults(pageSize)//设置本次查询最多条数
				.list();
		
		return list;
	}
	
	
}

Hibernate命名查询,对原生SQL的支持,Criteria(了解)

在这里插入图片描述

在这里插入图片描述

集合属性

在这里插入图片描述

一对多,多对一及多对多关系

一对多,多对一

一个部门有多个员工
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一个部门有一个父部门,多个子部门(自身关联)

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

多对多关系

一个课程有多个学生选择,一个学生可以学多门课程

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

在这里插入图片描述

乐观锁与悲观锁

在hibernate配置文件中设置隔离级别

在这里插入图片描述

乐观锁

在数据库表中提供一个版本号的字段,每次提交数据时,hibernate会比对用户的versionno和数据库的versionno是否一致,如果一致,则允许提交,如果不一致,则阻止提交,每次提交之后,versionno会自动加1

在这里插入图片描述

在这里插入图片描述

隔离级别2+乐观锁≈隔离级别4

悲观锁

悲观锁很少被使用,他是一种独占的方法

基本原理:使用数据库的独占锁:select ....for update;

在这里插入图片描述

缓存:提高效率

1.缓存可以减少内存跟服务器的交互次数,从而提高程序效率
2.一级缓存:session,自动开启
3.Hibernate中对象的状态:
①临时状态: 使用new 关键字创建一个对象时,这个对象处于临时状态
②持久状态: 数据已经持久化,并且保存在session中
③游离状态: 数据已经持久化,但是不在session中
④删除状态: 调用delete方法,并且提交事务
4.二级缓存
针对需要频繁访问,且不会经常修改的数据,一般会将它们加入到二级缓存

在hibernate中使用二级缓存

在这里插入图片描述
上图是使用hibernate自带的,这种并不常用,常用的是下边使用第三方的,
第一步:将下图三个jar包导入工程
在这里插入图片描述
第二步:在hibernate.cfg.xml配置文件中配置
在这里插入图片描述

第三步:在官方下载的压缩包里搜索ehcache.xml文件,将其导入到工程src包下
可以指定自己的缓存区,如下KeyBoard缓存区

<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by
         its value in the running VM.

         The following properties are translated:
         user.home - User's home directory
         user.dir - User's current working directory
         java.io.tmpdir - Default temp file path -->
    <diskStore path="./target/tmp"/><!--当缓存在内存中过多时,转存到磁盘中的位置-->


    <!--Default Cache configuration. These will applied to caches programmatically created through
        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->
        <!-- 
            maxElementsInMemory:在内存中存放的最大对象数量
            eternal:缓存数据是否持久保存
            timeToIdleSeconds:eternal是false的情况下,允许对象最大处于空闲状态的时间,单位是秒,超过这个时间则被销毁
            timeToLiveSeconds:eternal是false的情况下,允许对象在缓存中最大存放时间,单位是秒,超过则销毁
            overflowToDisk:当内存满时,是否将缓存保存到磁盘
         -->
         <!-- 默认缓存区 -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!--Predefined caches.  Add your cache configuration settings here.
        If you do not have a configuration for your cache a WARNING will be issued when the
        CacheManager starts

        The following attributes are required for defaultCache:

        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->

    <!-- Sample cache named sampleCache1
        This cache contains a maximum in memory of 10000 elements, and will expire
        an element if it is idle for more than 5 minutes and lives for more than
        10 minutes.

        If there are more than 10000 elements it will overflow to the
        disk cache, which in this configuration will go to wherever java.io.tmp is
        defined on your system. On a standard Linux system this will be /tmp"
        -->
        <!-- 指定缓存区,将name指定的内容存到缓存区 -->
    <cache name="keyBoard"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <!-- Sample cache named sampleCache2
        This cache contains 1000 elements. Elements will always be held in memory.
        They are not expired. -->
    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> -->

    <!-- Place configuration for your caches following -->

</ehcache>

第四步:配置映射文件KeyBoard.hbm.xml文件

在这里插入图片描述

Hibernate注解使用

工程目录

在这里插入图片描述

注意导入的包是javax,不是hibernate
Person.java

package com.hala.entity;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="t_person")//指定表名,不加的话默认与实体类类名一致
public class Person {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)//id自增长
	@Column(name="person_id")//可以自定义在数据库中字段的名字
	private int id;
	@Basic//表示普通字段,可以省略
	private String name;
	@Basic
	private int age;
	@Basic
	private String gender;
	
	@Transient//表示忽略该属性,不会在表中建字段
	private int abc;
	
	
	
	
	
	
	public Person() {
		super();
	}
	
	
	
	
	
	
	public Person(String name, int age, String gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}






	public Person(int id, String name, int age, String gender) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.gender = gender;
	}

	


	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	
	
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}
	
	
	

}


配置文件

在这里插入图片描述

PersonTest.java

package com.hala.test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.hala.entity.Person;
import com.hala.util.HBUtil;

public class PersonTest {
	
	private Session session=null;
	private Transaction ts=null;
	
	@BeforeEach
	public void before() {
		// 1,2步在HBUtil类中封装执行
		// 3.创建session
		session = HBUtil.getSession();
		// 4.开启事务
		ts=session.beginTransaction();
		
	}
	
	@Test
	public void add() {
       
		Person person=new Person("hala",13,"male");
		session.save(person);
	}
	
	@AfterEach
	public void after() {
		//6.Hibernate不自动提交事务,需要手动
		ts.commit();
		//关闭会话
		session.close();
		//关闭会话工厂
		HBUtil.closeFactory();
	}

}

注解一对多,多对一,多对多关系

在这里插入图片描述

在这里插入图片描述

多对多建议拆封为两个一对多,中间表另建实体类

这里有一个问题,两个表主键用的是同一个序列,下边是修改方法

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值