使用博客来记录自己的学习历程,的确是个不错的选择 多年以后,当自己回首往事时,会不会感谢现在努力的自己呢? O(∩_∩)O哈哈哈~
@ORM框架 对象关系映射,用于实现面向对象编程语言里不同系统的数据之间的转换 @实例 public void demo01(){ User user = new User(); user.setUsername("haha"); user.setPassword("123"); //加载配置文件获得核心配置对象 Configuration config = new Configuration().configure("配置文件"); //获得工厂SessionFactory,相当于连接池 SessionFactory factory = config.buildSessionFactory(); //获得回话session,相当于链接Connection Session session = factory.openSession(); //开启事务 Transaction transaction = session.beginTransaction(); //操作 session.save(user); //提交事务 | 回滚事务 transaction.commit(); //释放资源 session.close(); //关闭工厂 factory.close(); } PO:persistent object ,用于与数据库交互数据 BO:Business object 业务数据对象 VO: value Object 值对象 @Configuration配置对象 1:提供构造 new Configuration() hibernate 将自动加载hibernate.properties 2:提供方法 configure() 将加载src下的hibernate.cfg.xml 3:扩展api configure(String) 加载执行目录下的xml文件 4:手动加载配置文件 //手动加载指定的配置文件 config.addResource("com/shikun/hello/User.hbm.xml"); //手动加载指定类,对应的映射文件 config.addUser(user.class); @SessionFactory工厂 1:SessionFactory相当于java web连接池,用于管理所有session 2:获得方式:config.buildSessionFactory(); 3:sessionFactory hibernate缓存配置信息(数据库配置信息,映射文件) 4:SessionFactory线程安全,可以是成员变量,多个线程同时访问 5://打开一个新的回话 session factory.openSession(); //获得当前线程中绑定的会话session factory.getCurrentSession(); 6:hibernate支持,将创建session绑定到本地线程中,底层使用ThreadLoacl,在程序之 间共享session 1:必须在hibernate.cfg.xml配置 <property name="hibernate.current_session_context_class">thread</property> 2:如果提交或回滚事务,底层将自顶关闭session @Session会话 1:Session相当于JDBC的Connection会话 2:session单线程,线程不安全,不能编写成员变量 3:session api 1:save 保存 2:update 更新 3:delete:删除 4:get:通过id查询,如果没有 null 5:load 通过id查询,如果没有跑异常 6:createQuery("hql") 获得Query对象 7:createCriteria(class) 会的Criteria对象 @Transaction事务 1:开启事务 beginTransaction() 2:获得事务 getTransaction() 3:提交事务 commit() 4:回滚事务 rollback() @Query对象 1:hibernate执行hql语句 2:hql语句:hibernate提供面向对象查询语句,使用对象和属性进行查询 3:获得session.createQuery("hql"); 4:方法: list() 查询所有 uniqueResult():获得一个结果,如果没有查询到返回null,如果查询多条抛异常 setFirstResult(int) 分页,开始索引数startIndex setMaxResult(int) 分页,每页显示个数 pageSize @Criteria对象 1:QBC(query by criteria),hibernate提供春面向对象查询语言 2:获得方式:Criteria criteria = session.createCriteria(User.class); 3:eq :等于 gt:大于 ge:大于等于 lt:小于 le:小于等于 like:模糊查询 @hibernate基本配置 <property name="hibernate.connection.driver_class>com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://db</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123</property> //与本地线程绑定 <property name="hibernate.current_session_context_class">thread</property> //方言:不同的数据库,生成sql语句提供依据 <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Diaelct</property> //sql语句 <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> //表生成策略 <property name="hibernate.hbm2ddl.auto">create</property> //验证 <property name="javax.persistence.validation.mode">none</property> //添加映射文件 <mapping resource="com/shikun/hello/User.hbm.xml"/> @hibernate中持久化类 1:持久化对象的唯一标识OID 1:javaan地址区分同一个类的不同对象 2:关系数据库用主键区分同一条记录 3:Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系 4:对象的OID和数据库的标的主键对应,由hibernate来为OID赋值 2:区分自然主键和代理主键 主键需要具备:不为空,不能重复,不能改变 1:自然主键:在业务中,某个属性符合主键的三个要求,该属性可以作为主键列 2:代理主键:在业务中,不存符合以上三个条件的属性,就增加一个没有意义的列 作主键 3:基本数据与包装类型 1:基本类型无法表达null,默认为0 2:包装类默认值是null @主键生成策略 <id>配置主键,name:属性名称 access=““ 设置使用属性还是字段 column=”“ 表的列名 length=“” 长度 type=“” 类型 <generator>class 属性用于设置主键生成策略 1:increment 由hibernate自己维护自动增长 2:identity hibernate磁层采用数据库本身自动增长列 3:sequence hibernate底层采用数据库序列 4:Hilo 5:native:根据底层数据库的能力选择 identity,sequence或者Hilo中的一个 6:uuid 采用字符串唯一值,代理主键,由hibernate维护 7:assigned 自然主键,由程序自己维护 @对象状态 hibernate规定三种状态:瞬时态,持久态,脱管态 1:瞬时态:transient,session没有缓存对象,数据库也没有对应记录,OID没有值 2:持久态:persistent,session缓存对象,数据库最终会有记录 OID特点:有值 3:脱管态:detached,session没有缓存对象,数据库有记录 OID有值 4:状态转换 1:瞬时态转换持久态 一般操作:save方法,saveOrUpdate 2:瞬时态转换脱管态 一般操作:通过setId方法设置数据 @一级缓存 1:又称为session级别的缓存,当获得一次会话session,hibernate在session中创建多 个集合map,用于存放操作数据po对象,为程序优化服务,如果之后需要相应的数据, hibernate优先从session缓存中获取,如果有就使用;如果没有在查询数据库。当session关闭时,一级缓存销毁 2:清除缓存 session.evict(对象); 3:快照:与一级缓存一样的存放位置,对一级缓存数据备份,保证数据库的数据与一级 缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一集缓存,执行update语句,将一级缓存的数据更新到数据库 4:refresh 刷新:保证一级缓存的数据与数据库的数据保证一致将执行select语句查询数据库,将一级缓存中的数据覆盖掉,只要执行refresh都将执行select语句 @PO对象操作 1save&persist save方法:瞬时态转换持久态,会初始化OID 1:执行save方法,立即触发insert语句,从数据库获得主键的值OID值 2:执行save方法前,设置OID将忽略 3:如果执行查询,session缓存移除了,在执行save方法,将执行insert 4:persist方法不会立即得到ID,所以执行sql语句的时机要靠后 2:update :脱管态 转换 持久态 1:如果OID在数据存放的,将执行update语句 2:如果OID不存在将抛异常 3:saveOrUpdate:判断是否有OID 代理主键: 1:如果没有OID,将执行insert语句 2:如果有OID,将执行update语句 自然主键: 1:先执行select语句,查询是否存放 2:如果不存在,将执行insert 3:如果存在,将执行update @多表设计 一对多:主表必须主键和从表必须外键,主表的主键与从表外键形成主外键关系 多对多:提供中间表,提供2个字段(外键)分别对应两个主表 @关联关系映射 1:一对多实现:一个客户,拥有多个订单 private Set<Order> orderSet = new HashSet<Order>(); 配置文件 1:确定容器 set<set> 2: name确定对象属性名 3:确定从表外键的名称 4:确定关系,及另一个对象的类型 注意:在hibernate中可以只进行单项配置,每一个配置项都可以完整的描述彼此关系,一般情况采用双向配置,双方都可以完成描述表与表之间关系 <set name="orderSet" cascade="delete-orphan"> <key column="customer_id"></key> <one-to-many class="com.shikun.Order"/> </set> 多对一:多个订单属于一个客户 private Customer customer; 配置文件 1:name 确定属性名称 2:class 确定自定义类型 3:column 确定从表的外键名称 <many-to-one name="custoemr" class="com.shikun.Customer" column="customer_id"></many-to-one> 2:双向关联,使用inverse <set name="orderSet" inverset="true"> <key column="customer_id"></key> <one-to-many class="com.shikun.Order"/> </set> 3:级联操作 1:save-update 级联保存或更新 <set name="orderSet" cascade="save-update"> </set> 2:delete 级联删除 <set name="orderSet" cascade="delete"> </set> 3:孤儿删除:一对多关系,存在父子关系,主表可以成为父表多表也可以成为子表 客户和订单接触关系后,外键被设置成null,此时订单就是孤儿,两者单独存在 孤儿删除,当订单称为孤儿,一并删除,客户仍存在 主表不能删除,从表已经引用(关联)的数据 从表不能添加,主表不存在的数据 <set name="orderSet" cascade="delete-orphan"> </set> 4:多对多映射 配置多对多关联映射 Course.hbm.xml <set name="students" table="stu_cour"> <key column="cno"/> <many-to-many class="com.shikun.Student" column="sno"/> </set> Student.hbm.xml <set name="course" table="stu_cour"> <key column="sno"/> <many-to-many class="com.shikun.Course" column="cno"/> </set> @抓取策略 1:检索方法 a:立即检索:立即查询,在执行查询语句时,立即查询所有的数据 b:延迟检索:延迟查询,在执行查询语句之后,在需要时在查询(懒加载) 2:检索策略 a:类级别检索:当前的类的属性获取是否需要延迟 b:关联级别的检索:当前类关联另一个类是否需要延迟 3:类级别检索 a:get :立即检索,get方法一执行,立即查询所有字段的数据 b:load:延迟检索,默认情况,load方法执行后,如果只使用OID的值不进行查询 如果要使用其他属性值将lazy默认值TRUE,为FALSE,表示立即检索 4:关联级别检索 a:一对多或多对多 1:容器<set>提供两个属性:fetch,lazy fetch:确定使用sql格式 lazy:关联对象是否延迟 2:fetch:join,select,subselect join:底层使用迫切左外链接,lazy无效 select:使用多个select语句 subselect:使用子查询 3:lazy:FALSE,true,extra false:立即 TRUE:延迟 extra:极其懒惰 b:多对一:<many-to-one fetch="" lazy=""> 1:fetch:取值:join,select join:底层使用迫切左外链接 select:多条select语句 2:lazy取值:FALSE,proxy,no-proxy,no-proxy FALSE:立即 proxy:采用关联对象,类级别检索的策略 5:批量查询 1:批量查询使用in语句减少查询语句的个数 select * from order where customer in(?,?,?,?,?) 2:<set batch-size="5">:5表示括号中?个数 @HQL:Hibernate Query Language 描写对象操作一种查询语句,查询的是对象的属性 1:查询所有客户 1:使用简单类名,存在自动导包 session.createQuery("from 简单类名"); 2:使用全限定类名 session.createQuery("from com.shikun.简单类名"); 2:选择查询 1:指定数据,cid,OID民称 2:使用id 3:对象别名 4:查询所有项 3:投影查询 1:默认 a:单列使用List<object> b:多列需要List<Object[]> 4:order by asc|desc 5:分页 startIndex = (pageNum -1 )* pageSize //pageNum 当前页 query.setFirstResult(); //pageSize:每页显示个数 query.setMaxResults() 6:绑定参数 1:setXxx(int,object) 2:setXxx(String,object) 3:setParameter(int|string,object) 7:聚合函数和分组 1:count(*|别名|oid) 8:连接查询 1.交叉连接 ,等效 sql 笛卡尔积 2.隐式内连接,等效 sql 隐式内连接 3.内连接,等效sql内连接 4.迫切内连接,hibernate底层使用 内连接。 5.左外连接,等效sql左外连接:底层是使用sql的左外链接,hibernate进行数据 自动封装,将一条记录封装给两个对象 6.迫切左外连接,hibernate底层使用 左外连接 left outer join fetch ,底层使用sql的左外链接,hibernate将一条记录封装给一个对象,将另一条数据封装给另一个对象,并将对象2关联到对象1,默认查询的数据重复 去重复 select distinct c from Customer left outer join fetch c.orderSet 7.右外连接,等效sql右外连接 9:命名查询 全局:session。getNamedQuery("queryName"); 局部:session.getNamedQuery("className.queryName"); 需要使用类的全限定名称 @QBC 1:QBC查询:Query By Criteria 条件查询,面向对象的查询的方式 2:QBC简单的查询:session.createCriteria(Customer.class); 3: QBC分页的查询: criteria.setFirstResult(10); criteria.setMaxResults(10); 4:QBC排序查询: criteria.addOrder(org.hibernate.criterion.Order.asc("")); 5:QBC条件查询 criteria.add(Restrictions.eq("属性","值")); //模糊查询 criteria.add(Restrictions.like("属性","条件")); 6:离线查询:DetachedCriteria 离线查询对象,不需要session,在web 或service层拼凑,将此对象传递给dao层 DetachedCriteria detachedCtiteria = DetachedCriteria.forClass(Customer.class); @整合c3p0连接池 <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProcider</property> @事务 悲观锁:丢失更新发生,采用数据库锁机制 读锁:共享锁 select ... from ... lock in share mode; 写锁:排它锁 select ... from ... for update session.get(Customer.class,1,LockMode.UPGRADE); 乐观锁:丢失更新肯定不会发生,在po对象|表中提供一个字段,一般Integer在hbm.xml文件配置<version name="...">,用于表示记录,如果版本不一致,不允许操作 @二级缓存:降低应用程序直接读写硬盘的频率 1:hibernate提供缓存机制:一级缓存,二级缓存 一级缓存:session级别缓存,在一次请求中共享数据 二级缓存:sessionFactory级别缓存,整个应用程序共享一个会话工厂 2:SessionFactory的缓存两部分:内置缓存:使用一个Map,用于存放配置信息,预 定义HQL语句,提供给Hibernate框架自己使用,对外只读的,不能操作 ; 外置缓存:使用另一个Map,用于存放用户自定义数据,默认不开启,外置缓存hibernate只提供规范,需要第三方实现类,外置缓存又称为二级缓存 3:二级缓存内部结构 由四部分组成:类级别缓存,集合级别缓存,时间戳缓存,查询缓存 4:并发访问策略 1:transactional:事务型 2:read-write:读写型 3:nonstrict-read-write:非严格读写型 4:read-only:只读型 5:二级缓存提供商 EHCache: 可作为进程(单机)范围内的缓存,存放数据的物理介质可以是内存或硬盘, 对 Hibernate 的查询缓存提供了支持。--支持集群。 ?OpenSymphony `:可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持 ?SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存 ?JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存 6:开启二级缓存 <property name="hibernate.cache.user_second_level_cache">true</property> 确定提供商 <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 确定缓存内容 <class-cache usage="read-write" class=""/> //集合缓存 <collection-cache usage="read-write" collertion=""/> 7;类缓存:只存放数据 一级缓存:存放对象本身 8:集合缓存:只存放关联对象OID的值,集合操作,将从集合缓存获得内容,此时只 能获得OID的值,然后从类缓存查询指定对象 9:时间戳:任何操作都在时间戳中记录操作时间,如果不一致,将触发select语句 10:查询缓存:又称为三级缓存,将HQL语句与查询结果进行绑定,通过HQL相同语句可以缓存内容,默认情况Query对象枝江查询结果存放在一级和二级缓存,查询缓存就是让Query可以从二级缓存获得内容 1:开启查询缓存 <property name="hibernate.cache.use_query_cache">true</property> 2:在查询query对象,设置缓存内容 Query q = s.createQuery("from student"); q.setCacheable(true);