2009年5月14日
Annotation是JavaSE5开始引入的,在Java的世界已是大行其道,各大开源框架Hibernate、Spring等都对它无缝集成,足见其份量了。。
其实很早就出现在程序员的视野,只是关注的比较少:@Override、@SuppressWarnings("unchecked"),开始主要觉得没什么用处,后来公司的框架用到它,感觉还不错。。于是来一记:
在网上搜Annotation的学习资料不是很多,还是用的人不多
,比较经典的入门就是这个:
实战篇:设计自己的Annotation,很清楚,通俗易懂,这里我就不赘述了。然而仅仅是弄懂它是怎么回事,具体还是没什么用处,这也是大多数开发人员的感觉。
在现在的公司的经历两次框架升级,第一次没有用到Annotation,xml配置文件大行其道:Action跳转、Ibatis sqlmapper、Form表单(我们的表单都是从后台生成的),整个项目xml眼花缭乱,每个模块都有自己专属的配置文件,然后集中到一起处理,而我们最痛苦的莫过于写那大量重复的配置文件。
后来公司接了个ERP的单子,技术总监马上意识到框架该升级了,他技术很牛,我们公司的框架就是他一人写的,两周之后,新框架出炉,xml只保留三分之一:Action跳转、Form表单都不再使用xml配置,而是Annotation横空出世,给我的感觉:它就像一个救世主,让我们的框架重生,它就是这次升级的最大亮点,只有sqlmapper依然保留,这无可厚非,因为它原本是ibatis封装的,Action控制器既不是Struts1,Struts2,也不是Webwork,是总监自己封装的Servlet,Form表单都由后台生成js组件抛到前端,通过反编译看到源码,其实还是很基础的,贴些代码上来看下吧:
1.Action请求部分:
/**
* 显示新增页面
* author YuWenLin
* date 2010-5-13 上午10:31:57
* @param data
*/
@Action("/add.shtml")
@Permission("client.ContractType.add")
public void add(ActionData data){
FormBuilder builder = data.getService(FormBuilder.class);
builder.append(Type.class);
builder.setAction("client/contract/type/add.do");
data.put("script", builder);
//向页面抛出cookie提示信息
MessageUtil.putMessage(data);
data.setResulter("template");
data.setPath("client/contract/type/type.shtml");
}
可能大家看得不太明白(每个公司都有自己框架),没有关系,就两句:
@Action("/add.shtml")
它就是负责请求显示新增的页面,就这一句,不需要像我们以前的action.xml(类似Struts2的跳转),干净利索吧,当然底层后台有处理,但是公共的,不需我们管,至于
@Permission("client.ContractType.add")
就是用来处理权限管理的,也是Annotation的使用,就这一句。就权限管理,后面我也会记述。。。
2.再来看看@Action底层的定义:
package org.plugbase.action;
import java.lang.annotation.Annotation;
public interface Action
extends Annotation
{
public abstract String value();
}
说明下:extends Annotation跟 @interface是一样的效果,只不过前者手动extends,后者自动的。
怎么样,很基础吧,跟jdk源码是一样的。。。
3.JavaBean生成表单:
@Widget(value="TextBox")
@Valider({"notempty","len(2,8)"})
public void setName(String name) {
this.name = name;
}
给setter方法加Annotation,@Widget是组件,@Valider是验证
意思就是给name字段生成TextBox组件,并做验证处理,后台有相应的公共js组件,验证控件库调用,我们所有的表单组件都是这样生成的,说实话,这样生成一个页面真有点繁锁,既要写js,又要写后台,前端还要配,还真是有技术含量,呵呵。。。但是它保证一致性,所有表单组件,验证控件,如TextBox我们只有一套,所有人都去调用这一套,不得再重造,因为它是框架。。。
4.@Widget底层定义:
import java.lang.annotation.Annotation;
public interface Widget
extends Annotation
{
public abstract String value();
public abstract String defaultValue();
public abstract String dataType();
public abstract String dataSource();
}
@Valider类似,当然这些都只是定义、声明,具体怎么用,这里就不贴了,毕竟是人家东西嘛
怎么样,看到这些,似乎觉得Annotation开始起作用了,其实我一直觉得,Annotation就是为xml所生,因为它们俩是死对头,不管单一地用谁,都有缺陷,
只有结合才是完善,正所谓,没有最好,只有更好,合理就行。
在这里我可能没有贴出什么@Annotation技术含量的东西,但是我想要表达的是一种思想,一种框架的思想,并不是什么地方都能用到Annotation,一般的中小型项目根本没必要用它,因为xml就搞定,所以用在需要用的地方,将它的能量发挥到最大。。。
以上仅为一家之言,欢迎拍砖。。。
posted @
2010-08-10 16:47 独孤行 阅读(1699) |
评论 (1) |
编辑 收藏
摘要: 在项目中使用ibatis有一段时间了,之前一直用jdbc、hibernate。自我感觉ibatis是介于jdbc和hibernate之间的非常实用的轻量级框架,相信用过的人都有同感吧。对搞java的来说,上手是非常快的,只要你具备sql基础,再加一点ORM的思想,夏昕的《ibatis开发指南》是不错的选择。
今天项目搞完了,我就把所学的,以及在项目中用到拿来贴一番,也是对我个人技术的总结吧,怎样...
阅读全文
posted @
2010-04-01 11:35 独孤行 阅读(3344) |
评论 (0) |
编辑 收藏
thickbox是jQuery的一个插件,其作用是弹出对话框、网页框,使用户体验度更加愉悦,下面就来简单介绍它的几种用法。
声明一下:这只是个人的总结记载而已。
准备工作:你需要三个文件:thickbox.js、thickbox.css、jquery.js,网上到处可下
具体使用:
第一步:将这三个文件引入到你要使用thickbox的页面
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="thickbox.js"></script>
<link rel="stylesheet" href="thickbox.css" type="text/css" />
第二步:一般简单使用就是给<a>标签和Button添加样式:class=thickbox
还有就是通过thickbox函数调用:如tb_init()、tb_show();见下文。
几种不同用法:
1.点击显示图片:
<a href="001.jpg" class="thickbox"><img src="001.jpg"/></a>
ok,就这样搞定
2.点击按钮或链接:
<input alt="#TB_inline?height=300&width=400&inlineId=div1" title="shawnliu" class="thickbox" type="button" value="Show" />
<a href="#TB_inline?height=155&width=300&inlineId=div2&modal=true" class="thickbox">Show hidden modal content.</a>
<div id="div1" style="display:none">
<P>
这是一个非模式对话框。
</P>
</div>
<div id="div2" style="display:none">
<P>
这是一个模式对话框。
<p style="TEXT-ALIGN: center"><INPUT id="Login" onclick="tb_remove()" type="submit" value=" Ok " /></p>
</P>
</div>
说明:给你要使用thickbox的<a>或button添加"#TB_inline?height=300&width=400&",#TB_inline是thickbox固定用法,height和width是显示弹出对话框的大小参数,
inlineId是你要显示的标签或组件,modal是模式与非模式的选择,当然你还可以接很多你自定义的参数
3.一般在项目中用得比较多的就是加载form的页面,如添加,编辑在同一个list列表页面,这时我们就可以将添加和编辑都做成thickbox形式,如下图:
怎样做呢一样的,给添加链接加thickbox样式:
<a href="add.shtml?width=300&height=250" class="thickbox">新增</a>
前提是你得将要显示的页面(add.shtml)做好,然后指定你要显示的大小
编辑同样是一样:先将原信息提取出来,再让用户修改:
代码也一样:
<a href="edit.shtml?width=300&height=250&nid=item.nid" class="thickbox">编辑</a>
4.能自己定位到需要用thickbox的元素,不使用样式,可以用函数,如:
<div id="PicList">
<a href="Pic01.jpg"><img src="Pic01s.jpg" border="0"/></a>
<a href="Pic02.jpg"><img src="Pic01s.jpg" border="0"/></a>
</div>
$(function() {
tb_init("#PicList a[img]");});
5.通过ajax加载的页面,thickbox样式会失效,解决办法:
只要在AJAX载入HTML并更新到页面后执行下以下代码:
tb_init('.thickbox');
6.自定义函数调用:
如点击缩图,要显示大图,缩略图URL只不过在大图URL的后缀前加了s:
<div id="PicList">
<img src="Pic01s.jpg" border="0"/>
<img src="Pic01s.jpg" border="0"/>
</div>
$(function() {
$("#PicList img").click(function() {
tb_show("",this.src.substring(0,this.src.length-5)+'.jpg',false);
});});
另外,如果想用其它事件,还可以将click改成你想触发thickbox的事件。
下班勒,大概记录到这,以后再加吧。。。
posted @
2010-03-26 17:47 独孤行 阅读(4628) |
评论 (2) |
编辑 收藏
在域模型(实体域)中,关联关系是类与类之间最普遍的关系。根据UML语言,关系是有方向的。下面以客户(Customer)和订单(Order)的关系为例,阐述一下ORM的中的一对多映射:
我们知道,在关系数据库中,只存在外键参照关系,而且总是由“many”方参照“one“方。
1.建立多对一单向关联——Order(many)--->Customer(one):
-------------------------------Order.java--------------------------------
pack mypack;
import java.io.Serializable;
public class Order implements Serializable{
private int id;
private String orderNumber;
private Customer customer;
//构造方法及set方法get方法
}
在以上代码中customer属性要使用<many-to-one>来映射:
多对一单向关联(many方)
<many-to-one>
name = "customer" --待映射的持久化类属性名
column = "customer_Id" --数据库外键字段
class = "mypack.Customer" --持久化类
not-null = "true"/>
a. <many-to-one>的not-null属性
not-null属性会影响Hiberntae的运行时行为,Hibernate在保存Order对象时,会先检查它的customer属性是否为null:
若为null:在执行session.save(Order)时会抛出PropertyValueException异常;
原因很简单:既然Customer为null,那么对应的外键Customer_Id也为null,试问外键都没有,Order表的数据能插得进去吗
若将not-null 属性设为false:表示外键引用可以为null,试想一下,数据库数据可以插进去吗?
我们来看:在执行session.save(Order)时,发出了sql语句:insert into......
但是当Hibernate自动清理(flush)缓存时,抛出新的异常:TransientObjectException
所谓清理是提交事务或手动Flush,将session与数据库保持同步,很显然不可能同步嘛,Order对象虽然持久化,但Customer没有.
注:是否应该把<many-to-one>的not-null属性设为true,这根据实际业务而定。通常,订单总是由客户自己发出,因此建议设为true.
b. 级联保存与更新
默认情况下,Hibernate持久化一个对象,不会自动持久化所关联的其它临时对象,因此会有TransientObjectException,
想它关联也可以,<many-to-one>中加个属性cascade="save-update"即可.
2.建立一对多关联——Customer(one)--->Order(many):
-----------------------------Customer.java-------------------------------
package mypack;
import
public calss Customer implements Serlizliab;e{
private int id;
private String name;
private Set orders = new HsahSet();
//构造方法及set方法get方法
}
一对多关联(one方)
<set
name = "orders" --持久化对象的属性
cascade = "save-update" --级联操作
<key cloumn = "customer_Id"/> --外键
<one-to-many class = "mypack.Order"/> --持久化类
</set>
a. <set>元素的inverse属性
在映射一对多的双向关联时,应该在“one”方把inverse属性设为true,这样可提高应用性能。
inverse:控制反转,为true表示反转,由它方负责;反之,不反转,自己负责;
如果不设,one和many两方都要负责控制,因此,会引发重复的sql语句以及重复添加数据,
在建立两个象的双向关系时,应该同时修改关联两端的对象属性:
customer.getOrders().add(order);
order.setCustomer(customer);
这样做可提高业务逻辑的独立性,使业务逻辑的程序代码不受Hibernate实现的影响。同理解除双向关系也一样。
b. 级联删除(从数据库删除相关表记录)
当删除Customer对象时,及联删除Order对象.只需将cascad属性设为delete即可.
注:删除后的对象,依然存在于内存中,只不过由持久化态变为临时态.
c. 父子关系(逻辑删除,只是解除了关联关系)
自动删除不再和Customer对象关联的Order对象.只需将cascade属性设为delete-orphan.
customer.getOrders().remove(order);
order.setCustomer(null);
注:当关联双方都存在父子关系,就可以把父方的cascade属性设为delete-orphan,所谓父子关系,是由父方来控制子方的生命周期.
posted @
2009-10-16 00:29 独孤行 阅读(3329) |
评论 (2) |
编辑 收藏
My97DatePicker是一款非常灵活好用的日期控件,在本次项目中我使用它暴露了很多问题:
首先来说使用步骤:
1.在My97DatePicker主页下载控件,
目前的版本是:4.2 正式版 发布于2008-12-03
http://www.my97.net/dp/down.asp
2.将文件解压包(一个文件都不要删除)拷贝到classpath/webroot下
3.直接使用<script />引入:
<script type="text/javascript" defer="defer" src="<%=request.getContextPath() %>/My97DatePicker/WdatePicker.js"></script>
4.在<input type="text"/>中调用:
<input type="text" name="time" onfocus="WdatePicker()">
其次来说一下我在使用中碰到的问题:
1.IE中 无法打开internet站点 。。。。。已终止操作
这个问题搞了好半天,网上到处查,最后才在csdn上看到解决办法:
a.如果页面有<base/>标签的:则要在第3步js引入后添加<base target="_self" />;
b.在<script/>中添加属性defer="defer"; //就是这具属性救了我
2.在步骤4中调用了,结果不出来:
开始以为是stuts1.2 标签的原因,结果不是,后来反复测试,才搞定了
其实调用的时候有很多方法,然而有的方法不一定出得来,所以要反复测试
这是My97DatePicker的主页:http://www.my97.net
里面有控件下载,使用演示,问题解决等
posted @
2009-05-14 00:28 独孤行 阅读(10450) |
评论 (9) |
编辑 收藏