1。框架是什么
框架是用来提高开发效率的,封装了好多的功能我们使用这些功能的时候,调用即可,不需要手动实现,所以框架就是一个半成品的项目,只要懂得如何使用这些功能即可
我们需要学习的框架和各部分之间的作用
2.
3.使用hibernate的好处
操作数据库的时候我们可以使用面向对象的方式来完成,不需要书写sql语句
hibernate是一款orm框架,orm————指的是object ralationmapping 对象关系映射
二,环境的搭建
1.导包>>>> /hiberante/lib/required 下的所有包+数据库的驱动包
2.创建数据库 准备表和实体()
3.书写主配置文件命名规则是 hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<!-- #hibernate.dialect org.hibernate.dialect.MySQLDialect #hibernate.dialect
org.hibernate.dialect.MySQLInnoDBDialect #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
#hibernate.connection.driver_class com.mysql.jdbc.Driver #hibernate.connection.url
jdbc:mysql:///test #hibernate.connection.username gavin #hibernate.connection.password -->
<!-- 数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<!-- 数据库url -->
<property name="hibernate.connection.url">jdbc:mysql:///test1?serverTimezone=UTC</property>
<!-- 数据库连接用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库连接密码 -->
<property name="hibernate.connection.password">123456</property>
<!-- 数据库方言 不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成. sql99标准:
DDL 定义语言 库表的增删改查 DCL 控制语言 事务 权限 DML 操纵语言 增删改查 注意: MYSQL在选择方言时,请选择最短的方言. -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- #hibernate.show_sql true #hibernate.format_sql true -->
<!-- 将hibernate生成的sql语句打印到控制台 -->
<property name="hibernate.show_sql">true</property>
<!-- 将hibernate生成的sql语句格式化(语法缩进) -->
<property name="hibernate.format_sql">true</property>
<!-- ## auto schema export 自动导出表结构. 自动建表 #hibernate.hbm2ddl.auto create
自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用) #hibernate.hbm2ddl.auto create-drop
自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用) #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
#hibernate.hbm2ddl.auto validate 校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败. -->
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<!-- 指定hibernate操作数据库时的隔离级别 #hibernate.connection.isolation 1|2|4|8 0001
1 读未提交 0010 2 读已提交 0100 4 可重复读 1000 8 串行化 -->
<property name="hibernate.connection.isolation">4</property>
<!-- 指定session与当前线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 引入orm元数据 路径书写: 填写src下的路径 -->
<mapping resource="com/liangxin/domain/Customer.hbm.xml" />
<mapping resource="com/liangxin/domain/LinkMan.hbm.xml" />
<mapping resource="com/liangxin/domain/User.hbm.xml" />
<mapping resource="com/liangxin/domain/Role.hbm.xml" />
</session-factory>
</hibernate-configuration>
4.
书写orm元数据(对象和表之间的对应关系)
<hibernate-mapping package="com.liangxin.domain" >
//name对应完整类名 class对应数据库中表的名字
<class name="User" table="sys_user" >
// id对应主键的名称
<id name="user_id" >
//主键生成策略
<generator class="native"></generator>
</id>
//property 对应表中除了主键之外的普通属性的映射 当数据库中属性的名称和实体中的属性完全相同时 column属性可以省略
<property name="user_code" ></property>
<property name="user_name" ></property>
<property name="user_password" ></property>
<property name="user_state" ></property>
书写测试代码
@Test
public void fun1(){
//加载主配置文件
Configuration conf= new Configuration().configure;
//创建sessionFatory工厂 用于创建操作数据库核心对象session对象的工厂, 保证在一个web项目中,只创建一个sessionfactory 是线程安全的
SessionFactory sessionFactory= conf.buildSessionFactory();
//创建一个session对象 相当于jdbc中的connection对象,还可以完成对数据库中的正删改查操作
Session session=sessionFactory.opensession();
//获得事务
Transaction tx=session.beginTransaction();
Customer c= new Customer();
c.setCust_name();
//保存对象
session.save();
//提交对象
tx.commit();
session.close();
sessionFactory.close();
}
5.将orm元数据引入配置文件中也就是hibernate.cfg.xml 文件中
<mapping resource ="cn/itheima/domain/customer.hbm.xml"/>
hibernate中实体的规则
持久化类提供无参构造 成员变量私有,提供共有的getset方法 需提供属性 属性应该尽量使用包装类型持久化需要提供oid与数据库中的主键对应,不能用final修饰类 ,hibernate使用cglib代理, 代理对象是通过继承来实现的,
主键的类型——自然主键 (就是表中自己有的不需要外加)和代理主键(表的业务列中没有 例如我们自己加入的id 和项目的业务没有关系)
2.主键的生成策略
代理主键———— identity 主键自增,有数据库来维护主键的
sequence Oracle中的主键生成策略
increment 主键自增,有hibernate来进行维护,每次插入前后都会先查询表中的id最大值+1 座位新的主键值
hilo———— 高低位算法,主键自增,有hibernate来维护,开发是不使用
native——————hilo +- sequence +identity ) 自动三选一 我们开发中使用这个
uuid:产生随机字符串作为主键,主键类型必须使用string类型
3.hibernate中对象的三种状态————
瞬时态 没有id 没有在session缓存中
持久态:有id 在session缓存中
游离态:有id 没有在session缓存中
三种状态的转换图如下
hibernate中的一级缓存 :提高效率,hibernate'中的一级缓存也是为了提高操作数据库中的数据,减少不必要的修改语句的发送。提高查询效率
缓存的原理图
5.hibernate中的事务事务的特性 a.原子性 一致性 隔离性 持久性
事务并发的问题 1.脏读 不可重复读 虚度 事务的隔离级别 读未提交 读已提交 可重复度 序列化 分别对应 1248
在项目中怎样管理事务 在业务开始之前打开事务,业务执行之后提交事务,执行过程中如果有异常 回滚事务
在dao层操作数据库需要用到session对象 在service控制事务,也是使用session对象来完成 我们要确保dao层和service层中使用的是用一个session对象,在hibernate中,确保使用同一个session的问题,hibernate已经帮助我们解决了,我们开发时只需要使用sf.getCurrentSession()方法 就可以获得与当前线程绑定的session对象
三.表与表之间的关系 一对多 多对多
1.一对多 比如说客户与联系人之间就是一对多的关系
我们采用将少的一方中的主键放到多的一方作为外键;
在实体中我们的表示
在orm元数据中表示也就是在配置文件中表示 一的一方拥有一个集合配置文件如下
在多的一方的配置文件
级联操作 :cascade 属性有三个 save-update级联保存更新 | delete——级联删除 | all save-update+ delete
关系维护:在保存时,两方都会维护外键关系,关系维护两次 没有必要,浪费资源
关系之间的维护 :inverser属性 true表示 不维护关系 false表示维护关系 在一对多的关系中 一得一方放弃维护,多的一方来维护
关系
四,多对多之间的关系
比如说员工表和角色表 就是多对多的关系在表中的关系如下
在实体中
3.在orm元数据中
wu
五.hibernate 中的数据库操作
1.hql查询语法
HQL语法
1.基础语法
String hql="from cn.itcast.domain.Customer";
String hql2="from customer;
Query query=session.createQuery(hql2);
List<>list=query.list();
2.排序问题
String hql="form cn.itcast .domain.customer order by cust_id asc";
Stirng hql2="from cn.itcast.domain.customer order by cust_id desc";
Qquery query=session.createQuery();
List<> list= query.list();
3.条件chacun
String hql="from cn.itcast.domain.customer where cust_id=?";
String hql2="from cn.itcast.domain.customer where cust_id= : id";
Query query = session.createQuery(hql);
query.setParameter(o ,2l);
query.setParameter("id",2l);
List<> list=query.list();
4.分页
String hql1="from cn.itcast.domain .customer";
Query query session.createQuery(hql)
query.setFirstResult(2);
query.setMaxResult(2);
List<> list =query.list();
5.聚合函数
string hql="select count(*) from cn.itcast.domain .customer";
string hql ="select sum(cust_id ) from cn.itcast.domain.customer";
string hql ="select avg(cust_id) from cn.itcast.domain .customer ";
Query querey = session.createQuery();
number query.uniqueResult();
6.投影
string hql ="select cust_name from cn.itcast.domain.customer";
Query query session.createQuery(hql);
List<> list= query.list();
7. 多表查询
回顾原生的 select * from A,B;
内连接:隐士内连接;select *from A,B Wwhere b.aid = a.aid ;
显式内连接:select* from A inner join B ON b.aid = a.aid;
外链接:
左外链接: select * from a left [outer] join B on b.aid = a.aid;
右外链接:select*from A right join b on b.aid = a.aid;
在hql中
内连接:string hql="form customer c inner join c.linkMens";
Query query= session.createQuery(hql);
List<> list=query.list();
string hql = "from customer c inner join fetch c.linkMens"'
Query query= session.createQuery(hql);
List<> list=query.list();
左外链接:
string hql =" from customer c left join c.linkMens";
Query query= session.createQuery(hql);
List<> list=query.list();
右外链接:
string hql ="from customer c right joion c.linkMens";