JavaEE-Hibernate入门笔记
2015-09-20 23:53
441 查看
hibernate体系结构
my.inilog = c:/xxx
可以得到sql查询历史
最上层
app(pojo对象(实体对象))—>api—>hibernate(htbernate.cfg.xml, *.hbm.xml)—>jdbc—->database
单对象查询, get和load的区别。
get就是sql语句执行,找得到就找,找不到返回空。
load,是找了之后要对对象进行装载,相当于user.setXXX,因为是空,所以报错,因为无法装载user;会报ObjectNotFound。
第二种区别:get要执行sql语句,要打印出Sql语句,假如设置了show_sql,不访问属性也要读取sql,
而load,不读取查找到的对象属性,就不会打印sql。读取的时候才打印sql,也是相当于执行sql (懒加载)
单对象的方法, Query q.uniqueResult(),得到唯一的一个对象,假如查询到了多个纪录,
多参数连续替换,参数设置
第一种,用问号,设置参数用(索引,值 session.createQuery(?).setParameter(0,4).setParameter(1,4) 第二种,语句复杂后建议用这种,注意,两种不能同时用; setParameter(名字,值); session.createQuery(:id).setParameter("id",4) 第三种,多条件查询,map集合,map的键和占位符名字一样,值就是查询条件的值 Map param = new HashMap(); param.put("uid",5); map的键要和:uid这个冒号给的名一样。 Query q.setProperties(param(Map对象)) 第四种:javaBean方法,注意,占位符:xxx 的XXX要和对象里面的属性名相符合 User userParam = new User(); userParam.setName(""); userParam.setGender(false); Query q.setProperties(userParam).list(); ; hql = "select new User(id,name) from User u "; 这样就只能得到数据库中的 id和name 字段,,返回的是一个对象列表 而 hql = "select id,name from User u"; 得到的是一个object[] List<Object[]> list = q.list(); 迭代器查询 Iterator<User> us = session.createQuery(hql).iterate(); 先查询所有id,然后一条一条查询的,根据id。 标准查询 Criteria c = session.createCriteria(User.class); List<User> us = c.list(); 添加查询条件 c.add(Restrictions.eq("对象属性",需要查的值)); Restrictions.or("name",name),Restrictions.eq("gender",false); c.list(); 不等于 not(eq());
QBE查询
query by example使用EMP的时候,要注意创建查询属性的时候不能使用基本类型,例如boolean,要使用包装类型Boolean
关系映射
关系(对象关系):1. one to one
2. many to one ; one to many
3. many to many
4. 继承关系
一对一:
例如,公民<—>身份证;
一个对象包含另一个对象,另一个对象包含这个对象。
主键关联:两个表的主键相同;
一个表的PK_id是关联的另一个表的pk_id
一个表的主键是另一个表的主键,这个主键既是主键也是外键
一个表的主键是参考另外一个表的主键。
在映射的时候主键生成方式
<generator class="foreign"> <param name="property">husband(类里面包含的其他对象)</param> </generator> 关系的映射: <one-to-one name="该类包含的另外的对象名" class="包含的对象的权限定名"></one-to-one> 另外一个对象的ORM也需要这样配置; 在代码中 h.setWife(w); w.setHusband(h); session.save(h); session.save(w);
一对一方法2:
唯一外键关联,在主表里面,建立一个外键,这个外键是另外一个表的主键。 (唯一外键,为这个外键添加unique属性?)
一对多关系映射:
单项关联(效率不高),在一的方向建立多的对象的Set集合。然后在配置里面写
<Set name="多对象作为该对象里的的属性名" table="多对象所在的数据库中的表" inverse="true"控制反转,如果是true,就将外键关系维护权利交给另外一个来管理。各自做自己的。> <key column="one在表中代表的列"></key> <one-to-many class="many所指代的类的地址"/> </Set> 双向关联,另一个配置 <many-to-one name="该对象中“一”属性的标识符" column="one所在的表列名" class="">
多对一,其实就一对多的特殊情况
这个”一”是基础数据,是独立的。预先就有数据,我们的多只是需要选择这个”一”,来规定这个多是属于哪个 一”自关联(树状结构())
例如银行。银行中包括上级银行和子级银行;
上级为一个Bank,子级为一个
Set<Bank>
<many-to-one name="parentBank" column="fk_bank_id" class="com.wang.model.Bank"> </many-to-one> <!-- many to one 的colum为one代表的键,多 to one,多个bank有共同的parentBank --> <set name="childBank" table="t_bank" cascade="all" inverse="true"> <!-- one代表的键 ,一个fk_bank_id有多个child--> <key column="fk_bank_id"></key> <one-to-many class="com.wang.model.Bank"/> </set>
多对多
<set name = "该类的哪个属性名(Set)" table="它们的关系所在的表"> <key column="自己在这个表中代表的位置"> <many-to-many column="以自己相关的另一个对象的类在表中的列名" class="以自己相关的另一个对象的类权限定名"></many-to-many> </set>
多对多的查询
select xx.set from YY类 xx where xx.name=”;
继承映射
一张表,建立一个type,来放对象属于类型,该列对对象来说,是透明的。配置的时候只用根据父类来配置xml,在父类配置里面将子类描述
表示子类
<id name="" column = ""> <generator class="identity"></generator> </id> <!--下面这句话必须写在<property>参数前面,最好就跟在id字段后面写--> <discriminator column = "标识字段的列名,即下面F,D,对应的列。"></discriminator> <property name="其他属性字段" column=""></property> <subclass name="子类权限定名1" discriminator-value="表中的type是什么时,代表这个子类" > <property name="子类特有属性" column="表中对象字段"></property> </subclass> 另一个子类 <subclass name="子类权限定名2" discriminator-value="表中的type是什么时,代表这个子类" > <property name="子类特有属性" column="表中对象字段"></property> </subclass>
查询,如果要查所有xxx对象(父类下的所有其他子类对象),直接针对父类的类来查询,如果要对查出来的不同子类进行不同 的操作
可以遍历父类(使用父类声明),然后用instanceof 具体子类 ,来进行操作。
From java.lang.Object可以查询到映射配置中,一级数据库中存在的所有对象
级联对象cascade属性列表:
none :忽略其他关联对象
save-update:当通过save()update()及saveOrUpdate()级联保存新建临时对象,更新游离对象
persist:级联保存新建对象
merge:融合当前对象时,级联融合所有关联的游离对象
delete:级联删除所有关联的对象
lock:锁?
replicate:赋值当前对象时,会级联复制所有关联的对象
evict:清楚对象时,会级联清楚
refresh:刷新是指读取数据库中响应数据(refresh()方法),会级联刷新所有关联的对象,用数据库中的最新数据去同步更新Session缓存中的响应对象;
all
delete-orphan 删除所有和当前解除级联关系的对象
all-delete-orphan,包括all和delete-orphan
子集对父级的级联的many-to-one的cascade最好为none,避免多余的update语句
事物的提交,tx.commit(),其实差不多是一个清理Session缓存的手段,更新或新增或删除响应数据
批量处理:mysql不能通过储存过程来进行批量更新或批量删除;(一般来说,应该再数据库层直接进行)
通过session来批量操作会受到以下约束。
1.配置文件中,设置
hibernate.jdbc.batch_size=20;
2.如果对象采用identity标识符生成器,则Hibernate无法在JDBC层进行批量插入操作
3.批量操作时,建议关闭二级缓存
批量插入:注意,对象标识符生成器不能为identity
if(i%20 == 0 ){
session.flust();
session.clear();
}
使用HQL来批量操作数据;
更新和删除都差不多
注意批量插入
insert into EntityName properties_list select_statement;
EntityName表示持久化类的名字, properties_list表示持久化类的属性列表,select_statment表示子查询语句;
HQL只支持insert into …select… 不支持insert into values…
实例:把Cusutmoers表中的数据复制到Delinquent_Account表中
insert into DelinquentAccount(id,name) select c.id,c.name from Customer c where c.id>1;
int createdEntities = session.createQuery(hql).executeUpdate();
相关文章推荐
- 初始Java——解释型还是编译型?
- JavaWeb-JSP
- java中read()和readline()方法对比
- JavaWeb-过滤器
- JavaWeb-会话
- java随堂笔记2
- Java中的递归调用
- eclipse下gradle配置
- struts标签与C标签下拉框
- spring学习日记 (1)jdom的小栗子
- java拾遗--有关数组和list的转化
- struts原理及核心流程
- Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition
- Netbeans设计简易计算器学习
- spring Ioc 实践
- java把字符串转化为unicode编码
- Java多线程基础知识(三)
- java开发前奏
- Caused by: java.lang.ClassNotFoundException: org.hibernate.impl.SessionImpl
- JAVA字符串的各种编码转换