传智播客学习笔记5.17

来源:互联网 发布:2016 网络新词 编辑:程序博客网 时间:2024/05/01 15:59

传智播客学习笔记5.17
Hibernate 汤阳光老师

上午:环境的搭建
第一个HIBERNATE程序

Eclipse快捷键:

ctrl+shift+t:查找列名?
ctrl+d:删除一行
alt+向下箭头:
shift+enter

ctrl+shift+l:连按两次,打开快捷键配置窗口

String arg0这样的参数?关联源码后即可解决

添加getter/setter方法:alt+shift+s:打开source窗口,ctrl+r。


 <property name="birthday" type="date"></property>
不指定column时,与name相同

自动更新表结构:(创建SessionFactory时)
<property name="hibernate.hbm2ddl.auto">update</property>

ctrl+alt+向下箭头:复制当前行到下一行

<property name="avatar" type="binary" length="512000"></property>

实体类或属性名与数据库关键字冲突问题:
table=`关键字`
column= `关键字`

基本类型的映射


下午:


主键生成策略

如何判断自由状态还是游离状态?
id属性中unsaved-value值(主键生成策略是assigned时,该值失效)


get和load的区别
区别一、
load:在第一次使用时,才真正去数据库查询数据
懒加载

区别二、
在查找不存在的值时
get返回空
load报错

mysql客户端编码只能是gbk(命令行窗口就是gbk编码)

最简单的mysql数据库配置文件(无乱码,可用。直接覆盖my.ini即可):
[mysql]
default-character-set=gbk
[mysqld]
default-character-set=utf8
default-storage-engine=innodb


Hibernate绝大多数情况下使用 Set

Bag与List类似,但是没有顺序。Class中对应类型为List


集合属性

外键是怎么找到主键的?

一对多

一对多中,一的配置文件中,set属性不需要指定表名
table (optional - defaults to property name) the name of the collection table (not used for one-to-many associations)

<hibernate-mapping>
其中可以加入package属性

 

声明集合属性的时候,只能用接口,不能使用具体实现类(Hibernate会采用自己实现集合接口的类)

官方推荐开发流程:
Domain Object -> mapping -> db

save和persist差别
persist在事务外不会产生insert语句 ?

 


Java是面向对象语言,对象模型,其主要概念有:继承、关联、多态等;关系型
数据库中的概念有:表、主键、外键等。当使用Jdbc去操作关系型数据库时,因
为他们对应不起来,所以要做转换(转换的过程就叫做ORM, Object Relation
Mapping, 对象关系映射)。除了手工转换外,还可以使用ORM框架来解决,当前
主流ORM框架有Hibernate和TopLink等,我们学习的是Hibernate(3.2.6).

* HelloWorld
有实体User,他有两个属性id:int和name:String,用Hibernate实现对User实体
的增删改查。

1,准备环境:
   a) 导入jar包,最基本的包为:hibernate3.jar,antlr-2.7.6.jar,
      asm.jar,asm-attrs.jar,cglib-2.1.3.jar,dom4j-1.6.1.jar,
      commons-collections-2.1.1.jar,commons-logging-1.0.4.jar,jta.jar,
      所用的数据库的JDBC驱动,可以选择加入log4j-1.2.11.jar。
   b) 拷贝配置文件hibernate.cfg.xml到classpath的根中,并修改其中的数据
      库连接信息。选择拷贝log4j.properties文件。可以到doc/tutorial/src中去
      拷贝。
2,写出实体User,有属性id:int和name:String,并写出映射文件User.hbm.xml。
   映射文件的模板可以到eg/目录下找或到文档中拷贝。
3, 完成对User的save,delete,update,get(id),find(first,max)。
4, 使用Junit测试UserDao。
5, 练习UserDao(增删改查)。

* 映射文件
property元素是映射普通属性的。name;column,以及一些说明列的性质的属性,
也可以用子元素column来说明。

property元素的type可用的值,并给User增加如下属性:
1,用户的生日birthday:Date:date类型。
2,用户的头像avatar:byte[]:binary类型。
3,用户的说明resume:String:text类型。

