hibernate 简介:
hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC作了轻量级的封装,而咱们java程序员可使用面向对象的思想来操纵数据库。
hibernate核心接口
session:负责被持久化对象CRUD操做
sessionFactory:负责初始化hibernate,建立session对象
configuration:负责配置并启动hibernate,建立SessionFactory
Transaction:负责事物相关的操做
Query和Criteria接口:负责执行各类数据库查询
hibernate工做原理:
1.经过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息
3.经过SessionFactory sf = config.buildSessionFactory();//建立SessionFactory
4.Session session = sf.openSession();//打开Sesssion
5.Transaction tx = session.beginTransaction();//建立并启动事务Transation
6.persistent operate操做数据,持久化操做
7.tx.commit();//提交事务
8.关闭Session
9.关闭SesstionFactoryhtml
hibernate对象的三种状态:java
1,Transient 瞬时 :对象刚new出来,还没设id,设了其余值。内存中临时存在,数据库没有对应记录,瞬时状态的对象容许直接使用程序员
2,Persistent 持久:调用了save()、saveOrUpdate(),就变成Persistent,有id。数据库中有对应记录,而且处于session缓存区中sql
3,Detached 脱管 : 当session close()完以后,变成Detached。数据库有对应的记录,脱离session缓存区中数据库
hibernate-取消关联外键引用数据丢失抛异常的设置@NotFound
@Cascade(CascadeType.ALL)级联,能够经过注解添加也能够经过属性添加在如@onetomeny
@OnetoMany(mappedBy = "comment")
默认状况下,双方都负责关联关的维护。
可是若是让一方负责关联关系的维护,多了一条update语句(也就是级联会访问另外一张表)
通常状况下,一方不负责关联关系的维护加mappedBy或xml中inverse =true缓存
为何要用hibernate:
1. 对JDBC访问数据库的代码作了封装,大大简化了数据访问层繁琐的重复性代码。
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工做
3. hibernate使用Java反射机制,而不是字节码加强程序来实现透明性。
4. hibernate的性能很是好,由于它是个轻量级框架。映射的灵活性很出色。它支持各类关系数据库,从一对一到多对多的各类复杂关系。session
Hibernate是如何延迟加载?get与load的区别架构
1. 对于Hibernate get方法,Hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,而后在二级缓存中查找,尚未就查询数据库,数据 库中没有就返回null。并发
2. Hibernate load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true),分状况讨论: app
(1)若为true,则首先在Session缓存中查找,看看该id对应的对象是否存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子类,由CGLIB动态生成)。等到具体使用该对象(除获取OID之外)的时候,再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
(2)若为false,就跟Hibernateget方法查找顺序同样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
这里get和load有两个重要区别:
若是未能发现符合条件的记录,Hibernate get方法返回null,而load方法会抛出一个ObjectNotFoundException。
load方法可返回没有加载实体数据的代 理类实例,而get方法永远返回有实体数据的对象。
总之对于get和load的根本区别,一句话,hibernate对于 load方法认为该数据在数据库中必定存在,能够放心的使用代理来延迟加载,若是在使用过程当中发现了问题,只能抛异常;而对于get方 法,hibernate必定要获取到真实的数据,不然返回null。
Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体如今表与表之间的关系进行操做,它们都是对对象进行操做,咱们程序中把全部的表与类都映射在一块儿,它们经过配置文件中的many-to-one、one-to-many、many-to-many、
说下Hibernate的缓存机制:
1、什么是注解?
解析:来源:Hibernate提供了Hibernate Annotations扩展包,它能够替换复杂的hbm.xml文件( Annotations扩展包是hibernate-annotation-3.4.0GA.zip)
做用:使得Hibernate程序的开发大大的简化。利用注解后,可不用定义持久化类对应的*.hbm.xml,而直接以注解方式写入持久化类的实现中。
2、注解配置持久化类经常使用注解。
注解 | 含义和做用 |
@Entity | 将 一个类声明为一个持久化类 |
@Id | 声明了持久化类的标识属性(至关于数据表的主键) |
@GeneratedValue | 定义标识属性值的生成策略 |
@Table | 为持久化类映射指定表(table)、目录(catalog)和schema的名称。默认值,持久化类名,不带包名 |
@UniqueConstraint | 定义表的惟一约束 |
@Lob | 表示属性将被持久化为Blob或者Clob类型 |
@Column | 将属性映射到列 |
@Transient | 忽略这些字段和属性,不用持久化到数据库 |
【hibernate】经常使用注解
转载:http://www.javashuo.com/article/p-dybuyffv-bz.html
目录
========================================================
一、@Entity 实体
二、@Table 表
三、@Id 和 @GeneratedValue 主键及生成策略
四、@Column 列
五、@DynamicInsert 和 @DynamicUpdate 动态字段
六、@Immutable 不变实体
七、@Basic 非空约束
八、@NotNull 非空检查
九、@Access 属性访问
十、@Formula 派生属性
十一、@ColumnTransformer 转换列值
十二、@Generated 默认值
1三、@Temporal 时序属性
1四、@CreationTimestamp和@UpdateTimestamp 建立时间戳和更新时间戳
1五、@Enumerated 枚举类型
1六、@Embeddable 可嵌入组件
1七、@Lob 大数据类型
1八、@Type 类型适配器
1九、@Convert 转换器
20、@MappedSuperclass 不持久化超类属性
2一、@AttributeOverrides 和 @AttributeOverride 重写属性
2二、@Inheritance 继承策略
========================================================
一、@Entity 实体
声明持久化实体,不带 name 参数时代表和实体名相同,带参数重写代表 @Entity(name="ycx_user")
二、@Table 表
重写表名 @Table(name="ycx_user")
三、@Id 和 @GeneratedValue 主键及生成策略
主键和主键生成策略 @GeneratedValue(generator="id_generator") 或者 @GeneratedValue(strategy=GenerationType.SEQUENCE)
四、@Column 列
name="列名"
table=“列属表名”
nullable=false 不能为空,生成非空约束
length=3 字段长度
insertable=false 不包含 INSERT
updatable=false 不包含 UPDATE
列声明 @Column(name="代表", nullable=false),nullable=false 声明数据库非空约束
五、@DynamicInsert 和 @DynamicUpdate 动态字段
动态 SQL 生成,@DynamicInsert 和 @DynamicUpdate,经过启用动态插入和更新,就能够告知 hibernate 在须要时生成 SQL 字符串
六、@Immutable 不变实体
让实体不可变,这样 hibernate 永远不会执行 update 语句,同时能够进行一些优化,好比对不可变类不进行脏检查。
七、@Basic 非空约束
@Basic(optional=false) 声明数据库非空约束
八、@NotNull 非空检查
@NotNull(message="消息内容"),实体非空注解,可是这个在生成数据库结构时会被忽略,在实体保存校验时起做用。
要想在数据库中生成非空约束,必须结合 @Column(nullable=false) 或者 @Basic(optional=false)
九、@Access 属性访问
重写默认的访问行为,字段访问或者属性访问,已经注解过的实体会从强制的 @Id 注解位置继承访问行为,@Id 在字段上则继承字段访问,在 getter 方法上则继承属性访问。
@Access(AccessType.FIELD) 字段访问
@Access(AccessType.PROPERTY) 属性访问
当 @Access 在实体级别设置则会影响实体的全部访问策略,一样 @Access 也能够重写单个属性的访问策略
若默认是字段访问,在字段上添加 @Access(AccessType.PROPERTY) 则被修改成属性访问
若默认是属性访问,在 getter 方法上添加 @Access(AccessType.FIELD) 则被修改成字段访问
十、@Formula 派生属性
运行时经过 @Formula 估算出来,不会出如今 UPDATE 和 INSERT 中,只会出如今 SELECT 中,能够包含 SQL 函数和子查询。
例如 数据库中没有全名而实体中有 @Formula("concat(firstname,'-',lastname)")
十一、@ColumnTransformer 转换列值
数据库中存储重量 weight 单位是克,实体中使用千克
@Column(name="weight") @org.hibernate.annotations.ColumnTransformer(read="weight / 1000",write="? * 1000") protected int kilogramWeight;
十二、@Generated 默认值
自动刷新数据库生成的值,如触发器在每次插入和更新后更新的值。使用 @Generated 注解在每次执行 INSERT 和 UPDATE 后委托给 Hibernate 自动查询。
好比插入用户后给一个默认国籍
触发器
BEGIN set new.nationality = 'CN'; END
java
@Column(insertable=false,updatable=false) @org.hibernate.annotations.ColumnDefault("'CN'") //在 Hibernate 导出 SQL 架构 DDL 时设置列的默认值 @org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.INSERT) protected String nationality;
测试
@Test public void testInsert() { this.session.beginTransaction(); User u = new User(); u.setUsername("admin"); u.setFirstname("Tom"); u.setLastname("Green"); u.setKilogramWeight(62); this.session.persist(u); this.session.getTransaction().commit(); //事务提交后才能获得最新的值 System.out.println(u.getId() + " Hibernate 自动刷新数据库触发器生成的值:" + u.getNationality()); assertTrue( true ); }
1三、@Temporal 时序属性
JPA 规范要求使用 @Temporal 注解时序属性,以声明所映射列的准确 SQL 数据库类型。当没有提供时 Hibernate 会默认使用 TemporalType.TIMESTAMP。
Java时序类型 java.util.Date;、java.util.Calendar;、java.sql.Date;、java.sql.Time;、java.sql.Timestamp;
TemporalType 选项 DATE、TIME、TIMESTAMP
1四、@CreationTimestamp和@UpdateTimestamp 建立时间戳和更新时间戳
当没有提供 @Temporal 时 Hibernate 会默认使用 TemporalType.TIMESTAMP
@Temporal(TemporalType.TIMESTAMP) @Column(updatable=false) @org.hibernate.annotations.CreationTimestamp protected Date createOn; @Temporal(TemporalType.TIMESTAMP) @Column(insertable=false) @org.hibernate.annotations.UpdateTimestamp protected Date updateOn;
当执行插入时 Hibernate 自动给 createOn 赋值,当执行更新时 Hibernate 自动给 updateOn 赋值。
1五、@Enumerated 枚举类型
默认 Hibernate 会存储 EnumType.ORDINAL 位置,这种很脆弱。EnumType.STRING 存储枚举值的标签,这样变动不会影响
@Enumerated(EnumType.STRING) private Sex sex;
1六、@Embeddable 可嵌入组件
@Embeddable public class Address { @NotNull @Column(nullable=false) protected String street; @NotNull @Column(nullable=false) protected String zipcode; @NotNull @Column(nullable=false) protected String city; public Address() {} public Address(String street,String zipcode,String city) { this.street = street; this.zipcode = zipcode; this.city = city; } @Override public String toString() { return "Address [street=" + street + ", zipcode=" + zipcode + ", city=" + city + "]"; } }
嵌入式组件
protected Address address;
重写嵌入式组件
@AttributeOverrides({ @AttributeOverride(name="street",column=@Column(name="billing_street")), @AttributeOverride(name="zipcode",column=@Column(name="billing_zipcode")), @AttributeOverride(name="city",column=@Column(name="billing_city")) }) protected Address billingAddress;
1七、@Lob
二进制数据和大数据
1八、@Type 类型适配器
@org.hibernate.annotations.Type(type="yes_no") protected boolean verify;
@org.hibernate.annotations.Type(type="true_false") protected boolean verify;
1九、@Convert 转换器
@Convert(converter = MoneyConverter.class,disableConversion=false) protected Money money;
20、@MappedSuperclass 不持久化超类属性
使用 @Entity 映射具体类,要想超类的属性被忽略而且不持久化,则必须使用 @MappedSuperclass
2一、@AttributeOverrides 和 @AttributeOverride 重写属性
子类重写从父类继承的字段和属性
类重写嵌入式字段和属性
2二、@Inheritance 继承策略
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 每一个带有联合的具体类使用一个表
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 每一个类层次结构使用一个表
@Inheritance(strategy=InheritanceType.JOINED)
=====================================================================================================
Hibernate经常使用查询方式
hibernate的查询方式常见的主要分为三种: HQL, QBC(命名查询), 以及使用原生SQL查询(SqlQuery)
1、HQL查询
• HQL(Hibernate Query Language)提供了丰富灵活的查询方式,使用HQL进行查询也是Hibernate官方推荐使用的查询方式。
• HQL在语法结构上和SQL语句十分的相同,因此能够很快的上手进行使用。使用HQL须要用到Hibernate中的Query对象,该对象专门执行HQL方式的操做。
查询全部示例
-
session.beginTransaction();
-
String hql = "from User"; // from 后跟的是要查询的对象,而不是表
-
Query query = session.createQuery(hql);
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
带where的查询示例
-
session.beginTransaction();
-
String hql = "from User where userName = 'James'";
-
Query query = session.createQuery(hql);
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
-
/*
-
在HQL中where语句中使用的是持久化对象的属性名,如上面示例中的userName。固然在HQL中也可使用别名
-
*/
-
String hql = "from User as u where u.userName = 'James'";
-
/*
-
过滤条件
-
在where语句中还可使用各类过滤条件,如:=、<>、<、>、>=、<=、between、not between、
-
in、not in、is、like、and、or等
-
*/
获取一个不完整的对象
-
session.beginTransaction();
-
String hql = "select userName from User";
-
Query query = session.createQuery(hql);
-
List<Object> nameList = query.list();
-
for(Object obj:nameList){
-
String name=(String)obj;
-
System.out.println(name);
-
}
-
session.getTransaction().commit();
-
// 多个属性的话,须要用object[]接收
-
session.beginTransaction();
-
String hql = "select userName,userPwd from User";
-
Query query = session.createQuery(hql);
-
List nameList = query.list();
-
for(Object obj:nameList){
-
Object[] array = (Object[]) obj; // 转成object[]
-
System.out.println( "name:" + array[0]);
-
System.out.println( "pwd:" + array[1]);
-
}
-
session.getTransaction().commit();
统计和分组查询
-
session.beginTransaction();
-
String hql = "select count(*),max(id) from User";
-
Query query = session.createQuery(hql);
-
List nameList = query.list();
-
for(Object obj:nameList){
-
Object[] array = (Object[]) obj;
-
System.out.println( "count:" + array[0]);
-
System.out.println( "max:" + array[1]);
-
}
-
session.getTransaction().commit();
-
/*
-
该条sql语句返回的是单条数据,因此还能够这样写
-
单列数据用Object,多列数据用Object[]
-
*/
-
Object[] object = (Object[]) query.uniqueResult();
-
System.out.println( "count:" + object[0]);
-
System.out.println( "max:" + object[1]);
更多写法
-
select distinct name from Student;
-
select max(age) from Student;
-
select count(age),age from Student group by age;
-
from Student order by age;
HQL占位符
-
session.beginTransaction();
-
String hql = "from User where userName = ?";
-
Query query = session.createQuery(hql);
-
// 索引从0开始
-
query.setString( 0, "James");
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
HQL引用占位符
-
-
session.beginTransaction();
-
String hql = "from User where userName = :name";
-
Query query = session.createQuery(hql);
-
query.setParameter( "name", "James");
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
HQL分页
-
session.beginTransaction();
-
String hql = "from User";
-
Query query = session.createQuery(hql);
-
query.setFirstResult( 0);
-
query.setMaxResults( 2);
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
2、QBC(Query By Criteria)查询
• Criteria对象提供了一种面向对象的方式查询数据库。Criteria对象须要使用Session对象来得到。
• 一个Criteria对象表示对一个持久化类的查询。
查询全部
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
List<User> userList = c.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
where
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
c.add(Restrictions.eq( "userName", "James"));
-
List<User> userList = c.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
Restrictions对象
-
方法名称 对应SQL中的表达式
-
----------------------------------------------------------
-
Restrictions.eq field = value
-
Restrictions.gt field > value
-
Restrictions.lt field < value
-
Restrictions.ge field >= value
-
Restrictions.le field <= value
-
Restrictions.between field between value1 and value2
-
Restrictions. in field in(…)
-
Restrictions.and and
-
Restrictions.or or
-
Restrictions.like field like value
-
示例
-
Criteria c = session.createCriteria(User.class);
-
c.add(Restrictions.like( "userName", "J"));
-
c.add(Restrictions.eq( "id", 120));
-
c.add(Restrictions.or(Restrictions.eq( "userName", "James"),
-
Restrictions.eq( "userName", "Alex")));
获取惟一记录
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
c.add(Restrictions.eq( "id", 120));
-
User user = (User) c.uniqueResult();
-
System.out.println(user.getUserName());
-
session.getTransaction().commit();
分页
-
Criteria c = session.createCriteria(User.class);
-
c.setFirstResult( 0);
-
c.setMaxResults( 5);
分组与统计
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
c.setProjection(Projections.sum( "id"));
-
Object obj = c.uniqueResult();
-
System.out.println(obj);
-
session.getTransaction().commit();
Projections对象
-
方法名称 描述
-
-------------------------------------------------------
-
Projections.sum 等于SQL中聚合函数sum
-
Projections.avg 等于SQL中聚合函数avg
-
Projections.count 等于SQL中聚合函数count
-
Projections .distinct 去除重复记录
-
Projections.max 等于SQL中聚合函数max
-
Projections.min 等于SQL中聚合函数min
-
Projections .groupProperty 对指定的属性进行分组查询
多个统计与分组
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
ProjectionList projectionList = Projections.projectionList();
-
projectionList.add(Projections.sum( "id"));
-
projectionList.add(Projections.min( "id"));
-
c.setProjection(projectionList);
-
// 和HQL同样,单列用Object,多列用Object[]
-
Object[] obj = (Object[]) c.uniqueResult();
-
System.out.println( "sum:" + obj[0]);
-
System.out.println( "min:" + obj[1]);
排序
-
Criteria c = session.createCriteria(User.class);
-
c.addOrder(Order.desc( "id"));
3、原生SQL查询:
示例
-
session.beginTransaction();
-
String sql = "select id,username,userpwd from t_user";
-
List list = session.createSQLQuery(sql).list();
-
for(Object item : list){
-
Object[] rows = (Object[]) item;
-
System.out.println( "id:" + rows[0] + "username:"
-
+ rows[ 1] + "userpwd:" + rows[2]);
-
}
-
session.getTransaction().commit();
addEntity()示例
-
session.beginTransaction();
-
String sql = "select id,username,userpwd from t_user";
-
// addEntity()能够告诉Hibernate你想要封装成对象的类型,而后自动为你封装
-
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
-
List<User> list = query.list();
-
for(User user : list){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
uniqueResult示例
-
session.beginTransaction();
-
String sql = "select id,username,userpwd from t_user where id = 2";
-
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
-
User user = (User) query.uniqueResult();
-
System.out.println(user.getUserName());
-
session.getTransaction().commit();
转载地址:https://blog.csdn.net/u010963948/article/details/16818043