传智播客学习笔记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
汤老师介绍了很多快捷键的使用,能够有效地提高效率
- 传智播客学习笔记5.17
- java学习笔记5.17
- 传智播客学习笔记4.6
- 传智播客学习笔记4.9
- 传智播客学习笔记4.10
- 传智播客学习笔记4.12
- 传智播客学习笔记4.13
- 传智播客学习笔记4.14
- 传智播客学习笔记4.16
- 传智播客学习笔记4.17
- 传智播客学习笔记4.17
- 传智播客学习笔记4.19
- 传智播客学习笔记4.20
- 传智播客学习笔记4.22
- 传智播客学习笔记4.24
- 传智播客学习笔记4.26
- 传智播客学习笔记4.27
- 传智播客学习笔记4.28
- 让firefox3.5也可以使用tab mix plus
- java classcastexception 哈希表中的对象只能是同一类型的
- CMarkUp使用简介
- C#读取Win32标准DLL文件中的Bitmap(位图)
- 传智播客学习笔记5.15&5.16
- 传智播客学习笔记5.17
- 传智播客学习笔记5.19
- 传智播客学习笔记5.20
- 迭代与递归
- CSS 单位
- CSS单位
- 鼠标滚轮程序以及CSS的zoom属性范例
- 自定义checkbox大小(注:用CSS的ZOOM属性 )
- 虚拟机上网问题解决方法