- 浏览: 203123 次
- 性别:
- 来自: 湖南
文章分类
最新评论
@Entity
@Table
@Id
@Column
@Transient //透明,不加入影射
@Temporal(TemporalType.DATE) //时间刻度、针度
@Enumerated(EnumType.STRING) //枚举类型
ID生成策略
@Id
@TableGenerator(name = "tab_pk", table = "PKS_TABLE", pkColumnName = "G_KEY", pkColumnValue = "EXAM_ONLINETEST_PK", valueColumnName = "G_VALUE", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "tab_pk")
@OrderBy("id")
strategy = GenerationType.TABLE //策略
AUTO mysql IDENTITY sql server orcel SEQUENCE
在实体前加入策略
@SequenceGenerator(name="gzmetro",sequenceName="gzmetro_db")
方法前
@GenericGenerator(strategy=GenerationType.SEQUENCE,generator="gzmetro")
联合主键(三种方法)
1、主键类 @Embeddable //注解嵌入类
主键类属性方法 @Id
2、主键类属性方法 @EmbeddedId //声明成联合组件
3、在多个属性方法 @Id @IdClass(value=Test.Class)
hibernate 三种状态
Transient 瞬时 对象创建 对象不会被持久化到数据库中,也不会被赋予持久化标识
Persistent 持久 内存、数据库存在 在数据库中有对应的记录,并拥有一个持久化标识
Detached 脱管 缓存 与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的
Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession(); //上下文找,如果没有,自动创建
getCurrentSession的话会自动关闭,而openSession需要你手动关闭
Student t= new Struden();
t.setId(1);
session.delete(t); //必须有Id
load 返回代理对象,调用时加载
get 直接发送sql查询,加载数据,不会延迟
update 更新Transient时会报错,但自己设定数据存在对应对象Id不会报错
merge(s) 首先load查询后,update可以是缓存对象
saveOrUpdate
clear() 清除缓存(hibernate首先查询缓存)
flush() 强制缓存与数据库同步
evict() 从一级缓存中去掉这些对象及其集合
SchemaExport 输出sql语句
new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);
关系映射
一对一
单向(外键关联)
@OneToOne
@JoinColumn(name="QUESTIONPOOL_ID") //指定生成外键ID
单向(外键关联xml)
<money-to-one name="Student" column="student_id" unique="true" />
双向(外键关联)
@OneToOne
@JoinColumn(name="QUESTIONPOOL_ID") //指定生成外键ID
@OneToOne(mappedBy="questionpool") //对方关联属性
双向(外键关联xml)
<money-to-one name="Student" column="student_id" unique="true" />
<one-to-one name="person" property-ref="student"/>
单向(主键关联)
@OneToOne
@PrimaryKeyJoinColumn
单向(主键关联xml)
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/>
双向(主键关联)
@OneToOne
@PrimaryKeyJoinColumn
@OneToOne
@PrimaryKeyJoinColumn
双向(主键关联xml)
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<one-to-one name="address"/>
</class>
<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person"
constrained="true"/>
</class>
联合主键
@OneToOne
@JoinColumns(
{
@JoinColumn(name="wifeId", referencedColumnName="id"),
@JoinColumn(name="wifeName", referencedColumnName="name")
}
)
组件映射
一个类是另外一个类组成部分,产生一张表
@Embeddable //注解嵌入类
采用xml
<component name="Name" class="eg.Name">
<property name="initial"/>
</component>
属性重写
@Embeddable
@AttributeOverrides({
@AttributeOverride(name="name",column=@Column(name="bornCountryName"))
}
)
采用xml
<component name="Name" class="eg.Name" unique="true">
<parent name="namedPerson"/> <!-- reference back to the Person -->
<property name="initial"/>
</component>
一对多
单向(一对多关联)
@OneToMany
@JoinColumn(name="Group_ID") //必须有,否则会产生中间表,当作many-to-many
xml文件配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses">
<key column="personId"
not-null="true"/>
<one-to-many class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
多对一
单向(多对一关联)多的一方加外键
@ManyToOne
//@JoinColumn(name="Group_ID")
private Group getGroup(){return group;}
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
一对多,多对一双向关联
@OneToMany(mappedBy="group")
@JoinColumn(name="Group_ID")
@ManyToOne
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true">
<key column="addressId"/>
<one-to-many class="Person"/>
</set>
</class>
多对多
单向多对多
@ManyToMany
@JoinTable(name="center_tbales",joinColumns={
@JoinColumn(name="Teacher_id")
},inverseJoinColumns={@JoinColumn(name="Student_id")})
//@JoinTable(name = "base_security_user_role", joinColumns = { @JoinColumn(name = "roleid") }, inverseJoinColumns = { @JoinColumn(name = "userid") })
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
双向多对多
@ManyToMany
@JoinTable(name="center_tbales",joinColumns={
@JoinColumn(name="Teacher_id")
},inverseJoinColumns={@JoinColumn(name="Student_id")})
@ManyToMany(mappedBy="Student_id")
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true" table="PersonAddress">
<key column="addressId"/>
<many-to-many column="personId"
class="Person"/>
</set>
</class>
CRUD
存在关联,只save一个对象,需要做如下操作 cascade管CUD
双向多对一 @ManyToOne(cascade ={CascadeType.ALL}) //增删改查,级联关联对象
双向一对多 @OneToMany(mappedBy="group",cascade ={CascadeType.ALL}) //一这方要设置双向关联
User u = new User();
u.setName("aaa");
Group g = new Goup();
g.setName("bbb");
g.getUsers().add(u);
u.setGroup(g);
seesion.save(g);
optional 属性用于定义关联关系的从类对象是否必须存在。如果设置为 false,那么该属性就不能设置为 null.默认值是 true
存在关联,get()、load()一个对象时 fetch管R
@ManyToOne 默认会把一方取出(fetch=FetchType.EAGER)
@OneToMany 默认不会把多的一方取出(fetch=FetchType.LAZY)
@OneToMany(mappedBy="group",cascade ={CascadeType.ALL},fetch=FetchType.EAGER) //把多一方取出
如果将fetch=FetchType.LAZY,对象调用时加载,如果sesion关闭时,就会报赖加载异常。
xml配制 (inverse="true")
更新cascade = { CascadeType.PERSIST, CascadeType.MERGE }//新增、修改
jap 标准新增、修改方法 persist merge
级联关系 delete(u) 全部会删除双向关联数据(u,g)内全部数据
解决办法
1、打破关联 u.setGroup(null);
2、createQuery 方法
集合映射
List 与set一样,@OneToMany 如果想对数据排序可以用@OrderBy("name ASC")
Map
@OneToMany(mappedBy="group",cascade ={CascadeType.ALL})
@MapKey(name="id")
继承映射
生成一张表
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discrininator",discriminatorType=DiscriminatorType.STRING) //区分相同的属性
@DiscriminatorValue("person") //区分父类类型
@DiscriminatorValue("student") //区分子类
@DiscriminatorValue("teacher")//区分子类
子类包含所有父类全部属性
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@TableGenerator(name = "tab_pk", table = "PKS_TABLE", pkColumnName = "G_KEY", pkColumnValue = "EXAM_ONLINETEST_PK", valueColumnName = "G_VALUE", allocationSize = 1)
@Entity //子类只要设置Entity
子类是扩展,父类没有,独有的
@Inheritance(strategy=InheritanceType.JOINED)
@Entity //子类只要设置Entity
HQL>EJBQL(jpal 1.0)>QBC(Qeary by criteria)>QBE(QUERY BY Eample)
当前主用habernate 编程接口
select distinct c from Catecy c //查找主主键不同对象
from Catecy c where c.id>:min and c.id<:max //q.setParame("min"2).setParame("max",8)
分页
q.setMaxResults(4).setFirstResult(2);
查询部分数据
Query q = session.createQuery("select c.id, c.name from Category c order by c.name desc");
List<Object[]> categories = (List<Object[]>)q.list();
for(Object[] o : categories) {
System.out.println(o[0] + "-" + o[1]);
}
关联查询
from Topic t where t.category.id = 1
关联导航
from Msg m where m.topic.category.id = 1
视图(VO Value Object/DTO data transfer object)
select new com.bjsxt.hibernate.MsgInfo(m.id, m.cont, m.topic.title, m.topic.category.name) from Msg
join //因为有可能存在多个成员变量(同一个类),需要指明用哪一个成员变量的连接条件来做连接
select t.title, c.name from Topic t join t.category c //t.category 而不是Category c
uniqueResult
Query q = session.createQuery("from Msg m where m = :MsgToSearch "); //不重要
Msg m = new Msg();
m.setId(1);
q.setParameter("MsgToSearch", m);
Msg mResult = (Msg)q.uniqueResult();
单行函数
count、max、 min、avg、sum
between ? and ?、in、is not null
is empty and is not empty
from Topic t where t.msgs is empty //集合是否为空
like (% 0个或多个,_一个)
from Topic t where t.title like '%5'
多行函数
lower、upper、trim、oncat、length、abs、sqrt、mod
数据库系统关键词
select current_date, current_time, current_timestamp, t.id from Topic t
日期比较
Query q = session.createQuery("from Topic t where t.createDate < :date");
q.setParameter("date", new Date());
分组
select t.title, count(*) from Topic t group by t.title
select t.title, count(*) from Topic t group by t.title having count(*) >= 1
子查询
from Topic t where t.id < (select avg(t.id) from Topic t)
from Topic t where t.id < ALL (select t.id from Topic t where mod(t.id, 2)= 0) //结果所有值==min(t.id)
用in 可以实现exists的功能
但是exists执行效率高
from Topic t where not exists (select m.id from Msg m where m.topic.id=t.id)
//update and delete
//规范并没有说明是不是要更新persistent object,所以如果要使用,建议在单独的trasaction中执行
update Topic t set t.title = upper(t.title)
命名查询
在实体添加HQL语句
@NamedQueries(
{
@NamedQuery(name="topic.selectCertainTopic", query="from Topic t where t.id = :id")
}
)
Query q = session.getNamedQuery("topic.selectCertainTopic");
q.setParameter("id", 5);
Topic t = (Topic)q.uniqueResult();
Native(了解)//数据库本身的SQL语句
SQLQuery q = session.createSQLQuery("select * from category limit 2,4").addEntity(Category.class);
@NamedNativeQueries(
{
@NamedNativeQuery(name="topic.select2_5Topic", query="select * from topic limit 2, 5")
}
)
//hibernate尚未实现JPA命名的NativeSQL
orcle 存储过程(PROCEDURE)
CallableStatement cs = session
.connection()
.prepareCall("{call modifyapppnumber_remain(?)}");
cs.setString(1, foundationid);
cs.execute();
QBC //标准、约束 Criteria 面向对象
Criteria c = session.createCriteria(Topic.class) //from Topic
.add(Restrictions.gt("id", 2)) //greater than = id > 2
.add(Restrictions.lt("id",) //little than = id < 8
.add(Restrictions.like("title", "t_"))
.createCriteria("category") //创建连接 join
.add(Restrictions.between("id", 3, 5)) //category.id >= 3 and category.id <=5
//DetachedCriterea 更灵活,脱离session管理,需要查询就绑定session
QBE(QBC一部分,子集query by Eample)
//is empty and is not empty
//query by criteria query by example
Topic tExample = new Topic();
tExample.setTitle("T_"); //榜样对象
Example e = Example.create(tExample)
.ignoreCase().enableLike();
Criteria c = session.createCriteria(Topic.class)
.add(Restrictions.gt("id", 2))
.add(Restrictions.lt("id",)
.add(e)
;
for(Object o : c.list()) {
Topic t = (Topic)o;
System.out.println(t.getId() + "-" + t.getTitle());
}
性能优化
clear()应用,分页或遍历查询
内存泄露 //部分资源没有回收,实际应用内存泄漏
1+N
不调用关联、解决产生多条sql语句
1、fetch=FetchType.LAZY
2、List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
3、@BatchSize(size=10) //关联实体上
4、List<Topic> topics = (List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list()
Query的遍历方式
1、query.list();2、query.iterate()
区别 1、iterate()首页取id,调用时才取相关属性 2、执行相同两次遍历,iterate从缓存中查找,产生一条sql,list每次调用查询一次
缓存
在内存分配一部分空间,服务本应该硬盘读取改变直接从内存中读取
一级缓存(session级别)
二级缓存(总缓存,SessionFactory所有缓存共有)
打开二级缓存(SessionFactory)
hibernate配制
hibernate.cfg.xml
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
添加ehcache.xml
//默认的缓存策略.
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //hibernate 如果查询条件一样,先从缓存中查询
load、iterate使用二级缓存,list 刷新二级缓存,往二级缓存存入数据,查询不使用二级缓存
三级缓存(查询缓存)
//list使用setCacheable(true)使用二级缓存
List<Category> categories = (List<Category>)session.createQuery("from Category").setCacheable(true).list();
缓存算法
LRU、LFU、FIFO
1、least Recently Used (最近不常用)
2、Least Frequenty Used(命中率高低)
3、First in First out (先进先出)
在ehcache.xml文件添加 memoryStoreEvictionPolicy="LRU" (defaultCache)
事务并发处理 (事务ACID)
原子性、一致性、独立性、持久性
1、丢失更新(lost update) 插销事务丢失
2、脏读(dirtyread) 读取另外事务没有提交的数据
3、不可重复读(non-repeatable read) 同一个事务读取两次,每一个值不一样
第二类丢失更新(second lost update problem)不可重复读的特殊情况
4、幻读(phantorn read) 读取时,更外一个事务向数据库里插入新数据
数据库的事务隔离机制
1、TRANSACTION_NONE //read-uncommitted
2、TRANSACTION_READ_COMMITTED 避免脏读,只读取提交数据 //read-committed
4、TRANSACTION_REPEATABLE_READ
8、TRANSACTION_SERIALIZABLE 解决一切问题,两个事务读取结果不一样 //排队
hibernate.connection.isolation=2
用悲观锁解决repeatable read的(依赖数据库)使用数据里锁
Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE);
LockMode.UPGRADE_NOWAIT //orcle 数据独有锁
乐观锁,在程序内添加锁,效率高 使用版本锁
在实体内添加版本控制属性(每次更新增加)
@Version
private int version;
@Table
@Id
@Column
@Transient //透明,不加入影射
@Temporal(TemporalType.DATE) //时间刻度、针度
@Enumerated(EnumType.STRING) //枚举类型
ID生成策略
@Id
@TableGenerator(name = "tab_pk", table = "PKS_TABLE", pkColumnName = "G_KEY", pkColumnValue = "EXAM_ONLINETEST_PK", valueColumnName = "G_VALUE", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "tab_pk")
@OrderBy("id")
strategy = GenerationType.TABLE //策略
AUTO mysql IDENTITY sql server orcel SEQUENCE
在实体前加入策略
@SequenceGenerator(name="gzmetro",sequenceName="gzmetro_db")
方法前
@GenericGenerator(strategy=GenerationType.SEQUENCE,generator="gzmetro")
联合主键(三种方法)
1、主键类 @Embeddable //注解嵌入类
主键类属性方法 @Id
2、主键类属性方法 @EmbeddedId //声明成联合组件
3、在多个属性方法 @Id @IdClass(value=Test.Class)
hibernate 三种状态
Transient 瞬时 对象创建 对象不会被持久化到数据库中,也不会被赋予持久化标识
Persistent 持久 内存、数据库存在 在数据库中有对应的记录,并拥有一个持久化标识
Detached 脱管 缓存 与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的
Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession(); //上下文找,如果没有,自动创建
getCurrentSession的话会自动关闭,而openSession需要你手动关闭
Student t= new Struden();
t.setId(1);
session.delete(t); //必须有Id
load 返回代理对象,调用时加载
get 直接发送sql查询,加载数据,不会延迟
update 更新Transient时会报错,但自己设定数据存在对应对象Id不会报错
merge(s) 首先load查询后,update可以是缓存对象
saveOrUpdate
clear() 清除缓存(hibernate首先查询缓存)
flush() 强制缓存与数据库同步
evict() 从一级缓存中去掉这些对象及其集合
SchemaExport 输出sql语句
new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);
关系映射
一对一
单向(外键关联)
@OneToOne
@JoinColumn(name="QUESTIONPOOL_ID") //指定生成外键ID
单向(外键关联xml)
<money-to-one name="Student" column="student_id" unique="true" />
双向(外键关联)
@OneToOne
@JoinColumn(name="QUESTIONPOOL_ID") //指定生成外键ID
@OneToOne(mappedBy="questionpool") //对方关联属性
双向(外键关联xml)
<money-to-one name="Student" column="student_id" unique="true" />
<one-to-one name="person" property-ref="student"/>
单向(主键关联)
@OneToOne
@PrimaryKeyJoinColumn
单向(主键关联xml)
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/>
双向(主键关联)
@OneToOne
@PrimaryKeyJoinColumn
@OneToOne
@PrimaryKeyJoinColumn
双向(主键关联xml)
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<one-to-one name="address"/>
</class>
<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person"
constrained="true"/>
</class>
联合主键
@OneToOne
@JoinColumns(
{
@JoinColumn(name="wifeId", referencedColumnName="id"),
@JoinColumn(name="wifeName", referencedColumnName="name")
}
)
组件映射
一个类是另外一个类组成部分,产生一张表
@Embeddable //注解嵌入类
采用xml
<component name="Name" class="eg.Name">
<property name="initial"/>
</component>
属性重写
@Embeddable
@AttributeOverrides({
@AttributeOverride(name="name",column=@Column(name="bornCountryName"))
}
)
采用xml
<component name="Name" class="eg.Name" unique="true">
<parent name="namedPerson"/> <!-- reference back to the Person -->
<property name="initial"/>
</component>
一对多
单向(一对多关联)
@OneToMany
@JoinColumn(name="Group_ID") //必须有,否则会产生中间表,当作many-to-many
xml文件配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses">
<key column="personId"
not-null="true"/>
<one-to-many class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
多对一
单向(多对一关联)多的一方加外键
@ManyToOne
//@JoinColumn(name="Group_ID")
private Group getGroup(){return group;}
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
一对多,多对一双向关联
@OneToMany(mappedBy="group")
@JoinColumn(name="Group_ID")
@ManyToOne
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true">
<key column="addressId"/>
<one-to-many class="Person"/>
</set>
</class>
多对多
单向多对多
@ManyToMany
@JoinTable(name="center_tbales",joinColumns={
@JoinColumn(name="Teacher_id")
},inverseJoinColumns={@JoinColumn(name="Student_id")})
//@JoinTable(name = "base_security_user_role", joinColumns = { @JoinColumn(name = "roleid") }, inverseJoinColumns = { @JoinColumn(name = "userid") })
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
双向多对多
@ManyToMany
@JoinTable(name="center_tbales",joinColumns={
@JoinColumn(name="Teacher_id")
},inverseJoinColumns={@JoinColumn(name="Student_id")})
@ManyToMany(mappedBy="Student_id")
xml配制
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true" table="PersonAddress">
<key column="addressId"/>
<many-to-many column="personId"
class="Person"/>
</set>
</class>
CRUD
存在关联,只save一个对象,需要做如下操作 cascade管CUD
双向多对一 @ManyToOne(cascade ={CascadeType.ALL}) //增删改查,级联关联对象
双向一对多 @OneToMany(mappedBy="group",cascade ={CascadeType.ALL}) //一这方要设置双向关联
User u = new User();
u.setName("aaa");
Group g = new Goup();
g.setName("bbb");
g.getUsers().add(u);
u.setGroup(g);
seesion.save(g);
optional 属性用于定义关联关系的从类对象是否必须存在。如果设置为 false,那么该属性就不能设置为 null.默认值是 true
存在关联,get()、load()一个对象时 fetch管R
@ManyToOne 默认会把一方取出(fetch=FetchType.EAGER)
@OneToMany 默认不会把多的一方取出(fetch=FetchType.LAZY)
@OneToMany(mappedBy="group",cascade ={CascadeType.ALL},fetch=FetchType.EAGER) //把多一方取出
如果将fetch=FetchType.LAZY,对象调用时加载,如果sesion关闭时,就会报赖加载异常。
xml配制 (inverse="true")
更新cascade = { CascadeType.PERSIST, CascadeType.MERGE }//新增、修改
jap 标准新增、修改方法 persist merge
级联关系 delete(u) 全部会删除双向关联数据(u,g)内全部数据
解决办法
1、打破关联 u.setGroup(null);
2、createQuery 方法
集合映射
List 与set一样,@OneToMany 如果想对数据排序可以用@OrderBy("name ASC")
Map
@OneToMany(mappedBy="group",cascade ={CascadeType.ALL})
@MapKey(name="id")
继承映射
生成一张表
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discrininator",discriminatorType=DiscriminatorType.STRING) //区分相同的属性
@DiscriminatorValue("person") //区分父类类型
@DiscriminatorValue("student") //区分子类
@DiscriminatorValue("teacher")//区分子类
子类包含所有父类全部属性
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@TableGenerator(name = "tab_pk", table = "PKS_TABLE", pkColumnName = "G_KEY", pkColumnValue = "EXAM_ONLINETEST_PK", valueColumnName = "G_VALUE", allocationSize = 1)
@Entity //子类只要设置Entity
子类是扩展,父类没有,独有的
@Inheritance(strategy=InheritanceType.JOINED)
@Entity //子类只要设置Entity
HQL>EJBQL(jpal 1.0)>QBC(Qeary by criteria)>QBE(QUERY BY Eample)
当前主用habernate 编程接口
select distinct c from Catecy c //查找主主键不同对象
from Catecy c where c.id>:min and c.id<:max //q.setParame("min"2).setParame("max",8)
分页
q.setMaxResults(4).setFirstResult(2);
查询部分数据
Query q = session.createQuery("select c.id, c.name from Category c order by c.name desc");
List<Object[]> categories = (List<Object[]>)q.list();
for(Object[] o : categories) {
System.out.println(o[0] + "-" + o[1]);
}
关联查询
from Topic t where t.category.id = 1
关联导航
from Msg m where m.topic.category.id = 1
视图(VO Value Object/DTO data transfer object)
select new com.bjsxt.hibernate.MsgInfo(m.id, m.cont, m.topic.title, m.topic.category.name) from Msg
join //因为有可能存在多个成员变量(同一个类),需要指明用哪一个成员变量的连接条件来做连接
select t.title, c.name from Topic t join t.category c //t.category 而不是Category c
uniqueResult
Query q = session.createQuery("from Msg m where m = :MsgToSearch "); //不重要
Msg m = new Msg();
m.setId(1);
q.setParameter("MsgToSearch", m);
Msg mResult = (Msg)q.uniqueResult();
单行函数
count、max、 min、avg、sum
between ? and ?、in、is not null
is empty and is not empty
from Topic t where t.msgs is empty //集合是否为空
like (% 0个或多个,_一个)
from Topic t where t.title like '%5'
多行函数
lower、upper、trim、oncat、length、abs、sqrt、mod
数据库系统关键词
select current_date, current_time, current_timestamp, t.id from Topic t
日期比较
Query q = session.createQuery("from Topic t where t.createDate < :date");
q.setParameter("date", new Date());
分组
select t.title, count(*) from Topic t group by t.title
select t.title, count(*) from Topic t group by t.title having count(*) >= 1
子查询
from Topic t where t.id < (select avg(t.id) from Topic t)
from Topic t where t.id < ALL (select t.id from Topic t where mod(t.id, 2)= 0) //结果所有值==min(t.id)
用in 可以实现exists的功能
但是exists执行效率高
from Topic t where not exists (select m.id from Msg m where m.topic.id=t.id)
//update and delete
//规范并没有说明是不是要更新persistent object,所以如果要使用,建议在单独的trasaction中执行
update Topic t set t.title = upper(t.title)
命名查询
在实体添加HQL语句
@NamedQueries(
{
@NamedQuery(name="topic.selectCertainTopic", query="from Topic t where t.id = :id")
}
)
Query q = session.getNamedQuery("topic.selectCertainTopic");
q.setParameter("id", 5);
Topic t = (Topic)q.uniqueResult();
Native(了解)//数据库本身的SQL语句
SQLQuery q = session.createSQLQuery("select * from category limit 2,4").addEntity(Category.class);
@NamedNativeQueries(
{
@NamedNativeQuery(name="topic.select2_5Topic", query="select * from topic limit 2, 5")
}
)
//hibernate尚未实现JPA命名的NativeSQL
orcle 存储过程(PROCEDURE)
CallableStatement cs = session
.connection()
.prepareCall("{call modifyapppnumber_remain(?)}");
cs.setString(1, foundationid);
cs.execute();
QBC //标准、约束 Criteria 面向对象
Criteria c = session.createCriteria(Topic.class) //from Topic
.add(Restrictions.gt("id", 2)) //greater than = id > 2
.add(Restrictions.lt("id",) //little than = id < 8
.add(Restrictions.like("title", "t_"))
.createCriteria("category") //创建连接 join
.add(Restrictions.between("id", 3, 5)) //category.id >= 3 and category.id <=5
//DetachedCriterea 更灵活,脱离session管理,需要查询就绑定session
QBE(QBC一部分,子集query by Eample)
//is empty and is not empty
//query by criteria query by example
Topic tExample = new Topic();
tExample.setTitle("T_"); //榜样对象
Example e = Example.create(tExample)
.ignoreCase().enableLike();
Criteria c = session.createCriteria(Topic.class)
.add(Restrictions.gt("id", 2))
.add(Restrictions.lt("id",)
.add(e)
;
for(Object o : c.list()) {
Topic t = (Topic)o;
System.out.println(t.getId() + "-" + t.getTitle());
}
性能优化
clear()应用,分页或遍历查询
内存泄露 //部分资源没有回收,实际应用内存泄漏
1+N
不调用关联、解决产生多条sql语句
1、fetch=FetchType.LAZY
2、List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
3、@BatchSize(size=10) //关联实体上
4、List<Topic> topics = (List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list()
Query的遍历方式
1、query.list();2、query.iterate()
区别 1、iterate()首页取id,调用时才取相关属性 2、执行相同两次遍历,iterate从缓存中查找,产生一条sql,list每次调用查询一次
缓存
在内存分配一部分空间,服务本应该硬盘读取改变直接从内存中读取
一级缓存(session级别)
二级缓存(总缓存,SessionFactory所有缓存共有)
打开二级缓存(SessionFactory)
hibernate配制
hibernate.cfg.xml
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
添加ehcache.xml
//默认的缓存策略.
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //hibernate 如果查询条件一样,先从缓存中查询
load、iterate使用二级缓存,list 刷新二级缓存,往二级缓存存入数据,查询不使用二级缓存
三级缓存(查询缓存)
//list使用setCacheable(true)使用二级缓存
List<Category> categories = (List<Category>)session.createQuery("from Category").setCacheable(true).list();
缓存算法
LRU、LFU、FIFO
1、least Recently Used (最近不常用)
2、Least Frequenty Used(命中率高低)
3、First in First out (先进先出)
在ehcache.xml文件添加 memoryStoreEvictionPolicy="LRU" (defaultCache)
事务并发处理 (事务ACID)
原子性、一致性、独立性、持久性
1、丢失更新(lost update) 插销事务丢失
2、脏读(dirtyread) 读取另外事务没有提交的数据
3、不可重复读(non-repeatable read) 同一个事务读取两次,每一个值不一样
第二类丢失更新(second lost update problem)不可重复读的特殊情况
4、幻读(phantorn read) 读取时,更外一个事务向数据库里插入新数据
数据库的事务隔离机制
1、TRANSACTION_NONE //read-uncommitted
2、TRANSACTION_READ_COMMITTED 避免脏读,只读取提交数据 //read-committed
4、TRANSACTION_REPEATABLE_READ
8、TRANSACTION_SERIALIZABLE 解决一切问题,两个事务读取结果不一样 //排队
hibernate.connection.isolation=2
用悲观锁解决repeatable read的(依赖数据库)使用数据里锁
Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE);
LockMode.UPGRADE_NOWAIT //orcle 数据独有锁
乐观锁,在程序内添加锁,效率高 使用版本锁
在实体内添加版本控制属性(每次更新增加)
@Version
private int version;
- 000_尚学堂马士兵_Java视频教程_Hibernate3.3.2_项目源码.rar (510.6 KB)
- 下载次数: 6
- readtext.rar (6.1 KB)
- 下载次数: 2
发表评论
-
领导首页页面
2012-11-30 19:57 0<%@ page language="ja ... -
服务器证书安装配置指南(Weblogic)
2012-04-24 12:20 1116一、 生成证书请求 1. 安装JDK(可选) We ... -
jsp 导出excel
2011-09-21 21:41 1486excel文件是可以在jsp响应,通过输出相应xml,即可得到 ... -
eclipse相关插件安装
2011-06-15 20:02 10581.tomcatPluginV321.zip tomcat部 ... -
流程控制应用JPBM
2011-06-04 14:48 1607工作流(流程控制应用) 什么是工作流? 工作流是业务流程自动化 ... -
网上支付
2011-03-28 12:57 3156两种接入方案 相接与银 ... -
Hibernate Annotation
2011-03-01 08:54 1131简介: 在过去几年里,Hibernate不断发展,几乎成为Ja ... -
在Struts 2中实现文件上传
2011-02-11 16:09 853Struts 2是通过Commons FileUpload文件 ... -
Java加密技术
2010-12-31 11:51 757本篇内容简要介绍几种方法源码文件 如基本的单向加密 ... -
电子邮件开发应用
2010-12-20 12:48 9671.电子邮件发送 /* * html 电子邮件发送 ... -
Struts 2与AJAX
2010-12-18 08:29 653在当今——Web 2.0概念铺天盖地的Internet环境下, ... -
Strus 2的新表单标志的使用
2010-12-17 09:10 787Struts 2为大家提供了不少常用的很酷的表单标志,简化了我 ... -
Struts 2中的OGNL
2010-12-16 08:28 638本人是一个EL(Expression ... -
在Struts 2中实现CRUD
2010-12-15 08:08 758CRUD是Create(创建)、Read(读取)、Update ... -
在Struts 2中实现文件上传
2010-12-14 08:34 841实现原理 Struts 2是通过Commons FileUpl ... -
在Struts 2中实现IoC
2010-12-13 07:58 843IoC(Inversion of Control,以下译为控制 ... -
Struts 2的基石——拦截器(Interceptor)
2010-12-11 08:23 810首先,要跟大家道个歉 ... -
在Struts 2.0中实现表单数据校验(Validation)
2010-12-10 09:45 784在写前几篇文章的时候,有些朋友建议我的写一篇关于表单数据校验的 ... -
转换器(Converter)——Struts 2.0中的魔术师
2010-12-09 08:20 673在我已往的Struts 1.x项目经验中,有个问题不时的出现— ... -
在Struts 2.0中国际化(i18n)您的应用程序
2010-12-08 08:14 738国际化是商业系统中不可或缺的一部分,所以无论您学习的是什么We ...
相关推荐
接下来,我们将逐步创建一个简单的Hibernate Annotation应用。首先,定义一个实体类,比如`User`: ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType...
以上仅是Hibernate Annotation部分核心概念的简述,实际使用中还需要根据项目需求和最佳实践来灵活应用。深入理解和熟练掌握这些注解,能极大地提升开发效率并优化数据库操作。阅读《Hibernate Annotation 中文文档...
随着Java社区对注解的广泛接受,Hibernate Annotation已经成为现代Java应用开发的标准实践,逐渐取代了传统的XML映射方式。 以上是对Hibernate Annotation的简要介绍,深入理解和熟练应用这些注解,将有助于提升你...
《Hibernate Annotation 学习笔记》 在Java的持久化框架中,Hibernate以其强大的功能和易用性成为开发者首选之一。而Hibernate Annotation则是Hibernate提供的一种基于注解的实体映射方式,它极大地简化了传统XML...
Spring 和 Hibernate 是两个非常重要的 Java 开发框架,它们在企业级应用开发中广泛使用。本文将深入探讨如何结合 Spring 的注解配置与 Hibernate 实现数据持久化,通过一个实际的 demo 示例来阐述整个过程。 首先...
总结,Hibernate Annotation API是Hibernate ORM的重要组成部分,它极大地简化了Java应用的数据库交互。通过合理运用注解,开发者能够高效地管理数据层,实现面向对象编程和关系型数据库之间的无缝对接。在实际开发...
【标题】:深入理解Hibernate Annotation及其使用 【描述】:本文将全面介绍Hibernate Annotation的使用,包括事务管理和声明式事务处理,以及如何通过注解简化数据库持久化操作。 【标签】:Hibernate, ...
通过阅读《Hibernate_annotation_1to1_foreignKey》文档或博客,你可以更详细地了解如何配置和使用这种关联,包括示例代码、注意事项以及可能遇到的问题和解决方案。理解并熟练运用这些知识,能帮助你在使用...
在传统的Hibernate应用中,我们通常使用XML文件来描述对象和表之间的映射关系。然而,随着Java 5的发布,注解成为了一种更简洁、更直观的元数据表示方式。Hibernate注解就是利用这种方式,将对象的映射信息直接写在...
【标题】:“Hibernate Annotation JAR” 【描述】:“Hibernate 3.3 Annotation JAR”指的是Hibernate框架的一个特定版本,即3.3版本中用于对象关系映射(ORM)的注解库。Hibernate是一个广泛使用的Java库,它允许...
Annotation注解可以直接应用在类和类的属性上,减少了额外的配置文件需求,提升了开发效率。 1. **实体类注解@Entity** `@Entity` 注解标记一个Java类为Hibernate管理的实体类,表示这个类将映射到数据库的一个表...
### Hibernate Annotation概述与实践 #### 一、Hibernate Annotation简介 Hibernate作为Java领域内最流行的ORM框架之一,在过去的几年中经历了显著的发展,已经成为Java数据库持久化的事实标准。它不仅功能强大,...
在"hibernate_annotation"这个部分,我们关注的是Hibernate的注解配置方式,这种方式比传统的XML配置更加简洁直观。Hibernate注解提供了如@Entity、@Table、@Id、@GeneratedValue等,它们分别用于定义实体类、指定...
《Hibernate Annotation 3.4.0:Java持久化框架的核心技术解析》 Hibernate Annotation是...通过实际项目中的应用和实践,我们可以更好地理解Hibernate Annotation的强大功能,从而在开发过程中发挥出它的最大价值。
### Hibernate Annotation 学习知识点详解 #### 一、概述 Hibernate 是一款开源的对象关系映射 (ORM) 巨具,它极大地简化了 Java 应用程序与数据库之间的交互过程。Hibernate 支持多种注解(Annotation),使得...
3. 注解(Annotation)在Hibernate中的应用: - @Entity:标记一个Java类为数据库中的一个表,表示该类是实体类。 - @Table:指定实体类对应的数据库表名。 - @Id:标识类中的主键字段,可以配合@GeneratedValue...
Java SSH项目是基于三个主要框架——Struts、Spring和Hibernate构建的企业级Web应用程序。这个项目中,Hibernate作为ORM(对象关系映射)工具被用来处理数据库操作,而使用了注解方式来配置Hibernate,这是一种更加...