传智播客学习笔记5.17

传智播客学习笔记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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 传智播客是一家著名的IT培训机构,成立于1998年,总部位于中国北京市。他们专注于提供高质量的IT技能培训,培养人才并满足市场对IT人才的需求。 传智播客以其优质的师资力量和完善的教育体系而闻名。他们拥有一支由业内专家和经验丰富的讲师组成的教师团队,能够提供全面的知识和实践指导。此外,他们还与许多知名的IT企业合作,以保持他们的课程内容与行业发展的最新趋势保持同步。 传智播客的培训课程涵盖了多个领域,如计算机编程、网络技术、数据库管理和移动应用开发等。无论是初学者还是有经验的专业人士,都可以找到适合他们的课程。他们的培训内容从基础知识到高级技能的学习,全方位满足学员的需求。 传智播客的特色在于他们注重实践能力的培养。培训期间,学员们将参与实际项目的开发,通过动手实践解决实际问题,提升他们的技能和经验。此外,学员们还可以借助他们的校友和教师的支持,进行项目交流和合作。 总之,传智播客作为一家领先的IT培训机构,通过提供优质的教育和实践机会,已经培养了大量的优秀IT人才。他们的成功要归功于他们的专业师资、丰富的课程和实践导向的教学方法。无论是学习者还是企业,都可以从传智播客的培训中受益,并且他们对IT行业的贡献会持续增长。 ### 回答2: 传智播客C是一家在编程教育领域具有知名度和影响力的教育机构。他们提供的培训课程以计算机编程为主,涵盖了包括软件开发、网站建设、移动应用开发等多个方向。通过他们的培训,学员可以学到实际的编程技能,并具备在相关领域就业的能力。 传智播客C作为教育机构的成功之处在于他们对教学的重视和创新。他们的教学方式注重实践,通过项目驱动的教学方式,让学员在真实的项目中进行编程实践和解决问题,从而加深对知识的理解和掌握。此外,他们还注重培养学员的动手能力和团队合作能力,通过小组协作的项目实践,让学员学会与他人合作并有效地应用所学知识。 除了教学方式的创新,传智播客C还具备其他优势。首先,他们拥有一支优秀的师资队伍,这些讲师都是业界的专业人士,能够将最新的技术和实践经验传授给学员。其次,他们与众多知名IT企业建立了合作关系,学员有机会参与实习和就业推荐。此外,他们还提供灵活的学习方式,包括线下课程和线上课程,满足不同学员的需求。 总的来说,传智播客C在编程教育领域具有很高的声誉和影响力。他们通过创新的教学方式和专业的师资队伍,为学员提供了一个良好的学习环境和就业机会。无论是想要入门编程还是提升技能,传智播客C都是一个值得考虑的教育机构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值