论道WP(三):应用程序栏
作者通过具体翔实的例子介绍了Winodws Phone 7中应用程序栏的使用方式。
该内容已经被标记书签!
标记书签错误,请重试!

作者 Oliver Gierke 译者 池建强 发布于 2011年2月7日
几乎每个应用系统都需要通过访问数据来完成工作。要想使用领域设计方法,你就需要为实体类定义和构建资源库来实现领域对象的持久化。目前开发人员经常使用JPA来实现持久化库。JPA让持久化变得非常容易,但是仍然需要编写很多模板代码。Hades是一个开源库,基于JPA和Spring构建,通过减少开发工作量显著的改进了数据访问层的实现。本文是Hades的向导性教程,会带你走进Hades的世界,帮助你了解Hades在数据持久化方面能为你做些什么,并简要介绍了最新的2.0版本的新特性。
Hades的核心部分由通用的持久化库实现构成,不仅提供了基本的CRUD(增删改读)方法,而且增加了一些通用场景功能的实现,类似分页这样的功能你就不用自己实现了。还包括查询实体页、动态增加排序定义等能力。
查询是使用最多的数据访问操作,如果你了解了Hades,就会意识到查询作为Hades的核心功能之一,定义和执行查询是多么容易,大大减少了工作量。一般完成一个查询操作包括以下三个步骤:
首先你需要声明一个继承了GenericDao<Entity, Id>的接口,该类保证在Hades接口中定义的CRUD方法在你的接口中是有效的,如下:
public interface UserRepository extends GenericDao<User, Long> { … }
其次是根据业务需求为你的接口增加查询方法:
List findByUsername(String username);
这又会引出问题,那就是如何实现查询方法。如果你没有增加任何附加的元数据,Hades会尝试查找格式为{entity}. {method-name}的JPA查询方法,如果有效的话就使用该方法。如果没有找到任何可以解析的方法名,那就会创建一个查询方法。因此,之前的例子就会产生这样一样查询:select u from User u where u.username=?。查询解析支持更多的关键字,你可以随时在参考手册文档中找到它们。
如果想定义手工查询,你可以使用Hades的@Query注释功能,让该查询直接在方法中执行:
@Query("select from User u where u.lastname = ?");
List someReallyStrangeName(String lastname);
这样你可以自由的进行方法命名,既可以对查询定义实现完全控制,又不必担心那些查询模板代码。围绕着执行查询还有很多方式,例如使用分页查询、执行编辑查询等。
到目前为止我们已经讨论了如何创建带有查询方法的库接口,接下来我们看一下如何使用这些接口。首先创建实体类的实例,然后根据该实例创建GenericDaoFactory的实例,通过工厂实例的getDao方法创建你需要的资源库,如下代码所示:
EntityManager em = … // Get access to EntityManager GenericDaoFactory factory = GenericDaoFactory.create(em); UserRepository userRepository = factory.getDao(UserRepository.class);
由于资源库经常通过依赖注入的方式被其客户端持有,所以Hades提供了优雅的方式与与Spring应用集成。在Spring的应用中引导Hades非常简单,只需使用Hades的命名空间,并声明可以被匹配到的基础包即可:
<hades:dao-config base-package="com.acme.*.repository" />
以上配置方式会选中所有继承了GenericDao的资源库接口,并为每个接口创建Spring的Bean。当然,命名空间支持更细粒度的配置,以实现精确控制。Hades的Eclipse插件实现了与Spring IDE和SpringSource工具套件的无缝集成,这样你就可以从其它Bean引用Hades的资源库,并在你的工作空间把它们标记为Spring的Bean。想了解详细信息请查看其参考手册。
在系统中记录实体类的创建者、修改者和相关日期等信息是一个很常见的需求。Hades提供了监听器EntityListener,可以帮你透明的实现这些功能。要启用Hades的审计功能,只需要在orm.xml文件中定义AuditingEntityListener即可:
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="org.synyx.hades.domain.auditing.support.AuditingEntityListener" />
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
并在Spring的配置中启动审计功能,如下:
<hades:auditing auditor-aware-ref="auditorAware" />
auditorAware是引用的Spring Bean,需要实现AuditorAware接口,通常是实现针对当前用户的安全查询功能。如果你只想跟踪创建和编辑日期,只需忽略该属性即可。想了解更多审计特性,请参考相关文档。
Hades2.0 是基于JPA2.0以及相关的Hibernate、EclipseLink和OpenJPA版本构建的。基于该版本的CRUD事务操作使用非常简单,开箱即用,对于相对简单的场景基本不需要再进行事务性的封装。未来结合资源库接口可以让事务管理变得更加简单。
public interface UserRepository extends GenericDao<User, Long> {
@Transactional(readOnly = true);
List<User> findByUsername();
@Override
@Transactional(readOnly = true, timeout = 60);
List<User> readAll();
}
正如你看到的,你可以简单的通过为查询方法增加注释@Transactional的方式把它们加入事务。当然,也可以不用注释的方式,基于XML的事务配置也能运行的很好。在GenericDao中的CRUD操作具备默认的事务性(对只读操作来说就是把readOnly设置为true)。如果你想为这些方法重新配置事务,简单的为这些方法声明自定义的@Transactional即可实现。想了解更多详细信息,请参考事务相关的参考文档。
Hades 最新版本的一个非常酷的特性是基于GenericDao的扩展即可符合规范。这里提到的规范指领域驱动设计的概念,DDD是由Eric Evans和Martin Fowler首次提出,从本质上捕捉实体的业务规则的一种开发方法。Hades提供的抽象方式可以很容易的基于JPA2.0的标准API实现领域驱动设计。在这里我们假设你已经读过上面提到的两位作者写的DDD相关的书籍。Hades提供了如下方式定义规范:
class BookSpecifications {
public Specification<Book> hasAuthorWithFirstnameLike(final String firstname) {
return new Specification<Book>() {
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
return cb.like(root.join("author").get("firstname"), firstname);
}
}
}
public Specification<Book> hasGenre(final Genre genre) {
return new Specification<Book>() {
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
return cb.equal(root.get( "genre"), genre);
}
}
}
}
当然,这并不是最优雅的代码片段(如果未来与Java 8里的单抽象方法(SAM)特性结果结合的话,效果会更好)。从积极的方面考虑,我们在资源库层面获得了执行规范的可能性:
bookRepository.readAll(hasAuthorWithFirstnameLike("Oliv*"));
好了,我们在声明式查询方面已经做了很多,不是吗?规范的能力真正闪光的时候是把它们整合为新的规范的时候。Hades提供了规范助手类,可以进行任意的合并:
bookRepository.readAll(where(hasAuthorWithFirstnameLike( "Oliv*").or(hasGenre(Genres.IT)));
通过这种方式,扩展资源库就变成了只是增加新的规范。少量的规范就可以帮助你使用类似DSL的柔性API查询资源库,而不是针对每次外部查询请求都使用查询方法访问资源库。想了解更多详细信息,请参考相关文档。
2.0 版本的另一部分内容是扩展模块,可以实现Hades与展现层技术框架(例如Spring的MVC)的无缝集成。它提供了属性编辑器和Spring 3.0转换器,可以透明的把实体类与MVC控制器方法的绑定在一起,同时MVC扩展还可以动态的从HTTP请求中提取分页信息。一个展示用户列表的页面,在控制层的写法就是这样:
@Controllerclass UserController {
@Autowired
UserRepository userRepository;
@RequestMapping("/users")
public void showUsers(Pageable pageable, Model model) {
model.addAttribute("users", userRepository.readAll(pageable));
}
@RequestMapping("/users/{id}")
public String showUser(@PathVariable("id") User user, Model model) {
model.addAttribute("user", user);
return"user";
}
}
就像你看到的,showUsers方法不需要解析HttpServletRequest获取分页信息。另外请注意,在showUser(...)方法中绑定的id路径变量的参数已经是实体类了。由于Spring MVC基础框架的配置内容已经超出了本文要讨论的范围,如果想了解更多信息,请参考扩展模块配置信息的相关章节,其中提供了非常容易的设置样例。
展望未来,2.1.x版本之后,Hades可能会成为Spring Data项目的一部分,其核心将作为实现其它数据存储资源库的实现基础。Spring Data是SpringSource的项目,其目标是为新兴的数据库、特定的数据存储提供Spring的方言支持,包括NoSQL数据库。
Hades 大大简化了使用JPA执行数据层的访问过程。你可以自由的进行精确的CRUD操作、执行查询和规范等。Hades既可以独立使用,可以方便的集成到 Spring中。除此之外,Eclipse的插件Spring IDE/STS和附加的Spring Roo 都可以非常容易的创建资源库。想了解更多信息,请参考项目网站。
关于作者
Oliver Gierke是VMware公司的SpringSource部门的高级顾问,是Hades开源项目的项目主管。大约在两年前他在原公司Synyx启动了该项目。
查看英文原文: Hades - JPA Repositories Done Right
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中 与我们的编辑和其他读者朋友交流。
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中对于锁的性能优化,以及锁的存储结构及升级过程。
本次分享将首先介绍现代富文本编辑器的组成和实现,然后结合UEditor的开发过程,与参会者分享UEditor在设计和实现的过程中,所涉及到的核心功能的细节实现。
本次演讲视频录制于百度技术沙龙。
我们所开发的应用程序大多都需要提供一个图形用户界面(GUI)。关于GUI应用的架构设计,已经有了Form & Control、MVC,、MVP、 Passive View等多种模式。模式可以帮助我们建立优雅的架构,但前提是弄清楚模式的应用场景。弄清楚GUI应用面临的设计上的问题,有助于我们正确的挑选设计方案。
MongoDB是一种非常易用的NoSQL方案,Brian C. Dilley在这篇文章里介绍了MongoDB的优劣势,并介绍了MJORM项目。MJORM用于MongoDB,是一个没有注解的Java ORM库。
随着网络基础设施的逐步成熟,从RPC进化到Web Service,并在业界开始普遍推行SOA,再到后来的RESTful平台以及云计算中的PaaS与SaaS概念的推广,分布式架构在企业应用中开始呈现出不同的风貌,然而殊途同归,这些分布式架构的目标仍然是希望回到建造巴别塔的时代,系统之间的交流不再为不同语言与平台的隔阂而产生障碍。
精益软件开发方法因其对市场和交付的重视和在各种场景下体现出的适应能力正在获得广泛的关注。特别是在精益创业(Lean Startup)渐渐兴起和技术日新月异的今天,其"极端"的思想也变得越来越必要和可行。 InfoQ就此主题对他做了深入的采访。
7 条回复
关注此讨论 回复