hibernate笔记整理
原文地址:http://blog.csdn.net/xyls_2009/archive/2009/12/30/5109374.aspx
?
在配置文件中hibernate这个前缀可以省略不写
?如:<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
可写为<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
?当我们的类名或属性名与数据库中的关键字冲突时,我们可以修改表中的字段名,也可以在映射文件
中加上反引号(`)在tab键上方,这时会当作字符串处理;或修改对应的表名称
?如:在oracle中user是一个关键字
?<class name="User" table="`user`"> 或 <class name="User" table="tuser">?
? <property name="name" column="tname"/>? 如这种
?</class>
?在配置文件中如果没有指定table、column则hibernate会按默认执行,即表名与类名相同,字段名
与属性名相同.
?如果要求不允许有相同的name,则可以加上: unique="true"如下
?<property name="name" unique="true"/>
对于下面这句代码
?User user = (User) session.get(User.class, id);
我们可以这样理解
?由于Session可以管理多个数据库表所对应的多个实体对象,如果查询id为1的实体对象,
Session.get方法需要知道从哪个数据库表中查询id为1的记录,所以,除了给get方法传递所
要查询的实体对象的id值外,还必须给get方法传递实体对象的类型,get方法才能知道去哪个
数据库表中进行查询
?通过学习,我们可以发现通过session去查询数据库有很大的局限性,它只能通过id去查询,而
在现实使用中,我们的需求肯定不只这些.这时我们就需要通过hql完成查询,hql是通过query创建
的:Query query = session.createQuery(hql);
以往的sql是查表,而这里的hql是查询对象
?还有一种比hql更方便的查询方式:Criteria,这也是由session创建的:
? Criteria crit = session.createCriteria(Class clazz);
?
?使用 命名参数 替换?
?如:String hql = "from User as user where user.name=?";
?query = session.createQuery(hql);
?query.setString(0, name);//下标从0开始,跟jdbc不同
?可通过命名参数修改为
?String hql = "from User as user where user.name=:name";需要加上一个冒号
?query = session.createQuery(hql);
?query.setString(name, "xyls");
?这样做就可以避免因为失误造成错误
?
?实现分页
? query.setFirstResult(0);//从哪一条开始取
? query.setMaxResults(10);//取多少条记录
?好处:跨数据库,可移植,不论用哪一种数据库,都可以通过此种方式,hibernate中通过方言类生成分页语句
? oracle用rowNormal
? mysql用limit
? sqlserver用top
?
?要注意单向关联与双向关联的关系
?
?多对多关系(如:teacher-student),在操作和性能方面都不太理想,所以多对多的映射使用较少,
实际使用中最好转换成一对多的对象模型,Hibernate会为我们创建中间关联表,转换成两个一对多的关系.
?
?多对一的关系使用的最多
?
?在学习Hibernate如何处理对象之间的关联关系的底层细节时,可以从两个方面去考虑:
? .如何将对象之间的关联关系保存到数据库中
? .如何检索出关联的对象
?
?List存储是有序的,而Set是无序的
?<set name="emps">
? <key column="depart_id"/>
? <one-to-many column="name"/>
? <one-to-many cascade="save-update">//cascade有很多可选用的值
?? <key column="depart_id"/>
?? <one-to-many **
?inverse:是否放弃维护关联关系(在java中两个对象产生关联关系时,对数据库表的影响),
在一对多和多对多的集合定义中使用,inverst="true"表示该对象不维护关联关系,该属性的值一般在
使用有序集合时设置成false(hibernate缺省值是false).
?一对多维护关联关系就是更新外键,
?多对多维护关联关系就是在中间表中增删记录.(两端都告诉,会报异常,可通过放弃关系维护避免)
?注:配置成一对一的对象不维护关联关系
?inverse属性只会在集合中出现,如Set,List,array,Map,不同于cascade
?如:<set name="emps" inverse="true">//效率会更高一些,不会产生update语句,一端不会考虑多端
?? <key column="depart_id"/>
?? <one-to-many type="int"/>//鉴别器,用来区别不同的子类,应放在id属性下面
type="string"是默认的
?如:<subclass name="Skiller" discriminator-value="1">
?? <property name="skill"/>
? </subclass>
?
? <subclass name="Sales" discriminator-value="2">
?? <property name="sell"/>
? </subclass>
?
?discriminator-value="*"用来区分
?特有的字段不能加上非空约束
?
?每个子类对应一张表,效率低,但是在关系模型上更合理
?<joined-subclass name="Skiller" table="skiller">
?? <key column="emp_id"/>
?? <property name="skill"/>
? </joined-subclass>
?
? <joined-subclass name="Sales" table="sales">
?? <key column="emp_id"/>
?? <property name="sell"/>
? </joined-subclass>
?
?另一种情况:还需要鉴别器,单独一张表处理sales,效率得到了提升
? <discriminator column="type" type="int"/>
?
? <subclass name="Skiller" discriminator-value="1">
?? <property name="skill"/>
? </subclass>
?
? <subclass name="Sales" discriminator-value="2">
?? <join table="sales">
??? <key column="emp_id"/>
??? <property name="sell"/>
?? </join>
? </subclass>
? 如果有异常,可以通过删除数据库完成操作,因为之前会有三张表
?
?每个类独立映射:不再提取公共类,不需要关联查询,每个具体类一张表
?(混全使用"一个类继承体系一张表"和"每个子类一张表"),需要更换主键生成策略hilo,不再需
要鉴别器,操作时报异常,需要删除相关表,或删除数据库,重建
如果主表是抽象的,加一个属性abstract="true",就不会产生Employee表了
? <id name="id">
?? <generator table="skiller">
?? <property name="skill"/>
? </union-subclass>
? <union-subclass name="Sales" table="sales">
?? <property name="sell"/>
? </union-subclass>
?
?注意一条原则:表的数目不要超过类的数目,表越多关联查询就越多,效率就越低
?
?
1 楼 csdn_zuoqiang 2010-08-03hibernate 学习总结:http://jianchen.iteye.com/category/33526