一、Hibernate五大接口
1.Configuration接口
用于加载主配置文件(hibernate.cfg.xml)信息,负责管理Hibernate的配置信息。
2.SessionFactory接口
用于创建session对象的工厂。
3.Session接口
用于执行增删改查基本操作。
4.Transaction接口
用于事务控制(默认false不自动提交事务)
5.Query和Criteria接口
用于执行各种复杂查询可以使用HQL或者SQL
二、Hibernate运行原理
1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的读取并解析映射信息
3.通过config.buildSessionFactory();//创建SessionFactory
4.sessionFactory.openSession();//打开Sesssion
5.session.beginTransaction();//创建事务Transation
6.使用session调用增删改查方法操作数据库。
7.通过Transation.commit();提交事务。
8.使用session.close();关闭session使session进入游离状态。
三、session常用方法
1:save()
@Test
public void testsave() {
//加载主配置文件
Configuration configure = new Configuration().configure();
//获取session
SessionFactory sessionFactory = configure.buildSessionFactory();
//获取session会话(提供操作数据库的方法)
Session session = sessionFactory.openSession();
//开启事务
Transaction tran = session.beginTransaction();
User user = new User(5,"张胜男","123",600);
//save()添加返回主键值
Serializable save = session.save(user);
//提交事务
tran.commit();
System.out.println(save);
session.close();
}
2:update()
@Test
public void TestUpdate() {
Session session = HibernateUtil.getSession();//封装一个工具类获取session
Transaction tran = session.beginTransaction();
User user = (User)session.get(User.class, 6);//先用查询获取到指定内容在转换成对象
user.setUsername("张胜女");//使用实体类的set方法修改
session.update(user);
tran.commit();
session.close();
}
3:createQuery()
public class QueryTest {
@Test//如果需要 select * 查询所有字段值,在Hql中可以省略select
public void TestCreateQuery() {
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test//若只查询实体中某几个字段返回结果的类型是泛型为数组的集合
public void TestCreateQuery2() {
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
//查询指定字段通过构造查询,
Query query = session.createQuery("select username,password from User");
//返回对象集合
List<Object[]> list = query.list();
//遍历对象
for (Object[] objects : list) {
//遍历对象中的每个属性
for (Object object : objects) {
System.out.println(object);
}
}
session.close();
}
@Test//条件查询
public void TestCreateQuery3() {
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
/**
* 参数设值方式有两种
* 1.问号设值
* Query query = session.createQuery("from User where username=?");
* 第一个参数代表第一个?, 第二个参数代表给?设值的值
* query.setString(0, "张胜女");
*
* 2.变量设值
* Query query = session.createQuery("from User where username=:name");
* query.setString("name", "张胜女");
*
* */
Query query = session.createQuery("from User where username=:name");
query.setString("name", "csxg");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test//根据用户名进行模糊查询
public void TestCreateQuery4() {
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User where username like ?");
query.setString(0, "%c%");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test//分页查询
public void Testpage() {
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User");
query.setFirstResult(0);//从第几条数据开始,等同于开始小标索引
query.setMaxResults(2);//抓取几条数据,等每一页显示几条数据
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test//查询返回单个对象
public void TestUniqueResult() {
Session session = HibernateUtil.getSession();
//Query query = session.createQuery("select count(*) from User");
//Query query = session.createQuery("select avg(age) from User");
//Query query = session.createQuery("select max(age) from User");
//Query query = session.createQuery("select min(age) from User");
Query query = session.createQuery("select sum(age) from User");
//返回单个数据
Object object = query.uniqueResult();
System.out.println(object);
}
@Test//区间查询
public void TestBetweenAnd() {
Session session = HibernateUtil.getSession();
//Query query = session.createQuery("from User where age >= ? and age <= ?");
Query query = session.createQuery("from User where age between ? and ?");
query.setInteger(0, 50);
query.setInteger(1, 90);
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test
public void TestGroupBy() {
Session session = HibernateUtil.getSession();
Query query = session.createQuery("from User group by age");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
}
@Test//测试构造查询
public void TestQuery() {
Session session = HibernateUtil.getSession();
Query query = session.createQuery("select new User(username,password) from User");
List<User> list = query.list();//直接返回泛型为User的list集合.
for (User user : list) {
System.out.println(user);
}
session.close();
}
@Test//批删
public void TestExecuteUpdate() {
Session session = HibernateUtil.getSession();
Transaction tran = session.beginTransaction();
Query query = session.createQuery("delete from User where id in(7,8)");
int executeUpdate = query.executeUpdate();
System.out.println(executeUpdate);
tran.commit();
session.close();
}
@Test
public void TestCreateQueryItrate() {
Session session = HibernateUtil.getSession();
Query query = session.createQuery("select u from User u");
// List<User> list = query.list();
// for (User user : list) {
// System.out.println(user);
// }
/**
* list 和 iterate 区别
* 1.list 是一次性把索引数据从数据库中查询出来
* 2.iterate 是先从数据库中查询所有id。如果缓存包含全部数据,无需查询数据库,
* 如果缓存不包含任何数据,需要根据id依次查询。
*
* 总结:大多数情况时有list查询,当对象包含大量属性或者要加载的大部分数据已经在缓存中可以使用iterate
*
* */
Iterator<User> iterator = query.iterate();
while(iterator.hasNext()) {
User user = iterator.next();
System.out.println(user);
}
session.close();
}
}
4:delete()删除
@Test//测试删除
public void TestDelete() {
Session session = HibernateUtil.getSession();
//开启事务
Transaction tran = session.beginTransaction();
User user = new User();//先创建一个对象
user.setUid(1);//设置对象id为1
session.delete(user);//删除时找到id为1的数据进行删除
tran.commit();
session.close();
}
5:load()查询
@Test
public void TestLoad() {//load 延迟加载,当访问实体对象时才会发送sql并
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tran = session.beginTransaction();
User user = (User)session.load(User.class, 6);
System.out.println(user);
tran.commit();
session.close();
}
6:saveOrUpdate();保存或修改
@Test
public void TestSaveOrUpdate() {//如果对象中有id数据值做修改,没有id值做添加
Session session = HibernateUtil.getSession();
Transaction tran = session.beginTransaction();
//User user = new User(null,"cstj","1234",55);测试修改
User user = new User(7,"csxg","1234",88);//测试添加
session.saveOrUpdate(user);
tran.commit();
session.close();
}
7:list();查询
public class Test {
public void list() {
Configuration configure = new Configuration().configure();
SessionFactory sessionFactory = configure.buildSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
session.close();
}
四、Hiernate HQL语法
HQL查询语句和SQL语句结构一样,不同点如下:
-HQL是面向对象的查询,SQL是面向结构的查询。
-HQL使用实体类中的类名和属性名,代替了原有的表名和列名。
-在HQL中类型名和属性名大小写敏感。
-在HQL中如果需要查询查询所有字段select * 可以省略直接写(from 类名)
-在HQL中如果需要使用join…on连接,不支持on字句,使用where条件。
-若只查询实体类中的某几个字段,返回结果为泛型数组的集合。
五、数据表创建
(1)自动创建数据表
参照hibernate.properties.txt进行配置
#ddl数据定义语言
#hibernate.hbm2ddl.auto create-drop
#hibernate.hbm2ddl.auto create
#自动创建并更新表(有表,更新)
#hibernate.hbm2ddl.auto update
#hibernate.hbm2ddl.auto validate
-------hibernate.cfg.xml--------
<!-- 自动生成表 -->
<!-- update如果不存在自动创建,存在不创建 -->
<property name="hibernate.hbm2ddl.auto">update</property>
(2)创建方式
加载映射
-----hibernate.cfg.xml-----------
<!--指定具体的映射文件-->
<mapping resource="com/tlxy/entity/type.hbm.xml"/>
------type.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>
<class name="com.tlxy.entity.type" table="g_type">
<id name="tid" column="tid">
<generator class="native"></generator>
</id>
<property name="tname" column="tname" length="32"></property>
</class>
</hibernate-mapping>
注解映射
<!-- 扫描指定的实体类-->
-------hibernate.cfg.xml--------
<mapping class="com.tlxy.entity.type"/>
package com.tlxy.entity;
@Entity
@Table(name="g_type")
public class type {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer tid;
private String tname;
@OneToMany
@JoinColumn(name="tid")
@Fetch(FetchMode.JOIN)
private Set<goods> goodSet;
//------生成对应get、set、有参、无参、tostring()方法
}
(3)关联映射
多对一
加载方式
<!-- 多对一映射
fetch = "join"默认值是select:在多对一将原本需要两条sql语句left outer join方式
用一条sql语句连接解决。
并且原本的懒加载也不在懒了
cascade:级联操作关联表
save-update:修改和添加级联操作关联表
all:增删改查都级联操作关联表
none:都不级联操作关联表
delete:删除时级联操作关联表
name为表自身的外键 column为关联表的主键
-->
<many-to-one name="dept" column="deptno" fetch="join"></many-to-one>
注解方式
@ManyToOne
@JoinColumn(name="deptno")
@Fetch(FetchMode.JOIN)
private Dept dept;//与dept表的主键关联
一对多
加载方式
<!-- 一对多 -->
<set name="goodSet">
<key column="tid"></key>
<one-to-many class="com.tlxy.entity.goods"/>
</set>
注解方式
@OneToMany
@JoinColumn(name="tid")
@Fetch(FetchMode.JOIN)
private Set<goods> goodSet;
多对多
注解方式(要通过一个中间表来关联两个实体)描述多对多关系的数据表关系 name指定中间表名称 joinColumns定义中间表与 student表的外键关系
inverseJoinColumns定义中间表与另一端(Course)的外键关系。
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer cid;
private String cname;
//joinColumns为与连接表连接的一段 inverJoibColumns为连接表的另一段
@ManyToMany
@JoinTable(name = "cou_stu",joinColumns = @JoinColumn(name="cid"),
inverseJoinColumns = @JoinColumn(name="sid"))
private Set<Student> stuSet;
//生成实体对应方法
}
@Entity
@Table(name="student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer sid;
private String sname;
//student是多对多的一段
@ManyToMany
@JoinTable(name = "cou_stu",joinColumns = @JoinColumn(name="sid"),
inverseJoinColumns = @JoinColumn(name="cid"))
private Set<Course> cpuSet;
六、使用Creteria原生SQL
1、获取session,使用session.createSQLQuery(“SQL语句”)就可以使用SQL语句操作数据库。
package com.tl.test;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.tl.entity.Student;
import com.tlxy.utils.HibernateUtil;
//使用hibernate原生sql操作
public class SQLTest {
@Test
public void testQuery() {
Session session = HibernateUtil.getSession();
List<Student> list = session.createSQLQuery("select * from student").addEntity(Student.class).list();
System.out.println(list);
session.close();
}
@Test//使用sql语句删除
public void testDelete() {
Session session = HibernateUtil.getSession();
Transaction tran = session.beginTransaction();
Query query = session.createSQLQuery("delete from student where sid=?").setInteger(0, 1);
//执行增删改
int num = query.executeUpdate();
System.out.println(num);
tran.commit();
session.close();
}
@Test//测试添加
public void testSave() {
Session session = HibernateUtil.getSession();
Transaction tran = session.beginTransaction();
Query query = session.createSQLQuery("insert into student (sid,sname) values (?,?)").setParameter(0, 1).setParameter(1, "xxxxx");
query.executeUpdate();
tran.commit();
session.close();
}
@Test//测试修改
public void testUpdate() {
Session session = HibernateUtil.getSession();
Transaction tran = session.beginTransaction();
Query query = session.createSQLQuery("update student set sname=? where sid=?");
query.setParameter(0, "???");
query.setParameter(1, 1);
query.executeUpdate();
tran.commit();
session.close();
}
}
2、使用session.createCreteria(“实体类.class”)操作数据库,使用.add()方法追加条件。
Critera常用方法
Restrictions.eq()等于
Restrictions.not()不等于
Restrictions.gt()大于
Restrictions.ge()大于等于
Restrictions.lt()小于
Restrictions.le()小于等于
Restrictions.isnull()等于空
Restrictions.isNotNull()非空
Restrictions.ilike()模糊
Restrictions.or()并且
Restrictions.and()或
Restrictions.in()等于列表中某一个值
Restrictions.between()区间
package com.tl.test;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import com.tl.entity.Student;
import com.tlxy.utils.HibernateUtil;
public class CriteriaTest {
@Test//查询所有 通过list()返回集合
public void testList() {
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Student.class);
List<Student> list = criteria.list();
// for (Student student : list) {
// System.out.println(student);
// }
System.out.println(list);
session.close();
}
@Test
public void testOr() {
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Student.class);
//查询id为一或二的学生,追加条件
criteria.add(Restrictions.or(Restrictions.eq("sid", 2), Restrictions.eq("sid", 6)));//eq等于
List<Student> list =criteria.list();
System.out.println(list);
session.close();
}
@Test//多条件查询
public void testList2() {
Session session = HibernateUtil.getSession();
Criteria cirteria = session.createCriteria(Student.class);
//查询id大于3的学生
cirteria.add(Restrictions.gt("sid", 3));//gt大于
//名字为小明
cirteria.add(Restrictions.like("sname", "%伟%"));
List<Student> list = cirteria.list();
System.out.println(list);
session.close();
}
@Test//排序
public void testOrder() {
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.addOrder(Order.desc("sid"));//降序
List<Student> list = criteria.list();
System.out.println(list);
session.close();
}
}