很久没有上csdn写文章,因为最近一直在加班,刚好遇到个周五,想放松一下,顺便给我的空间浇点水,以免枯死掉,呵呵~``
spring2.5发布已经有一段时间了,我从rc版就开始在试用,感觉确实做了很多大的改进,基本上spring是我最喜爱的一个开源框架了,因为它确实很好用(^_^有打广告的嫌疑)。
好了,废话不多说了,下面帖一点代码吧,文字描述比较少点,因为加班加的人变懒了,请各位看官见谅。
首先来定义一个hibernate(jpa?)的基于annotation方式的pojo:
/**/
/*
* Account.java
*
* Created on 2007-12-29, ÏÂÎç05:51:47
*/
package
spring.withouttemplate.model;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.io.Serializable;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Id;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* @author icechen
*
*/
@Entity
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
Account
implements
Serializable
...
{
private Long id;
private String name;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
@Id
@GeneratedValue
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Long getId() ...{
return id;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void setId(Long id) ...{
this.id = id;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public String getName() ...{
return name;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void setName(String name) ...{
this.name = name;
}
}
然后定义一个操作数据库的interface:
/**/
/*
* AccountRepository.java
*
* Created on 2007-12-29, 下午05:52:56
*/
package
spring.withouttemplate.dao;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
spring.withouttemplate.model.Account;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* @author icechen
*
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
interface
AccountRepository
...
{
public Account loadAccount(String username);
public Account save(Account account);
}
接下来是该接口的spring实现,也是基于annotation方式,而且不再使用hibernatetamplate,也就不需要继承spring的特定类,真正做到零侵入:
/**/
/*
* HibernateAccountRepository.java
*
* Created on 2007-12-29, 下午05:53:34
*/
package
spring.withouttemplate.dao;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.hibernate.SessionFactory;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.stereotype.Repository;
import
org.springframework.stereotype.Service;
import
org.springframework.transaction.annotation.Propagation;
import
org.springframework.transaction.annotation.Transactional;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
spring.withouttemplate.model.Account;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* 设计一个非侵入式的spring bean,不再继承spring的api来实现,而直接操作hibernate的session
*
* @author icechen
*
*/
//
这个声明相当重要,spring必须对操作数据库的bean声明事务,否则就无法绑定hibernate的session
//
通常情况下,声明为“只读”模式会对sql进行优化,所以这里默认声明为true
//
但是“写”操作必须覆盖声明为“false”
@Service(
"
demo
"
)
@Transactional(readOnly
=
true
)
@Repository
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
HibernateAccountRepository
implements
AccountRepository
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
private SessionFactory factory;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// public HibernateAccountRepository(SessionFactory factory) {
// this.factory = factory;
// }
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 此声明对不写数据库的操作,根据spring的默认机制来决定是true或者false,否则跟全局声明保持一致
@Transactional(propagation = Propagation.SUPPORTS)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Account loadAccount(String username) ...{
return (Account) factory.getCurrentSession().createQuery("from Account acc where acc.name = :name").setParameter("name", username)
.uniqueResult();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 数据库的写操作,必须声明为false,否则无法将数据写如数据库
@Transactional(readOnly = false)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Account save(Account account) ...{
factory.getCurrentSession().saveOrUpdate(account);
return account;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
@Autowired(required = true)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void setFactory(SessionFactory factory) ...{
this.factory = factory;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
最后写个类来测试这段程序是否正常工作:
/**/
/*
* SpringDemo.java
*
* Created on 2007-12-29, 下午06:10:10
*/
package
spring.withouttemplate.dao;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.util.ArrayList;
import
java.util.Collection;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
spring.withouttemplate.model.Account;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* @author icechen
*
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
SpringDemo
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* @param args
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void main(String[] args) ...{
Collection<String> files = new ArrayList<String> ();
files.add("etc/beans.xml");
files.add("etc/dataAccessContext-local.xml");
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(files.toArray(new String[0]));
AccountRepository demo = (AccountRepository) ctx.getBean("demo");
Account account = demo.loadAccount("icechen");
System.out.println(account.getId());
Account newAccount = new Account();
newAccount.setName("jay");
newAccount = demo.save(newAccount);
System.out.println(newAccount.getId());
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
别忙,还有重要的事没有做,我们还需要少许配置(虽然使用了annotation方式,但是不等于不需要配置):
最后一段测试程序中两个xml:
beans.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<
beans
xmlns
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context
="http://www.springframework.org/schema/context"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>
<
context:annotation-config
/>
<
context:component-scan
base-package
="*"
/>
<!--
<bean id="accountRepo"
class="spring.withouttemplate.dao.HibernateAccountRepository">
<constructor-arg ref="sessionFactory" />
</bean>
-->
</
beans
>
dataAccessContext-local.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<
beans
xmlns
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<!--
========================= GENERAL DEFINITIONS =========================
-->
<!--
Configurer that replaces ${...} placeholders with values from properties files
-->
<!--
(in this case, mail and JDBC related properties)
-->
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
id
="propertyConfigurer"
class
="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
>
<
property
name
="locations"
>
<
list
>
<
value
>
etc/jdbc.properties
</
value
>
</
list
>
</
property
>
</
bean
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
id
="dataSource"
class
="org.apache.commons.dbcp.BasicDataSource"
destroy-method
="close"
>
<
property
name
="driverClassName"
>
<
value
>
${jdbc.driverClassName}
</
value
>
</
property
>
<
property
name
="url"
>
<
value
>
${jdbc.url}
</
value
>
</
property
>
<
property
name
="username"
>
<
value
>
${jdbc.username}
</
value
>
</
property
>
<
property
name
="password"
>
<
value
>
${jdbc.password}
</
value
>
</
property
>
</
bean
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<!--
Hibernate SessionFactory
-->
<
bean
id
="sessionFactory"
class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
>
<
property
name
="dataSource"
>
<
ref
local
="dataSource"
/>
</
property
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="configurationClass"
value
="org.hibernate.cfg.AnnotationConfiguration"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="configLocation"
>
<
value
>
classpath:hibernate.cfg.xml
</
value
>
</
property
>
</
bean
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
id
="transactionManager"
class
="org.springframework.orm.hibernate3.HibernateTransactionManager"
>
<
property
name
="sessionFactory"
ref
="sessionFactory"
/>
</
bean
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
class
="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
class
="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"
>
<
property
name
="transactionInterceptor"
>
<
ref
bean
="transactionInterceptor"
/>
</
property
>
</
bean
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
id
="transactionInterceptor"
class
="org.springframework.transaction.interceptor.TransactionInterceptor"
>
<
property
name
="transactionManager"
>
<
ref
bean
="transactionManager"
/>
</
property
>
<
property
name
="transactionAttributeSource"
>
<
bean
class
="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"
/>
</
property
>
</
bean
>
</
beans
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
最后当然还需要hibernate.cfg.xml:
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>
<
hibernate-configuration
>
<
session-factory
>
<!--
show sql
-->
<
property
name
="show_sql"
>
true
</
property
>
<
property
name
="format_sql"
>
true
</
property
>
<!--
mapping class
-->
<
mapping
class
="spring.withouttemplate.model.Account"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
session-factory
>
</
hibernate-configuration
>
好了,代码基本上帖完了,简单吧???是不是开始觉得annotation的优美之处了?那还不赶快去试用~```
呵呵,全文完。。。或未完待续。。。
文中代码:http://download.csdn.net/source/335193
Java
咖啡群欢迎大家加入
(
加群者送分
,
顶帖者也送分哈
),
群号
:60446231
本群以讨论
IT
行业话题为主
,
本着交流信息的原则
,
为大家营造一个轻松欢娱的环境
,
给平时枯燥的工作增添一些调味剂
.
当然
,
技术问题同样在讨论范围之中
.
本人在这里欢迎大家的到来
,
并预祝大家五一快乐
.(
鼓掌
...
谢谢
...
嘿嘿
...)
Java
基础群
:49827836
为
java
初学者提供帮助,在讨论及解决问题中共同成长。