Category:学习笔记’
Hibernate关联映射
- by wu shengyuan
以简单的两个类为例:
User(int id, String name)
Group(int id, String name)
没有关联关系时的关系模型:
t_user(id int pk, name varchar)
t_group(id int pk, name varchar)
一、多对一和一对多关联映射(多个用户有相同的组)
这几种关联映射后的关系模型是相同的:
t_user(id int pk, name varchar, gid int fk->t_group(id))
t_group(id int pk, name varchar)
1、多对一单向关联
实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 使用<many-to-one>映射多对一关系。导出ddl时将自动生成一个外键 -->
<many-to-one name="group" column="gid"/>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
</class>
</hibernate-mapping>2、一对多单向关联(几乎不用)
实体模型:
bean.User(int id, String name)
bean.Group(int id, String name, Set users)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id"><generator class="native"/></id>
<property name="name"/>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 使用<set>映射集合 -->
<set name="users">
<!-- 使用<key>指定引用至自身的外键表(t_user)中的外键 -->
<key column="gid"/>
<!-- 使用<one-to-many>映射一对多关系 -->
<one-to-many class="bean.User"/>
</set>
</class>
</hibernate-mapping>为Group加入集合也可以使用List(<list>),注意不能指定类型是具体的HashSet或ArrayList,只能是接口Set或List。
集合标签可以使用order-by属性指定排序:
<set name="users" order-by="id desc">
3、双向关联
实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name, Set users)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 使用<many-to-one>映射多对一关系。导出ddl时将自动生成一个外键 -->
<many-to-one name="group" column="gid"/>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 使用<set>映射集合 -->
<set name="users">
<!-- 使用<key>指定引用至自身的外键表(t_user)中的外键 -->
<key column="gid"/>
<!-- 使用<one-to-many>映射一对多关系 -->
<one-to-many class="bean.User"/>
</set>
</class>
</hibernate-mapping>双向关联中,为<set>加入”inverse=true”可以反转维护关系:Hibernate将放弃从一的一端维护。意思就是user和group的关系必须使用user维护,操作group时Hibernate将不维护这个关系。
<set name="users" inverse="true">
操作group的示例:
session.beginTransaction();
User user = new User();
user.setName("张三");
Group group = new Group();
group.setName("admin");
group.setUsers(new HashSet());
group.getUsers().add(user);
session.save(user);
session.save(group);
session.getTransaction().commit();没有配置inverse=”true”时,Hibernate输出了添加user和group,并更新user的语句:
Hibernate: insert into t_user (name, gid) values (?, ?) Hibernate: insert into t_group (name) values (?) Hibernate: update t_user set gid=? where id=?
而配置了inverse=”true”后,Hibernate仅仅输出了添加user和group的语句,并没有更新user,放弃了关系的维护:
Hibernate: insert into t_user (name, gid) values (?, ?) Hibernate: insert into t_group (name) values (?)
此时应该从user端维护关系:
session.beginTransaction();
Group group = new Group();
group.setName("admin");
User user = new User();
user.setName("张三");
user.setGroup(group);
session.save(group);
session.save(user);
session.getTransaction().commit();因为外键列在t_user表中,从group端维护需要操作多表,所以从user端维护关系更加合理,效率也更高。上面的代码输出两条SQL语句,插入数据的同时也维护了关系:
Hibernate: insert into t_group (name) values (?) Hibernate: insert into t_user (name, gid) values (?, ?)
二、一对一关联映射(每个用户独有一个组)
依照映射方法不同,可分为主键关联映射和唯一外键关联映射。主键关联是维护两张表的主键一致,如有必要还可以在主键上再加上外键约束;唯一外键关联则类似于多对一关联,为表加入一个外键列,不过一对一关联会同时将这个外键加上唯一约束。
1、主键关联映射
主键关联生成的关系模型:
t_user(id int pk fk->t_group(id), name varchar)
t_group(id int pk, name varchar)
1.1、主键单向关联
实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id">
<!-- 指定主键生成策略为外键 -->
<generator class="foreign">
<!-- 指定要参照的属性 -->
<param name="property">group</param>
</generator>
</id>
<property name="name"/>
<!-- 使用<one-to-one>映射一对一关系。 -->
<one-to-one name="group">
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
</class>
</hibernate-mapping>主键关联由Hibernate维护,不依赖数据库。如果需要在数据库端也生成外键约束,可以使用constrained:
<one-to-one name="group" constrained="true"/>
1.2、主键双向关联
实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name, User user)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id">
<!-- 指定主键生成策略为外键 -->
<generator class="foreign">
<!-- 指定要参照的属性 -->
<param name="property">group</param>
</generator>
</id>
<property name="name"/>
<!-- 使用<one-to-one>映射一对一关系。 -->
<one-to-one name="group">
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 使用<one-to-one>映射一对一关系 -->
<one-to-one name="user"/>
</class>
</hibernate-mapping>
2、唯一外键关联映射
唯一外键关联生成的关系模型:
t_user(id int pk, name varchar, gid int fk->t_group(id))
t_group(id int pk, name varchar)
2.1、唯一外键单向关联
实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 为<many-to-one>加上unique就变成了一对一 -->
<many-to-one name="group" unique="true" column="gid"/>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
</class>
</hibernate-mapping>2.2、唯一外键双向关联
实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name, User user)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 为<many-to-one>加上unique就变成了一对一 -->
<many-to-one name="group" unique="true" column="gid"/>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 使用<one-to-one>映射一对一 -->
<one-to-one name="user"/>
</class>
</hibernate-mapping>三、多对多关联映射(每个用户拥有多个组,每个组也有多个用户)
多对多关联映射关系使用中间表表示。导出关系模型时Hibernate将自动生成复合主键以及外键约束。
关系模型:
t_user(id int pk, name varchar)
t_group(id int pk, name varchar)
t_user_group(userid int fk->t_user(id), groupid int fk->t_group(id), pk(userid, groupid))
1、多对多单向关联
实体模型:
bean.User(int id, String name, Set groups)
bean.Group(int id, String name)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
<set name="groups" table="t_user_group">
<!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
<key column="userid"/>
<!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
<many-to-many class="bean.Group" column="groupid"/>
</set>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id"><generator class="native"/></id>
<property name="name"/>
</class>
</hibernate-mapping>1、多对多单向关联
实体模型:
bean.User(int id, String name, Set groups)
bean.Group(int id, String name, Set users)
<!-- bean/User.hbm.xml -->
<hibernate-mapping>
<class name="bean.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
<set name="groups" table="t_user_group">
<!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
<key column="userid"/>
<!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
<many-to-many class="bean.Group" column="groupid"/>
</set>
</class>
</hibernate-mapping><!-- bean/Group.hbm.xml -->
<hibernate-mapping>
<class name="bean.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
<set name="users" table="t_user_group">
<!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
<key column="groupid"/>
<!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
<many-to-many class="bean.User" column="userid"/>
</set>
</class>
</hibernate-mapping>多对多的双向关联同样可以在不想要维护关系的一端的<set>里设置inverse=”true”;但是必须有一端可以维护,也就是说只可以设置一个。
针对移动设备web制作的小知识
- by wu shengyuan
最近,因为对手持设备样式表的逐渐了解,我对手机网站的开发设想产生了一点点改变。
首先,什么时候你会想打开手机用来上网?
通常有两种情况:一种是急需获得某种信息,但因为各种原因只能通过手机上网查询;另一种是闲着无聊,便通过手机上网消遣。
对于后一种情况,设计一种同电脑浏览有相同浏览体验的网站依然是每一个WEB开发者的梦想,但是对于前一种呢?当上课要迟到时,在路上赶路缺忘了上课的课室时,只想快速地查到想要的数据,一点不在乎网页的用户体验;同样,在外地想查询某公司的电话号码时,我们需要的,仅仅是一个8位数的电话号码,并不要任何的视觉效果。
现在开始,我们将讨论如何制作针对前一种情况的wml。
现在正是移动web的成长期,在这个阶段,手机的功能正在变得越来越强,他们的内存甚至比早期的个人电脑还要多,但是,与所有技术的成长期一样,移动WEB的未来还有太多的变数。数百种手持设备,它们可能使用四十种不同的浏览器,而这些浏览器以不同的方式支持HTML和CSS。目前我建议在等待移动WEB成熟的时候保持简约和耐心。
下面列出了一些针对手持设备应该注意的地方:
- 让每KB都物有所值,隐藏额外的部分,使用更少更小的图像,等等,因为WEB访问是昂贵的。
- 要确保站点上每个有意义的图像都有替换文本,使以无图像方式查看页面的访问者不会错过任何信息。因为访问者可能会选择在不显示图像的情况下查看页面(从而加快访问速度)。
- 保证图像尽可能小,彻底地对站点进行测试。因为许多手机浏览器(比如UCWEB)会通过代理服务器对网站进行过滤,从而去掉手机浏览器无法处理的内容。
- 在栏上使用窄的外边距,最好根本不使用。不要使用浮动、绝对定位、表格(它们的内容可能以出乎意料的次序显示)和弹出窗口。
- 避免使用固定宽度的设计。应该使用em和百分数来代替。
- 避免使用CSS字体属性,应该主要依靠标题标记,如h1,h2等等,来区分大标题和小标题。对于常规文本用p,对于强调部分用b或strong,尽量少用斜体。因为大多数手持浏览器只支持一种字体和最多两三种字号,支持粗体而不支持斜体(至少支持得不好)。
- 可以对导航条使用有编号的列表(ol)。因为手持设备对列表的支持很好。
- 避免使用背景图片。因为不太支持CSS的background-image属性。
- 一般支持CSS的color和background-color属性,应尽可能地利用,使得文本颜色和背景颜色之间的对比足够强烈,让访问者在日光下也能够看清页面上的内容。
- 确保站点的显示在没有加在样式表的情况下也是有意义的。测试时用尽可能多的手持设备或手持浏览器来查看站点。因为某些手持浏览器会完全忽视CSS文件(比如QQ手机浏览器居然像傻瓜似的不加载一个以上的样式表)。
开放移动web网页中的一些体会
- by wu shengyuan
本文讲述我这两周手机web开发中的一些经验总结,我是个菜鸟,有什么地方说错了请大家帮忙指点一下~
时代在不断变迁,手机上网早已普及大众,但远远落后的,不是停滞不前的wap协议,而是花样百出的手机浏览器,手机浏览器已进入百家争鸣的状态。但是欣慰的是,现在手机浏览器存在一个共同的目标:如何让网页显示得和电脑看到的一样(即使电脑不同浏览器间也存在差别,特别是CSS3的到来)。
我们没有选择WML,而是HTML。
WAP协议是针对流量受限,屏幕大小较小,功率消耗小,运算处理速度低的小型移动终端而设计的;尽管WAP的兼容性和可扩展性好,可是人们的目标始终是:手机浏览和电脑浏览能得到一致的效果,因此,随着手机浏览器的发展,WAP必将被舍弃。
参考资料:http://www.wapforum.org/faqs/index.htm
几个测试
通过对不同机型的实测,请允许我我主观地对结果做一个简单的排序:
Android自带浏览器
- 用户体验一流
用过Android自带浏览器的用户应该深有体会,当你用两个手指放大网页上的图片时,不得不在心理发出惊叹,这种感觉太棒了!,字体和图片全部跟着放大,并懂得自动换行,这才是smartphone! - 堪称完美的样式展示
测试用的9种手机浏览器中,这种是网页兼容性最好的浏览器了。和我在电脑上用firefox测试的效果一模一样,甚至在某些方面做得更好;而且,这是测试的9种浏览器中两种实现了自动跳转脚本的浏览器之一。 - 字体显示全部按用户设定的大小显示
- 用户体验一流
Opera Mobile (Version 10.00)
超炫的界面,几乎完美的兼容性,仅仅是偶尔的中文排版问题(原因不明,英文可以完美展示,中文浏览部分网站会排版错误,比如一行多出3个字符)。
Symbian s60 3rd UCWEB (V7.2.2.51)
适应屏幕模式:
- 强制统一了所以字体大小,包括h4~h6和p一样大,h1~h3比p大约2px。无斜体。
- 当字体颜色和背景颜色相同时,强制改为黑色。
- border-color默认为灰色。
- body强制有3px的margin。
- 不完全的无视margin和padding,默认margin为0,block元素有1px的padding-top和3px的padding-bottom,还有margin:5px 0px;但是当没有定义margin的上和下时,会出现IE典型的double margin的bug。
- 对于内联函数,对齐也有问题,有空截图下来。
缩放模式:字体还是统一了大小(UC这你就做得不对了)。
魅族自带浏览器
感觉就是仿Android,可是幸运的是,“该有”的小bug它也有了~
Opera Mini(Version 5.0.18755)
作为mini型浏览器,opera mini非常的出色,几乎完美地表现了盒子模型,只是偶尔会碰到中文字体换行有偏差,估计是外框的左padding撑开了字体?不对啊,一行显示的字数足足多出了4,5个…这个以后有空在研究。
Android UCWEB(v7.0.3.45) & 魅族UCWEB(v7.1.042 wince)
不明白为什么Android的UCWEB比Symbian的效果差,字体大小被重设,这本身没有什么问题,错就错在字体被放大得太大了,图标和图片还是原比例,搭配非常不协调。还有很多小bug,比如图标对齐有问题。
Symbian s60 3rd自带浏览器
网络浏览体验其实还蛮不错的,可惜以为一尘不变以及流量的浪费,使它最后还是成为了诺基亚的一个花瓶。
Symbian QQ浏览器
请原谅这位手机浏览器的初生婴儿吧,半岁大的QQ手机浏览器,不单止只能载入单一CSS,默认字体和大小都奇丑无比,样式也一团糟,还自作聪明地去掉了所有空格,除了进QQ农场,还是不要干别的好…
一些要注意的地方:
- 所有测试的适应屏幕浏览器均不支持a:focus。所有懂得适应屏幕模式都重设了字体大小和样式。(现在想想重设才是正常的)
- 不要自动跳转。
- 少用背景图片。
【字体】
- 不要对字体抱有任何幻想,感觉比较漂亮的字体还是arial,sans-serif;
- 字体大小虽然不是必要但是最好还是重新设定,这对于能缩放的浏览器有较好的用户体验;
- 视觉设计不要依赖于你的字体大小和字体颜色,因为大多数浏览器会重设你的字体,包括大小和颜色
Summary
- 对于有重写代码的css,手机浏览器对重写的优先级顺序更加复杂,建议不要写太复杂的CSS。
- 手机浏览器兼容性相当混乱,不建议尝试制作精密到像素的手机WEB设计。
- 如果目标只是制作手机网页,怎么简单就怎么做,不要依赖CSS达到美观效果,但可以试着多加些小gif图标。
- 既然不同浏览器的网页展现方式如此不同,那么,最低限度请不要出现任何的html或css错误了,对代码不严密的网页,不同浏览器的纠错能力各不相同,展示效果更是“随心所欲”。