Hibernate(一)

Hibernate

一、Hibernate概述

Hibernate是使用在三层架构中的dao层的一个框架,与JDBC和myBatis是类似的技术,它也是基于ORM(对象关系映射:数据表中的字段和实体类中的属性一一对应)设计的,其实就是对JDBC的封装,封装之后的东西使用起来更加方便快捷。
Hibernate是一个全自动的ORM框架,而myBatis是一个半自动的ORM框架,全自动代表数据表,SQL语句会自动生成,弊端在于不够灵活,效率低,而mybatis可以字节写sql语句非常灵活。国内更加青睐于myBatis。半自动表示,数据查出来之后可以自动封装到JavaBean(实体类/pojo/entity)中。
JavaBean:类中的属性全部私有,必须有一个无参的构造方法,必须有get和set方法
我们需要通过反射调用无参构造创建对象并且调用set方法给对象赋值,完成数据的自动注入。

二、Hibernate快速入门

2.1、导包

在这里插入图片描述

2.2、创建实体类

创建一个User类
在这里插入图片描述

2.3、创建实体类的映射文件

注:建议写在实体类包下,名字为实体类名.hbm.xml
约束到资料中的dtd文件中找

<?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>
	<!-- 1 配置实体类的映射文件
		使用class标签:将数据表和实体类一一对应,可以参考mybatis中的resultMap标签
		name:实体类的全路径
		table:表名,可以在核心配置文件中设置自动在数据库中生成表,要保证对应的数据库存在
	 -->
	 <class name="com.zhiyou100.javabean.User" table="tb_user">	 
		 <!--2  配置主键映射:	 使用id标签
				 	column:数据表中的字段名 (可以不写默认与name属性值一样)
				 	name:实体类中的属性名
				 	type:字段的数据类型 (可以不写,会自动根据实体类匹配)
		 -->
		 <id name="u_id">
		 	<!-- 
			设置主键生成策略:
				increment:主键按数值顺序递增,用在mysql上
				sequence:采用数据库提供的sequence 机制生成主键。如Oralce中的Sequence
				native:由  Hibernate   根据使用的数据库自行判断,可以自己判断出使用的数据库是oracle还是mysql
			 -->			
			 <generator class="native"></generator>		 
		 </id>
		 <!-- 3 配置其他字段的映射 -->
		 <property name="u_name"/>
		 <property name="u_pass"/>
	 </class>
</hibernate-mapping>

在这里插入图片描述

2.4、创建核心配置文件

要求:创建在src下,名字是hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- 第一部分:数据库部分–>
<property name=“hibernate.connection.driver_class”>com.mysql.jdbc.Driver</property>
<!-- 如果数据库连接的本机并且端口是3306可以直接写成jdbc:mysql:///数据库名 -->
<property name=“hibernate.connection.url”> jdbc:mysql:///hibernate</property>
<property name=“hibernate.connection.username”>root</property>
<property name=“hibernate.connection.password”>123</property>
<!–第二部分:hibernate部分 -->
<!-- 是否自动生成表:
update:无表创建表,有表修改表
–>
<property name=“hibernate.hbm2ddl.auto”>update</property>
<!-- 是否打印sql -->
<property name=“hibernate.show_sql”>true</property>
<!-- 设置是否格式化–>
<property name=“hibernate.format_sql”>true</property>
<!–第三部分:实体类映射文件部分 -->
<mapping resource=“com/zhiyou100/javabean/User.hbm.xml”/>
</session-factory>
</hibernate-configuration>

在这里插入图片描述

2.5、测试

在这里插入图片描述 注:在创建工厂的时候就会去创建数据库,这里是非常消耗资源的,我们可以把创建工厂的过程封装起来,只运行一次。最后我们需要使用的是session对象,并且封装之后方法要返回一个session对象提供给我们使用

package com.zhiyou100.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.zhiyou100.javabean.User;

