Hibernate是使用在三层架构中的dao层的一个框架,与JDBC和myBatis是类似的技术,它也是基于ORM(对象关系映射:数据表中的字段和实体类中的属性一一对应)设计的,其实就是对JDBC的封装,封装之后的东西使用起来更加方便快捷。
Hibernate是一个全自动的ORM框架,而myBatis是一个半自动的ORM框架,全自动代表数据表,SQL语句会自动生成,弊端在于不够灵活,效率低,而mybatis可以字节写sql语句非常灵活。国内更加青睐于myBatis。半自动表示,数据查出来之后可以自动封装到JavaBean(实体类/pojo/entity)中。
JavaBean:类中的属性全部私有,必须有一个无参的构造方法,必须有get和set方法
我们需要通过反射调用无参构造创建对象并且调用set方法给对象赋值,完成数据的自动注入。
注:建议写在实体类包下,名字为实体类名.hbm.xml
约束到资料中的dtd文件中找
要求:创建在src下,名字是hibernate.cfg.xml
com.mysql.jdbc.Driver
jdbc:mysql:///hibernate
root
123
update
true
true
注:在创建工厂的时候就会去创建数据库,这里是非常消耗资源的,我们可以把创建工厂的过程封装起来,只运行一次。最后我们需要使用的是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:创建、读(查询)、修改、删除
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();
}
}
参考上边案例使用session.save(Object);
//查询一个用户
@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("111111");
session.update(user);
session.clear();
//提交事务
transaction.commit();
}
//删除
@Test
public void deleteUser(){
//开启事务
Transaction transaction = session.beginTransaction();
//查询
User user = session.get(User.class, 8);
//删除
session.delete(user);
//提交事务
transaction.commit();
}
添加:save
修改:update
查询:get
删除:delete
引入dtd文件即可
注:写xml文件时使用快捷键自动生成,千万不要手写,容易出错
过程:
1)复制约束网址,只粘贴内容不要粘贴引号
2)选择图下内容
Hibernate都是操作对象,间接的操作数据库。 其中对象有三种状态
注:session查询出来的对象其实有一个缓存, 就是缓存在session中
特点:不能直接获取,存在于数据库中但是不在session缓存中。
比如:clear之后就是游离态的
*注:*在创建工厂的时候就会去创建数据库中的表,这里是非常消耗资源的。 所以我们可以把创建工厂的过程封装起来,只运行一次。最后我们需要使用的是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();
}
}
做的是修改操作。 如果使用clear方法,会从持久态对象转换成托管态对象
1)该id不存在, 会 报错
2)该id存在
saveOrUpdate方法做的是修改操作。
3)save方法
保存,但是主键还是按照数据库自动递增,会从托管态变成持久态。
Hibernate对象状态之间的转换关系图:
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 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 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 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 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 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 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 list = sqlQuery.list();
//打印
for (User user : list) {
System.out.println(user);
}
}
}
//查询所有
@Test
public void query1(){
String hql="FROM User";
//查询
Query query = session.createQuery(hql);
//获取数据
List 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 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 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 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 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 list = query.list();
for (User user : list) {
System.out.println(user);
}
}
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 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一对多,多对多配置了解