hibernate创建的 java 工程,需要的 jar包:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_demoproperty>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">rootproperty>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
<mapping resource="com/inke/domain/Customer.hbm.xml"/>
session-factory>
hibernate-configuration>
public class Customer {
/*
* CREATE TABLE `cst_customer` (
`cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` VARCHAR(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` VARCHAR(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` VARCHAR(32) DEFAULT NULL COMMENT '客户级别',
`cust_linkman` VARCHAR(64) DEFAULT NULL COMMENT '联系人',
`cust_phone` VARCHAR(64) DEFAULT NULL COMMENT '固定电话',
`cust_mobile` VARCHAR(16) DEFAULT NULL COMMENT '移动电话',
PRIMARY KEY (`cust_id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
*/
private Long cust_id;
private String cust_name;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_linkman;
private String cust_phone;
private String cust_mobile;
set/get ...
@Override
public String toString() {
return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + "]";
}
}
<hibernate-mapping package="com.inke.domain" >
<class name="com.inke.domain.Customer" table="cst_customer" >
<id name="cust_id" >
<generator class="native">generator>
id>
<property name="cust_name" column="cust_name" >
property>
<property name="cust_source" column="cust_source" >property>
<property name="cust_industry" column="cust_industry" >property>
<property name="cust_level" column="cust_level" >property>
<property name="cust_linkman" column="cust_linkman" >property>
<property name="cust_phone" column="cust_phone" >property>
<property name="cust_mobile" column="cust_mobile" >property>
class>
hibernate-mapping>
public class Test1 {
private static SessionFactory sessionFactory;
@Test
public void test1() {
Configuration configuration = new Configuration();
configuration.configure();
sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_name("百度");
session.save(customer);
transaction.commit();
sessionFactory.close();
}
}
// Configuration功能: 配置加载类.用于加载主配置,orm元数据加载
public class Demo {
@Test
public void fun1(){
//1 创建,调用空参构造
Configuration conf = new Configuration();
//2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件
conf.configure();
//3 读取指定orm元数据(扩展),如果主配置中已经引入映射配置.不需要手动加载
//conf.addResource(resourceName);
//conf.addClass(persistentClass);
//4 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
}
}
// SessionFactory功能: 用于创建操作数据库核心对象session对象的工厂.
// 简单说功能就一个---创建session对象
//注意:1.sessionfactory 负责保存和使用所有配置信息.消耗内存资源非常大.
// 2.sessionFactory属于线程安全的对象设计.
//结论: 保证在web项目中,只创建一个sessionFactory.
public class Demo2 {
@Test
public void fun1(){
//1 创建,调用空参构造
Configuration conf = new Configuration();
//2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件
conf.configure();
//3 读取指定orm元数据(扩展),如果主配置中已经引入映射配置.不需要手动加载
//conf.addResource(resourceName);
//conf.addClass(persistentClass);
//4 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//--------------------------------------------------
//5 获得session
//打开一个新的session对象
sf.openSession();
//获得一个与线程绑定的session对象(明天讲解)
sf.getCurrentSession();
}
}
//session对象功能: 表达hibernate框架与数据库之间的连接(会话).
//session类似于JDBC年代的connection对象. 还可以完成对数据库中数据的增删改查操作.
//session是hibernate操作数据库的核心对象
public class Demo3 {
@Test
//事务操作
public void fun1(){
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//3 获得session
Session session = sf.openSession();
//4 session获得操作事务的Transaction对象
//获得操作事务的tx对象
//Transaction tx = session.getTransaction();
//开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();
//----------------------------------------------
//----------------------------------------------
tx2.commit();//提交事务
tx2.rollback();//回滚事务
session.close();//释放资源
sf.close();//释放资源
}
@Test
//session的新增
public void fun2(){
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//3 获得session
Session session = sf.openSession();
//4 session获得操作事务的Transaction对象
//获得操作事务的tx对象
//Transaction tx = session.getTransaction();
//开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();
//----------------------------------------------
Customer c = new Customer();
c.setCust_name("谷歌");
session.save(c);
//----------------------------------------------
tx2.commit();//提交事务
session.close();//释放资源
sf.close();//释放资源
}
@Test
//session的查询
//查询id为1的customer对象
public void fun3(){
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//3 获得session
Session session = sf.openSession();
//4 session获得操作事务的Transaction对象
//获得操作事务的tx对象
//Transaction tx = session.getTransaction();
//开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();
//----------------------------------------------
Customer customer = session.get(Customer.class, 1l);
System.out.println(customer);
//----------------------------------------------
tx2.commit();//提交事务
session.close();//释放资源
sf.close();//释放资源
}
@Test
//session的修改
//修改id为1的customer对象的name属性为脸书
public void fun4(){
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//3 获得session
Session session = sf.openSession();
//4 session获得操作事务的Transaction对象
//获得操作事务的tx对象
//Transaction tx = session.getTransaction();
//开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();
//----------------------------------------------
//1 获得要修改的对象
Customer c = session.get(Customer.class, 1l);
//2 修改
c.setCust_name("脸书");
//3 执行update
session.update(c);
//----------------------------------------------
tx2.commit();//提交事务
session.close();//释放资源
sf.close();//释放资源
}
@Test
//session的删除
//删除id为1的customer对象
public void fun5(){
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//3 获得session
Session session = sf.openSession();
//4 session获得操作事务的Transaction对象
//获得操作事务的tx对象
Transaction tx = session.getTransaction();
tx.begin();
//开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();
//----------------------------------------------
//1 获得要修改的对象
Customer c = session.get(Customer.class, 1l);
//2 调用delete删除对象
session.delete(c);
//----------------------------------------------
tx2.commit();//提交事务
session.close();//释放资源
sf.close();//释放资源
}
}
表的业务列中,有某业务列符合,必须有,并且不重复的特征时,该列可以作为主键使用,例如身份证号,但是不推荐.
表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键,例如:id,uuid等,推荐。
identity : 主键自增.由数据库来维护主键值.录入时不需要指定主键.
hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用.
native**(推荐)**:hilo+sequence+identity 自动三选一策略.
<hibernate-mapping package="cn.itheima.domain" >
<class name="Customer" table="cst_customer" >
<id name="cust_id" >
<generator class="native">generator>
id>
<property name="cust_name" column="cust_name" >property>
<property name="cust_source" column="cust_source" >property>
<property name="cust_industry" column="cust_industry" >property>
<property name="cust_level" column="cust_level" >property>
<property name="cust_linkman" column="cust_linkman" >property>
<property name="cust_phone" column="cust_phone" >property>
<property name="cust_mobile" column="cust_mobile" >property>
class>
hibernate-mapping>
//测试对象的三种状态
public class Demo {
@Test
//查看三种状态
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
Customer c = new Customer(); // 没有id, 没有与session关联 => 瞬时状态
c.setCust_name("联想"); // 瞬时状态
session.save(c); // 持久化状态, 有id,有关联
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//三种状态特点
//save方法: 其实不能理解成保存.理解成将瞬时状态转换成持久状态的方法
//主键自增 : 执行save方法时,为了将对象转换为持久化状态.必须生成id值.所以需要执行insert语句生成.
//increment: 执行save方法,为了生成id.会执行查询id最大值的sql语句.
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
Customer c = new Customer(); // 没有id, 没有与session关联 => 瞬时状态
c.setCust_name("联想"); // 瞬时状态
session.save(c); // 持久化状态, 有id,有关联
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//三种状态特点
// 持久化状态特点: 持久化状态对象的任何变化都会自动同步到数据库中.
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
Customer c = session.get(Customer.class, 1l);//持久化状态对象
c.setCust_name("微软公司");
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
}
缓存:提高效率.hibernate中的一级缓存也是为了提高操作数据库的效率.
提高效率手段1:提高查询效率
提高效率手段2:减少不必要的修改语句发送
a 原子性(像物理原子一样,最小而不可分隔,全成功或全失败)
c 一致性(例如,转账 相加总量不变)
i 隔离性(隔离级别)
d 持久性(数据写到硬盘等持久化的物质上)
1.脏读(查询正在操作还没有提交的数据)
2.不可重复度(两次查询数据不一致,中间可能别人操作了数据)
3.幻|虚读(删除记录的同时,别人又插入记录了,产生幻觉了)
(表示上面的并发问题代表的1,2,3)
读未提交- 123
读已提交 - 23
可重复读(mysql默认级别)-3
串行化 - 没有问题,效率太低,不考虑。
hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_32property>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">1234property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
<property name="hibernate.connection.isolation">4property>
<property name="hibernate.current_session_context_class">threadproperty>
<mapping resource="cn/itheima/domain/Customer.hbm.xml" />
session-factory>
hibernate-configuration>
业务开始之前打开事务,业务执行之后提交事务. 执行过程中出现异常.回滚事务.
在dao层操作数据库需要用到session对象.
在service控制事务也是使用session对象完成.
我们要确保dao层和service层使用的使用同一个session对象
在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了. 我们开发人员只需要调用sf.getCurrentSession()方法即可获得与当前线程绑定的session对象,底层还是 ThreadLocal
。
调用getCurrentSession方法必须配置
<property name="hibernate.current_session_context_class">threadproperty>
通过getCurrentSession方法获得的session对象.当事务提交时,session会自动关闭.不要手动调用close关闭,手动 close 会报异常。
(多表查询,但不复杂时使用)
Hibernate独家查询语言,属于面向对象的查询语言
//测试HQL语句
public class Demo {
@Test
//基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
// String hql = " from cn.itheima.domain.Customer ";
// 只有一个类名的话,那么可以不写包名。
String hql = " from Customer "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3> 根据查询对象获得查询结果
List list = query.list(); // 返回list结果
//query.uniqueResult();//接收唯一的查询结果
System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
}
@Test
//条件查询
//HQL语句中,不可能出现任何数据库相关的信息的
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = 1 "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();
System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//排序
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " from cn.itcast.domain.Customer order by cust_id asc ";//完整写法
String hql2 = " from cn.itcast.domain.Customer order by cust_id desc ";//完整写法
Query query = session.createQuery(hql2);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//条件查询
//问号占位符
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = ? "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
//query.setLong(0, 1l);
query.setParameter(0, 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();
System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//条件查询
//命名占位符
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = :cust_id "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
query.setParameter("cust_id", 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();
System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//分页查询
public void fun5(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置分页信息 limit ?,?
query.setFirstResult(1);
query.setMaxResults(1);
//3> 根据查询对象获得查询结果
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//统计查询
//count 计数
//sum 求和
//avg 平均数
//max
//min
public void fun5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " select count(*) from cn.itcast.domain.Customer ";//完整写法
String hql2 = " select sum(cust_id) from cn.itcast.domain.Customer ";//完整写法
String hql3 = " select avg(cust_id) from cn.itcast.domain.Customer ";//完整写法
String hql4 = " select max(cust_id) from cn.itcast.domain.Customer ";//完整写法
String hql5 = " select min(cust_id) from cn.itcast.domain.Customer ";//完整写法
Query query = session.createQuery(hql5);
Number number = (Number) query.uniqueResult();
System.out.println(number);
//----------------------------------------------------
tx.commit();
session.close();
}
就是查询默写字段名字,不是全部* 。
@Test
//投影查询
public void fun6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " select cust_name from cn.itcast.domain.Customer ";
// 字段查询到自动封装Object[] 中
String hql2 = " select cust_name,cust_id from cn.itcast.domain.Customer ";
// 字段查询到自动封装到 Model中,同时Customer需要创建2个参数的构造函数。
String hql3 = " select new Customer(cust_id,cust_name) from cn.itcast.domain.Customer ";
Query query = session.createQuery(hql3);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
//学习HQL语法(不常用) - 多表查询语法
public class Demo2 {
//回顾-原生SQL
// 交叉连接-笛卡尔积(避免)
// select * from A,B
// 内连接
// |-隐式内连接
// select * from A,B where b.aid = a.id
// |-显式内连接
// select * from A inner join B on b.aid = a.id
// 外连接
// |- 左外
// select * from A left [outer] join B on b.aid = a.id
// |- 右外
// select * from A right [outer] join B on b.aid = a.id
//---------------------------------------------------------------------
//HQL的多表查询
//内连接(迫切)
//外连接
// |-左外(迫切)
// |-右外(迫切)
@Test
//HQL 内连接 => 将连接的两端对象分别返回.放到数组中.
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from Customer c inner join c.linkMens ";
Query query = session.createQuery(hql);
List
(单表条件查询)
Hibernate自创的无语句面向对象查询
//测试Criteria查询
public class Demo {
@Test
//基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//查询所有的Customer对象
Criteria criteria = session.createCriteria(Customer.class);
List list = criteria.list();
System.out.println(list);
// Customer c = (Customer) criteria.uniqueResult();
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
}
@Test
//条件查询
//HQL语句中,不可能出现任何数据库相关的信息的
// > gt
// >= ge
// < lt
// <= le
// == eq
// != ne
// in in
// between and between
// like like
// is not null isNotNull
// is null isNull
// or or
// and and
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//添加查询参数 => 查询cust_id为1的Customer对象
criteria.add(Restrictions.eq("cust_id", 1l));
//执行查询获得结果
Customer c = (Customer) criteria.uniqueResult();
System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//分页查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置分页信息 limit ?,?
criteria.setFirstResult(1);
criteria.setMaxResults(2);
//执行查询
List<Customer> list = criteria.list();
System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//查询总记录数
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置查询的聚合函数 => 总行数
criteria.setProjection(Projections.rowCount());
//执行查询
Long count = (Long) criteria.uniqueResult();
System.out.println(count);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//排序语法
public void fun4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = session.createCriteria(Customer.class);
c.addOrder(Order.asc("cust_id"));
//c.addOrder(Order.desc("cust_id"));
List list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
区别就是创建的时候是否需要 session
//学习离线Criteria
public class Demo2 {
@Test
public void fun1(){
//Service/web层
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.idEq(6l));//拼装条件(全部与普通Criteria一致)
//----------------------------------------------------
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = dc.getExecutableCriteria(session);
List list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
}
演示
(复杂的业务查询)
@Test
//基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer";
//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
//3 调用方法查询结果
List list = query.list();
//query.uniqueResult();
for(Object[] objs : list){
System.out.println(Arrays.toString(objs));
}
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//基本查询
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer";
//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);
//3 调用方法查询结果
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//条件查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer where cust_id = ? ";
//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
query.setParameter(0, 1l);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);
//3 调用方法查询结果
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
@Test
//分页查询
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer limit ?,? ";
//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
query.setParameter(0, 0);
query.setParameter(1, 1);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);
//3 调用方法查询结果
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
Customer.hbm.xml
<hibernate-mapping package="cn.itcast.domain" >
<class name="Customer" table="cst_customer" >
<id name="cust_id" >
<generator class="native">generator>
id>
<property name="cust_name" column="cust_name" >property>
<property name="cust_source" column="cust_source" >property>
<property name="cust_industry" column="cust_industry" >property>
<property name="cust_level" column="cust_level" >property>
<property name="cust_linkman" column="cust_linkman" >property>
<property name="cust_phone" column="cust_phone" >property>
<property name="cust_mobile" column="cust_mobile" >property>
<set name="linkMens" inverse="true" cascade="save-update" >
<key column="lkm_cust_id" >key>
<one-to-many class="LinkMan" />
set>
class>
hibernate-mapping>
LinkMan.hbm.xml
<hibernate-mapping package="cn.itcast.domain" >
<class name="LinkMan" table="cst_linkman" >
<id name="lkm_id" >
<generator class="native">generator>
id>
<property name="lkm_gender" >property>
<property name="lkm_name" >property>
<property name="lkm_phone" >property>
<property name="lkm_email" >property>
<property name="lkm_qq" >property>
<property name="lkm_mobile" >property>
<property name="lkm_memo" >property>
<property name="lkm_position" >property>
<many-to-one name="customer" column="lkm_cust_id" class="Customer" >
many-to-one>
class>
hibernate-mapping>
使用级联操作
//一对多|多对一关系操作
public class Demo {
@Test
//保存客户 以及客户 下的联系人
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
Customer c = new Customer();
c.setCust_name("百度公司");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("李彦宏");
LinkMan lm2 = new LinkMan();
lm2.setLkm_name("小度");
//表达一对多,客户下有多个联系人
c.getLinkMens().add(lm1);
c.getLinkMens().add(lm2);
//表达对对对,联系人属于哪个客户
lm1.setCustomer(c);
lm2.setCustomer(c);
session.save(c);
// 使用级联操作,不用互相保存
// session.save(lm1);
// session.save(lm2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
@Test
//为客户增加联系人
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得要操作的客户对象
Customer c = session.get(Customer.class,1l);
//2> 创建联系人
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("郝强勇");
//3> 将联系人添加到客户,将客户设置到联系人中
c.getLinkMens().add(lm1);
lm1.setCustomer(c);
//4> 执行保存
session.save(lm1);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
@Test
//为客户删除联系人
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得要操作的客户对象
Customer c = session.get(Customer.class,1l);
//2> 获得要移除的联系人
LinkMan lm = session.get(LinkMan.class, 3l);
//3> 将联系人从客户集合中移除
c.getLinkMens().remove(lm);
lm.setCustomer(null);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
}
"customer" column="lkm_cust_id" class="Customer" >
//测试级联操作
public class Demo2 {
@Test
//保存客户 以及客户 下的联系人
//cascade:save-update
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
Customer c = new Customer();
c.setCust_name("百度公司");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("李彦宏");
LinkMan lm2 = new LinkMan();
lm2.setLkm_name("小度");
//表达一对多,客户下有多个联系人
c.getLinkMens().add(lm1);
c.getLinkMens().add(lm2);
//表达对对对,联系人属于哪个客户
lm1.setCustomer(c);
lm2.setCustomer(c);
session.save(c);
// session.save(lm1);
// session.save(lm2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
@Test
//测试删除客户时,级联删除客户下的联系人
//cascade:delete
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得要操作的客户对象
Customer c = session.get(Customer.class,1l);
//2>调用delete删除客户
session.delete(c);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
@Test
//保存联系人以及联系人对应的客户
//cascade:save-update
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
Customer c = new Customer();
c.setCust_name("北大青鸟");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("刘总");
//表达一对多,客户下有多个联系人
c.getLinkMens().add(lm1);
//表达多对一,联系人属于哪个客户
lm1.setCustomer(c);
session.save(lm1);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
}
简化操作.一定要用:save-update,不建议使用delete,delete 会把外键关联的记录也删除,太危险了.
inverse属性: 性能优化,提高关系维护的性能。
原则: 无论怎么放弃,总有一方必须要维护主键关系。
inverse=”true”放弃维护。一对多关系中: 一的一方放弃,也只能一的一方放弃。
多的一方不能放弃,外键在多方的表中。
<set name="linkMens" inverse="true" cascade="save-update" >
<key column="lkm_cust_id" >key>
to-many class="LinkMan" />
set>
//操作进阶--关系维护属性
public class Demo3 {
@Test
//保存客户 以及客户 下的联系人
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
Customer c = new Customer();
c.setCust_name("百度");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("李彦宏");
LinkMan lm2 = new LinkMan();
lm2.setLkm_name("小度");
//表达一对多,客户下有多个联系人.
// 如果客户放弃维护与联系人的关系. 维护关系的代码可以省略
//c.getLinkMens().add(lm1);
//c.getLinkMens().add(lm2);
//表达多对一,联系人属于哪个客户
lm1.setCustomer(c);
lm2.setCustomer(c);
session.save(c);
session.save(lm1);
session.save(lm2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
}
因为联系人表外键了客户表,所以不能直接删除客户。
@Test
//删除客户
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
Customer customer = session.get(Customer.class, 1l);
session.delete(customer);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
Role.hbm.xml
<hibernate-mapping package="cn.itcast.domain" >
<class name="Role" table="sys_role" >
<id name="role_id" >
<generator class="native">generator>
id>
<property name="role_name" >property>
<property name="role_memo" >property>
<set name="users" table="sys_user_role" inverse="true" >
<key column="role_id" >key>
<many-to-many class="User" column="user_id" >many-to-many>
set>
class>
hibernate-mapping>
User.hbm.xml
<hibernate-mapping package="cn.itcast.domain" >
<class name="User" table="sys_user" >
<id name="user_id" >
<generator class="native">generator>
id>
<property name="user_code" >property>
<property name="user_name" >property>
<property name="user_password" >property>
<property name="user_state" >property>
<set name="roles" table="sys_user_role" cascade="save-update" >
<key column="user_id" >key>
<many-to-many class="Role" column="role_id" >many-to-many>
set>
class>
hibernate-mapping>
中间表报错,必须只能一方维护外键关系,如果双方都维护外键关系,那么中间表会插入练体能一样的记录,造成中间表的主键重复。
将来在开发中,如果遇到多对多关系.一定要选择一方放弃维护关系.
一般谁来放弃要看业务方向. 例如录入员工时,需要为员工指定所属角色.
那么业务方向就是由员工维护角色. 角色不需要维护与员工关系.角色放弃维护.
操作关联属性
//多对多关系操作
public class Demo {
//为郝强勇解除一个角色
@Test
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得郝强勇用户
User user = session.get(User.class, 1l);
//2> 获得要操作的角色对象(保洁,保安)
Role r1 = session.get(Role.class, 1l);
Role r2 = session.get(Role.class, 2l);
//3> 将角色从用户的角色集合中移除
user.getRoles().remove(r1);
user.getRoles().remove(r2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
}
//保存员工以及角色
@Test
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 创建两个 User
User u1 = new User();
u1.setUser_name("郝强勇");
User u2 = new User();
u2.setUser_name("金家德");
//2> 创建两个 Role
Role r1 = new Role();
r1.setRole_name("保洁");
Role r2 = new Role();
r2.setRole_name("保安");
//3> 用户表达关系
u1.getRoles().add(r1);
u1.getRoles().add(r2);
u2.getRoles().add(r1);
u2.getRoles().add(r2);
//4> 角色表达关系
r1.getUsers().add(u1);
r1.getUsers().add(u2);
r2.getUsers().add(u1);
r2.getUsers().add(u2);
//5> 调用Save方法一次保存
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
注意:
中间表报错,必须只能一方维护外键关系,如果双方都维护外键关系,那么中间表会插入练体能一样的记录,造成中间表的主键重复。
//为郝强勇新增一个角色
@Test
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 开启事务
Transaction tx = session.beginTransaction();
//-------------------------------------------------
//3操作
//1> 获得郝强勇用户
User user = session.get(User.class, 1l);
//2> 创建公关角色
Role r = new Role();
r.setRole_name("男公关");
//3> 将角色添加到用户中
user.getRoles().add(r);
//4> 将角色转换为持久化
//session.save(r);//增加级联操作可以省略这一行
//-------------------------------------------------
//4提交事务
tx.commit();
//5关闭资源
session.close();
}
结论: cascade简化代码书写.该属性使不使用无所谓.
建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.
get方法:没有任何策略.调用即立即查询数据库加载数据.
load方法: 应用类级别的加载策略
lazy=”true”(默认值), 查询类时,会返回代理对象。会在使用属性时,根据关联的session查询数据库.加载数据.
lazy=”false”。load方法会与get方法没有任何区别.调用时即加载数据.
结论:为了提高效率.建议使用延迟加载(懒加载)
Customer.hbm.xml
属性:lazy="false"
<hibernate-mapping package="cn.itcast.domain" >
<class name="Customer" table="cst_customer" lazy="false" >
<id name="cust_id" >
<generator class="native">generator>
id>
<property name="cust_name" column="cust_name" >property>
<property name="cust_source" column="cust_source" >property>
<property name="cust_industry" column="cust_industry" >property>
<property name="cust_level" column="cust_level" >property>
<property name="cust_linkman" column="cust_linkman" >property>
<property name="cust_phone" column="cust_phone" >property>
<property name="cust_mobile" column="cust_mobile" >property>
<set name="linkMens" batch-size="3" fetch="join" lazy="proxy" >
<key column="lkm_cust_id" >key>
<one-to-many class="LinkMan" />
set>
class>
hibernate-mapping>
为了提高效率.fetch的选择上应选择select. lazy的取值应选择 true. 全部使用默认值.
参考自某某培训机构。