//注意:使用单元测试时,类名不要写成test
public class HibernateTest {
private static SessionFactory sessionFactory;
private Session session;

//创建sessionFactory
static{
	//读取文件并且创建SessionFactory对象
	sessionFactory=new Configuration().configure().buildSessionFactory();
}
//创建方法获取session对象
//@Before注解下的方法会在Test下的方法执行前执行
@Before
public void getSession(){
	System.out.println("before++++++++++++");
	session= sessionFactory.openSession();
}
//关闭资源session
//在test执行之后执行
@After
public void closeSession(){
	System.out.println("after--------------");
	//判断session是否为null
	if (session!=null) {
		//关闭session
		session.close();
	}		
}


//添加用户
@Test
public void addUser(){
	// 1创建configuration对象
	Configuration configuration = new Configuration();
	//读取配置文件,如果我们将配置文件写在src下并且名字是hibernate.cfg.xml,可以直接读取到
	configuration.configure();
	// 2创建Sessionfactory对象
	SessionFactory sessionFactory = configuration.buildSessionFactory();
	// 3通过SessionFactory创建Session对象
	Session session = sessionFactory.openSession();
	// 4开启事务
	Transaction transaction = session.beginTransaction();
	// 5添加用户  
	// 注:Hibernate不用写sql,操作的都是对象
	User user = new User();	
	//设置名字
	user.setU_name("小丽add");
	//设置密码
	user.setU_pass("12345612");
	//添加
	session.save(user);
	//提交事务
	transaction.commit();
	//关闭资源
	session.close();
	sessionFactory.close();	
}


//查询一个用户
@Test
public void queryUser(){
	//查询id=1的用户
	User user=session.get(User.class,1);
	//输出
	System.out.println(user);
}

//修改
//1)先查询    2)后修改
@Test
public void updateUser(){
	//开启事务
	Transaction transaction = session.beginTransaction();
	//查询
	User user = session.get(User.class, 7);
	//修改
	user.setU_pass("111111234");
	session.update(user);
	session.clear();
	//提交事务
	transaction.commit();		
}

//删除
@Test
public void deleteUser(){
	//开启事务
	Transaction transaction = session.beginTransaction();
	//查询
	User user = session.get(User.class, 7);
	//删除
	session.delete(user);	
	//提交事务
	transaction.commit();
}

}

三、CRUD

CRUD:创建、读(查询)、修改、删除

private static SessionFactory sessionFactory;
	private Session session;
//创建sessionFactory
static{
	//读取文件并且创建SessionFactory对象
	sessionFactory=new Configuration().configure().buildSessionFactory();
}
//创建方法获取session对象
//@Before注解下的方法会在Test下的方法执行前执行
@Before
public void getSession(){
	System.out.println("before++++++++++++");
	session= sessionFactory.openSession();
}
//关闭资源session
//在test执行之后执行
@After
public void closeSession(){
	System.out.println("after--------------");
	//判断session是否为null
	if (session!=null) {
		//关闭session
		session.close();
	}		
}

在这里插入图片描述

3.1、添加

参考上边案例使用session.save(Object);

3.2、查询

//查询一个用户
	@Test
	public void queryUser(){
		//查询id=1的用户
		User user=session.get(User.class,1);
		//输出
		System.out.println(user);
	}

在这里插入图片描述

3.3、修改

//修改
	//1)先查询    2)后修改
	@Test
	public void updateUser(){
		//开启事务
		Transaction transaction = session.beginTransaction();
		//查询
		User user = session.get(User.class, 7);
		//修改
		user.setU_pass("111111");
		session.update(user);
		session.clear();
		//提交事务
		transaction.commit();		
	}

在这里插入图片描述

3.4、删除


	//删除
	@Test
	public void deleteUser(){
		//开启事务
		Transaction transaction = session.beginTransaction();
		//查询
		User user = session.get(User.class, 8);
		//删除
		session.delete(user);	
		//提交事务
		transaction.commit();
	}

在这里插入图片描述

四、单元测试

使用到的注解:@Test @Before @After
在这里插入图片描述

3.5、总结

添加:save
修改:update
查询:get
删除:delete

五、xml文件没有提示的解决方法

引入dtd文件即可
:写xml文件时使用快捷键自动生成,千万不要手写,容易出错
过程:
1)复制约束网址,只粘贴内容不要粘贴引号
在这里插入图片描述
2)选择图下内容
在这里插入图片描述在这里插入图片描述

六、Hibernate对象的状态

Hibernate都是操作对象,间接的操作数据库。 其中对象有三种状态
session查询出来的对象其实有一个缓存, 就是缓存在session中注

6.1、持久态

特点:保存在数据库中,并且存在了session缓存中
在这里插入图片描述

6.2 瞬/临时态

特点:刚new出来的,还没有存到数据库中
在这里插入图片描述

6.3、脱管态/游离态

特点:不能直接获取,存在于数据库中但是不在session缓存中。
比如:clear之后就是游离态的
在这里插入图片描述

6.4、saveOrUpdate方法

*注:*在创建工厂的时候就会去创建数据库中的表,这里是非常消耗资源的。 所以我们可以把创建工厂的过程封装起来,只运行一次。最后我们需要使用的是session对象,并且封装之后方法要返回一个session对象提供给我们使用。
(因为创建表是在创建sessionFactory的时候创建的,每创建一次表就会创建一次sessionFactory对象,所以可以把它定义为一个静态代码块)

