2010年2月22日星期一

GAE(Google App Engine) 对 struts Spring 等的支持情况

完整描述见这里:(要fuckgfw)
http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine

Spring MVC
Version: 2.5.6
Status: COMPATIBLE
To see Spring's MVC framework running on App Engine, check out the autoshoppe sample application.
If you're using Spring forms (e.g. using the spring-form.tld tag library and subclassing SimpleFormController), you will need to register custom editors for your properties. This is covered in http://groups.google.com/group/google-appengine-java/browse_thread/thread/d93fd7385bf85bf7.

Spring ORM
Version: 2.5.6
Status: COMPATIBLE
To get Spring working with the App Engine-provided JPA interface, follow the instructions at http://objectuser.wordpress.com/2009/05/19/spring-jpa-in-google-app-engine/, which discusses a workaround to the dependency on javax.naming needed for @PersistenceContext. A more complex workaround is available at http://groups.google.com/group/google-appengine-java/browse_thread/thread/187d41712ec1d394.

Spring Security
Version(s): ?
Status: SEMI-COMPATIBLE
To work around a ClassNotFoundException, you can use a re-compiled version of the library which adds a StringInsensitiveComparator class -- the download is provided at http://www.google-app-engine.com/blog/post/Spring-security-fix-for-google-app-engine.aspx.
See http://www.dotnetguru2.org/bmarchesson/index.php?p=1100 for tips on how to get Spring Security running with App Engine and GWT (in French).

Stripes Framework
Version(s): ?
Status: COMPATIBLE
The default multipartwrapper implementation needs a temporary directory on the local file system for file uploads, which App Engine doesn't allow. The workaround is to create your own implementation -- more details at http://groups.google.com/group/google-appengine-java/browse_thread/thread/81dbcf7cf2281014.

Struts 1
Version: 1.2.28
Status: COMPATIBLE

Struts 2
Version(s): ?
Status: COMPATIBLE (see notes)
Struts will not initially work because the OGNL permissions which the framework relies on can't be set due to security restrictions in App Engine's sandbox. However, some users have documented a workaround at http://groups.google.com/group/google-appengine-java/browse_thread/thread/19018b0317f27817.
A tutorial on uploading files using Struts running on App Engine is available at http://whyjava.wordpress.com/2009/10/04/file-upload-on-google-app-engine-using-struts2/.
Will need to set devMode to false in struts.xml: <constant name="struts.devMode" value="false" />


这个人的博客上也描述了如何使用 Struts 2 with App Engine:

还有这个博客,关于GAE、Spring、JPA、JDO 内容非常丰富:(要fuckgfw)

  • Spring + JDO in Google App Engine
  • 17 Minute JDO!
  • Spring + JPA in Google App Engine
  • More on Spring Security in Google App Engine
  • Spring Security in Google App Engine
  • Google App Engine Testing with Spring
  • Queries in GAE: One to Many Relationships
  • Google App Engine
  • Queries in GAE: Many to Many Relationships
  • Queries in GAE: One to One Relationships

Spring + JPA in Google App Engine


I've been playing around with Google App Engine because it's new and cool and has some interesting possibilities. However, it's in a preview mode currently and has some limitations, as expected.

One difficulty I encountered was getting Spring (2.5.6) to work nicely with the App Engine-provided JPA. But now I have it working. Here's how.

The basic problem is that PersistenceAnnotationBeanPostProcessor has a dependency on javax.naming. But that's the thing you need to get @PersistenceContext to work. And you want that to work because you want to be able to have transactions that span DAOs (or, at least, I wanted that).

That dependency is easy to resolve, however. Just grab the source to PersistenceAnnotationBeanPostProcessor, put it in your own package, and replace the catch blocks with NamingException with just Exception … you won't be using those things anyway.

Now, use that bean in your context configuration file.
<bean id="persistienceAnnotationBeanPostProcessor"
class="your.package.name.PersistenceAnnotationBeanPostProcessor" />

Finally, use the @PersistenceContext annotation in your DAO just like it says in the Spring documentation:
@PersistenceContext
private EntityManager entityManager;

You're done. Thank me.

Update 5/25: As Alex points out I spelled the bean ID incorrectly. However, that was right from my code, so the id doesn't really matter. In fact, now I have:
<bean class="your.package.name.PersistenceAnnotationBeanPostProcessor" />

2010年2月5日星期五

Oralce游标定义、游标变量、游标循环的实际例子


--给销售订单加上行号
--同一个单据号(djh)之内,行号(rowno)按照10的步长来编号
--新单据号,行号要重新从10开始
declare
--本例子演示了Oralce游标定义、Oracle游标变量、Oracle游标循环
--以及在游标里面更新数据库的技巧
cursor cc is select nno,djh,rowno
from temp_so order by nno;
--定义游标变量
ccrec cc%rowtype;
--定义自己的变量
irowno number;
idjh varchar2(50);
begin
--打开游标
open cc;
--提取一行数据到ccrec中
fetch cc into ccrec;
--判断是否提取到值,没取到值就退出
--取到值cc%notfound 是false
--取不到值cc%notfound 是true
idjh := ccrec.djh;
irowno:=10;
loop --loop循环
--exit when (cc%notfound or cc%rowcount =300);
exit when (cc%notfound);

if (idjh = ccrec.djh) then
update temp_so set temp_so.rowno = irowno where temp_so.nno = ccrec.nno;
--dbms_output.put_line(cc%rowcount||' '||ccrec.djh||' '||idjh||' '||irowno);
else
irowno:=10;
idjh := ccrec.djh;
update temp_so set temp_so.rowno = irowno where temp_so.nno = ccrec.nno;
-- dbms_output.put_line(cc%rowcount||' '||ccrec.djh||' '||idjh||' '||irowno);
end if;
fetch cc into ccrec;
irowno:=irowno+10;
end loop;
close cc;
commit;
end;


-------------------
A Contre Courant