如果没有指定属性对应的列表,并且属性名刚好和数据库中的关键字冲突,在执
行时就会抛一个sql语法错误的异常。有两个解决方法:1,用column指定一个与
关键字不冲突的列名;2,用column指定的列名加上反引号(`),Hibernate会根据
使用的SQLDialect来生成正确的引号风格)。

<!-- 自动更新表结构 -->
<property name="hbm2ddl.auto">update</property>
<!-- 显示sql语句 -->
<property name="show_sql">true</property>


Hibernate映射文件就是用于说明Java对象与数据库表中的记录的对应关系的。不
同性质的属性(例如主键和普通属性)用不同的标签来映射,如果Java对象中的
某个属性不需要存储到数据库中,那么就不需要在映射文件中配置这个属性。

** Hibernate对实体(POJO)的要求:
    1,有默认的构造方法;
    2,推荐提供一个标识属性(与业务无关的id);
    3,推荐此类不是final的(对懒加载有影响);
    4,推荐重写hashCode与equals方法。

hibernate-mapping元素的属性:package:指定一个包前缀,如果在映射文档中
没有指定全限定的类名,就使用这个作为包名;auto-import:指定是否可以在查
询语言中使用非全限定名(仅限于本映射文件中的类),默认为true。

在hibernate-mapping元素中可以嵌套多个class元素来映射多个实体类。但是最
好是一个实体类(或一个类的继承层次)对应一个映射文件,并以实体类的名称
(或超类名称)命名。

class元素的属性:name:实体类的全限定名(如果在hibernate-mapping指定了
包名的话,可以写非全限定名);table:对应的数据库表名,默认是类的非全限
定名。

id元素,与主键生成策略:increment,由Hibernate维护主键值自动增长,是在
插入数据前先select max(id)得到当前最大的id值,再进行计算新插入对象的id
的值。identity;hilo;native;uuid;


* Hibernate对象实例的三种状态与Session的方法:
  三种状态:自由(瞬时)、持久、游离;

瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器
    回收,一般是new出来且与session没有关联的对象。

持久(persistent):数据库中有数据与之对应,当前与session有关联,拥有持久
    化标识(相当于主键值),并且相关联的session没有关闭,事务没有提交;
    持久对象状态发生改变,最终会同步到数据库中。

游离(detached):数据库中有数据与之对应,但当前没有session与之关联;游离
    对象状态发生改变,hibernate不能检测到。

这里没有使用"脱管"这个概念,因为容易和"托管"混淆;前者代表"游离",而后
者的代表"持久"。

对照着图讲解session的主要方法与在各个状态之间的转换,并且试验各个方法会
生成什么样的sql语句,及在什么时候生成(马上生成或是在flush()或是
commit()时生成。应是说:sql语句都应是在flush()时产生的,tx.commit()会先
flush(),在主键策略为identity时,执行save()方法会马上生成一条sql语句并
且执行,这是因为hibernate要求持久状态一定要拥有持久化标识,而这个标识是
由数据库生成的(自动增长的主键值),所以只有执行了插入才能知道主键值是
多少)。

试验saveOrUpdate()时讲解id元素的unsaved-value的作用:指定当主键值为什么
时表示这个对象是自由状态的。如果果自由状态,就会生成insert语句,否则生
成update语句。

对一个对象在同一个session中多次使用save(),update()等等没有意义,跟调用
一次的结果是一样的。如调用两次save()只生成一条insert语句。


* 集合映射
如果实体类有一个集合类型的属性,就需要一张额外的表,即所谓的集合表,这
个表有一个外键引用实体类对应的表的主键。

根据集合中存放的元素类型可以分为两种:1,值类型集合,元素是可识别的数据
库类型,如基本数据类型或字符串类型等;2,实体类型集合,元素是其他的实体。

** 对集合做映射时一般需要指定:
1)集合表的表名,在相应元素中使用属性table指定;
2)集合外键,是在子元素key中用属性column属性指定一个列名,他是一个外键
   引用了实体表的主键;
3)集合元素,对于值类型集合,使用元素element指定;对于实体类型集合,使
   用元素one-to-many或many-to-many。
4)如果是索引集合,如List,数组或Map(bag不是),还需要指定一个集合表中
   的索引字段,用于对应到数组索引或List的索引,或者Map的key。
   a) 如果是List或数组,需要指定(集合表中的)一个用于保存索引的列,用
      元素list-index指定。
   b) 如果是Map:key用map-key元素指定;如果key是一个实体引用,则是通过
      map-key-many-to-many来配置。

JAVA的实体类中集合只能定义成接口不能定义成具体类,因为在运行时集合会被
替换成Hibernate的实现。

在实体类中声明集合时,可进行初始化。比如Set addresses = new HashSet();
这样做的目的是方便往集合中添加元素,调用getAddresses().add(element)就可
以了,不需再做是否为null的判断。  注意,我们只在把addresses初始化为一个
HashSet的实例,在运行时,集合会被Hibernate替换为自已的实现。

用于映射集合类的元素是由集合接口的类型决定的:
  <set>  元素用来映射 java.util.Set  类型的属性;
  <list> 元素用来映射 java.util.List 类型的属性;
  <array>元素用来映射 对象类型的数组;
  <primitive-array>元素用来映射 原始数据类型的数组;
  <bag>  元素用来映射 java.util.List 类型的属性(允许重复但没有顺序);
  <map>  元素用来映射 java.util.Map  类型的属性;

1,Set,一个用户(User)有多个地址,地址是字符串类型的。
    <set name="addresses" table="itcast_useraddresses">
     <key column="userId"></key>
     <element type="string" column="address"></element>
    </set>

2,List,与Set相比,需要在表中增加一列用于保存索引(元素在List中保存的
   顺序,不对应实体的任何属性)。用<list-index>元素指定:
    <list name="phoneNumbers" table="itcast_user_phonenumbers">
     <key column="userId"></key>
     <list-index column="idx"></list-index>
     <element type="string" column="phoneNumber"></element>
    </list>

3,Map,需要映射key的value:
    <map name="phoneNumbers3" table="itcast_user_phonenumbers3">
     <key column="userId"></key>
     <map-key type="string" column="idx"></map-key>
     <element type="string" column="phoneNumber"></element>
    </map>


Hibernate区别于其它一些持续性解决方案(例如EJB实体Bean)的一项重要特征:持续类可以在任意的执
行环境中使用——不需要专门的容器。

It’s a good idea to add a convenience method to the Category class that groups
these operations, allowing reuse and helping ensure correctness:
public void addChildCategory(Category childCategory) {
if (childCategory == null)
throw new IllegalArgumentException("Null child category!");
if (childCategory.getParentCategory() != null)
childCategory.getParentCategory().getChildCategories()
.remove(childCategory);
childCategory.setParentCategory(this);
childCategories.add(childCategory);
}
The addChildCategory() method not only reduces the lines of code when dealing
with Category objects, but also enforces the cardinality of the association


汤老师介绍了很多快捷键的使用,能够有效地提高效率

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 考科目三下暴雨怎么办 挂科太多拿不到毕业证怎么办 挂科太多不给毕业证怎么办 大专毕业拿不到毕业证怎么办 高考差一分二本怎么办 3个月宝宝大小眼怎么办 华东交大理工学院没有评教怎么办 学校断4g网怎么办 学校移动4g网卡怎么办 没上专科线怎么办福建 联考没过本科线怎么办 拍婚纱拍的脸歪怎么办? 老婆彻底寒心要离婚怎么办 手机被同学偷了怎么办 钱被同学偷了怎么办 上班穿皮鞋脚疼怎么办 高跟靴子买大了怎么办 我怀了第三个小孩怎么办? 离婚前把钱花了怎么办 对谈对象有压力怎么办 和对象感情淡了怎么办 孩子处对象学习下降怎么办 孩子高三成绩差怎么办 老妈怨气太重怎么办 广东小高考有d怎么办 高考考生档案袋有个小洞怎么办 江苏省考生出省后小高考成绩怎么办 江苏小高考三D怎么办 小高考补考没过怎么办 理科高考200多分怎么办 高考没考过200分怎么办 电子手表指针不走了怎么办 家长说你教的不好怎么办 小升初分班考试考砸了怎么办 老公不给老婆看病怎么办 孕妈妈涨奶严重怎么办 90岁老头尿不下尿怎么办 妻子要离婚丈夫不离怎么办 弟媳妇天天在家吵架怎么办 弟媳妇不和我说话怎么办 我想和弟媳妇做一次怎么办