package com.zhiyou100.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.zhiyou100.javabean.User;
public class SaveOrUpdateTest {

private  static SessionFactory sessionFactory;
private Session session;

//创建sessionFactory
static{
	//读取文件并且创建sessionFactory对象
	sessionFactory=new Configuration().configure().buildSessionFactory();
}	
//创建方法获取session对象
//@Before注解下的方法:在单元测试Test下的方法执行前执行
@Before
public void getSession(){
	System.out.println("++++++++++++++++");
		session=sessionFactory.openSession();
}
//关闭资源
//@After注解下的方法:在单元测试Test方法执行之后执行
@After
public void closeSession(){
	System.out.println("-------------");
	if (session!=null) {
		session.close();	
	}		
}

//持久态对象
@Test
public void chijiu(){
	//开启事务
	Transaction transaction = session.beginTransaction();
	//获取对象
	User user = session.get(User.class, 5);
	user.setU_name("小气鬼");	
	session.saveOrUpdate(user);
	session.clear();//清空session缓存
	//提交事务
	transaction.commit();
}

//瞬/临时态对象
@Test
public void shunshi(){
	//开启事务
	Transaction transaction = session.beginTransaction();
	//获取对象
	User user = new User();
	//user.setU_id(12);
	user.setU_name("包子");
	user.setU_pass("000000");
	session.saveOrUpdate(user);
	//提交事务
	transaction.commit();

}

//脱管态/游离态对象
@Test
public void youli (){
	//开启事务
	Transaction transaction = session.beginTransaction();
	//获取对象
	User user = new User();
	//user.setU_id(15);  数据库中不存在这个Id,会报错
	user.setU_id(10);	
	user.setU_name("panda");
	user.setU_pass("123123");
	//调用方法
	session.saveOrUpdate(user);
	//提交事务
	transaction.commit();
}

}

在这里插入图片描述

6.4.1、持久态

做的是修改操作。 如果使用clear方法,会从持久态对象转换成托管态对象
在这里插入图片描述

6.4.2、瞬/临时态

id不存在
做的是添加操作。 从瞬时态转换为持久态
在这里插入图片描述

6.4.3、托管/游离态

1)该id不存在, 会 报错
在这里插入图片描述2)该id存在
saveOrUpdate方法做的是修改操作。
3)save方法
保存,但是主键还是按照数据库自动递增,会从托管态变成持久态。
在这里插入图片描述
Hibernate对象状态之间的转换关系图:
在这里插入图片描述

七、HQL

HQL(Hibernate Query Language)就是Hibernate框架的查询语言,SQL操作的是表,HQL操作的是对象

package com.zhiyou100.test;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.zhiyou100.javabean.User;

public class HQLTest {
private static SessionFactory sessionFactory;
private Session session;

static{
	sessionFactory=new Configuration().configure().buildSessionFactory();
}
@Before
public void getSession(){
	System.out.println("++++++++++++++");
	session=sessionFactory.openSession();
}
@After
public void closeSession(){
	System.out.println("-------------");
	if (session!=null) {
		session.close();
	}
}

//查询所有
@Test
public void query1(){
	String hql="FROM User";
	//查询
	Query query = session.createQuery(hql);
	//获取数据
	List&lt;User&gt; list = query.list();
	//打印
	for (User user : list) {
		System.out.println(user);
	}
	
}

//条件查询
@Test
public void query2(){
	String hql="FROM User WHERE u_name=? AND u_pass=?";
	//查询
	Query query = session.createQuery(hql);
	//替换占位符(从0开始) 
	query.setParameter(0, "小花");
	query.setParameter(1, "123456");
	//获取数据
	List&lt;User&gt; list = query.list();
	//打印
	for (User user : list) {
		System.out.println(user);
	}
	
}

//模糊查询
@Test
public void query3(){
	String hql="FROM User WHERE u_name LIKE ?";
	//查询
	Query query = session.createQuery(hql);
	//给占位符赋值
	query.setParameter(0, "%小%");
	//获取数据
	List&lt;User&gt; list = query.list();
	//打印结果
	for (User user : list) {
		System.out.println(user);
	}
}

//排序查询
@Test
public void query4(){
	//降序排序
	String hql="FROM User ORDER BY u_id desc";  
	//asc 升序排序  desc:降序
	Query query = session.createQuery(hql);
	//获取数据
	List&lt;User&gt; list = query.list();
	//打印
	for (User user : list) {
		System.out.println(user);
	}
	
}
//分页排序
@Test
public void query5(){
	String hql="FROM User";
	//查询
	Query query = session.createQuery(hql);
	//设置起始位置(从0开始的)
	query.setFirstResult(0);		
	//设置每页数据量
	query.setMaxResults(4);
	//获取数据
	List&lt;User&gt; list = query.list();
	//打印结果:
	for (User user : list) {
		System.out.println(user);
	}
}

//投影查询:只查询部分字段
@Test
public void query6(){
	//注:实体类中必须有对应的构造方法
	String hql="SELECT new User(u_name,u_pass) FROM User";
	Query query = session.createQuery(hql);
	List&lt;User&gt; list = query.list();
	for (User user : list) {
		System.out.println(user);
	}
}

//自定义sql语句
@Test
public void query(){
	//定义sql语句
	String sql="select * from tb_user";  //查询的是数据库中的表
	//使用方法查询
	SQLQuery sqlQuery = session.createSQLQuery(sql);
	sqlQuery.addEntity(User.class);
	//转换成集合
	List&lt;User&gt; list = sqlQuery.list();
	//打印
	for (User user : list) {
		System.out.println(user);
	}	
	
}

}

在这里插入图片描述

7.1、查询所有

//查询所有
	@Test
	public void query1(){
		String hql="FROM User";
		//查询
		Query query = session.createQuery(hql);
		//获取数据
		List<User> list = query.list();
		//打印
		for (User user : list) {
			System.out.println(user);
		}
}

在这里插入图片描述

7.2、条件查询

//条件查询
	@Test
	public void query2(){
		String hql="FROM User WHERE u_name=? AND u_pass=?";
		//查询
		Query query = session.createQuery(hql);
		//替换占位符(从0开始) 
		query.setParameter(0, "小花");
		query.setParameter(1, "123456");
		//获取数据
		List<User> list = query.list();
		//打印
		for (User user : list) {
			System.out.println(user);
		}
}

在这里插入图片描述

7.3、模糊查询

//模糊查询
	@Test
	public void query3(){
		String hql="FROM User WHERE u_name LIKE ?";
		//查询
		Query query = session.createQuery(hql);
		//给占位符赋值
		query.setParameter(0, "%小%");
		//获取数据
		List<User> list = query.list();
		//打印结果
		for (User user : list) {
			System.out.println(user);
		}
	}

在这里插入图片描述

7.4、降序排序

//排序查询
	@Test
	public void query4(){
		//降序排序
		String hql="FROM User ORDER BY u_id desc";  
		//asc 升序排序  desc:降序
		Query query = session.createQuery(hql);
		//获取数据
		List<User> list = query.list();
		//打印
		for (User user : list) {
			System.out.println(user);
		}
}

在这里插入图片描述

7.5、分页查询

//分页排序
	@Test
	public void query5(){
		String hql="FROM User";
		//查询
		Query query = session.createQuery(hql);
		//设置起始位置(从0开始的)
		query.setFirstResult(0);		
		//设置每页数据量
		query.setMaxResults(4);
		//获取数据
		List<User> list = query.list();
		//打印结果:
		for (User user : list) {
			System.out.println(user);
		}
	}

在这里插入图片描述

7.6、投影查询

投影查询:只查询部分字段
注:实体类中必须有对应的构造方法

//投影查询:只查询部分字段
	@Test
	public void query6(){
		//注:实体类中必须有对应的构造方法
		String hql="SELECT new User(u_name,u_pass) FROM User";
		Query query = session.createQuery(hql);
		List<User> list = query.list();
		for (User user : list) {
			System.out.println(user);
		}
	}

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

八、SQL

Hibernate中也可以写sql语句,但是非常滴麻烦
我们使用createSQLQuery方法实现

//自定义sql语句
	@Test
	public void query(){
		//定义sql语句
		String sql="select * from tb_user";  //查询的是数据库中的表
		//使用方法查询
		SQLQuery sqlQuery = session.createSQLQuery(sql);
		sqlQuery.addEntity(User.class);
		//转换成集合
		List<User> list = sqlQuery.list();
		//打印
		for (User user : list) {
			System.out.println(user);
		}

在这里插入图片描述

九、学习中出现的问题

单元测试:
1)方法不能有返回值,不能有参数,不能被static修饰,不能使用private修饰
2)在类中运行方法,右击直接运行会运行所有的Test方法。 所以点击单个的方法名运行单个方法即可
注意:单词别写错
空指针(看一下是否创建了session对象)
乱码:创建数据库时选择UTF8,以免出现乱码现象
查看当前文件的编码格式:Alter+回车
在这里插入图片描述

十、学习要求

10.1、整理一个自己的学习笔记
10.2、Hibernate基础知识,配置和HQL语句熟练掌握
10.3、Hibernate一对多,多对多配置了解

        </div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
            </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值