`
cnoss
  • 浏览: 15568 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

让你的 Ibatis2 也支持Annotation

阅读更多
在支持xml配置方式的基础上增加了对annotation的支持,用户可以根据自己的喜好来选择或者两种方式并存。详情请大家看:http://www.rest4g.org/viewthread.php?tid=12&extra=page%3D1

代码示例如下:
Account.java
package org.jrest4guice.persistence.ibatis;
public class Account {
  private int id;
  private String firstName;
  private String lastName;
  private String emailAddress;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getEmailAddress() {
    return emailAddress;
  }

  public void setEmailAddress(String emailAddress) {
    this.emailAddress = emailAddress;
  }

}
AccountService.java
package org.jrest4guice.persistence.ibatis;
import java.sql.SQLException;
import java.util.List;
import org.jrest4guice.persistence.ibatis.annotations.Delete;
import org.jrest4guice.persistence.ibatis.annotations.IbatisDao;
import org.jrest4guice.persistence.ibatis.annotations.Insert;
import org.jrest4guice.persistence.ibatis.annotations.Result;
import org.jrest4guice.persistence.ibatis.annotations.ResultMap;
import org.jrest4guice.persistence.ibatis.annotations.Select;
import org.jrest4guice.persistence.ibatis.annotations.Update;
import org.jrest4guice.transaction.annotations.Transactional;
import org.jrest4guice.transaction.annotations.TransactionalType;

import com.google.inject.Inject;
import com.ibatis.sqlmap.client.SqlMapClient;

@IbatisDao
@SuppressWarnings("unchecked")
@Transactional
@ResultMap(id = "accountResultMap", result = {
		@Result(property = "id", column = "id"),
		@Result(property = "firstName", column = "firstName"),
		@Result(property = "lastName", column = "lastName"),
		@Result(property = "emailAddress", column = "emailAddress") }, resultClass = Account.class)
@Cachemodel(id = "account-cache", flushInterval = "24", flushOnExecute = {
		"insertAccount", "updateAccount", "deleteAccount" }, type = "LRU", 
		property = { @Property(name = "size", value = "100") })
public class AccountService {
	@Inject
	private SqlMapClient sqlMapper;

	@Select(id = "selectAllAccounts", sql = "select * from ACCOUNT", 
			resltMap = "accountResultMap", cacheModel = "account-cache")
	@Transactional(type = TransactionalType.READOLNY)
	public List<Account> findAll() throws SQLException {
		return sqlMapper.queryForList("selectAllAccounts");
	}

	@Select(sql = "select id ,firstName,lastName,emailAddress from "
			+ "ACCOUNT where id = #id#")
	@Transactional(type = TransactionalType.READOLNY)
	public Account getAccountById(int id) throws SQLException {
		return (Account) sqlMapper.queryForObject("getAccountById", id);
	}

	@Insert(id = "insertAccount", sql = "insert into ACCOUNT (id,firstName,"
			+ "lastName,emailAddress) values (#id#, #firstName#, #lastName#, "
			+ "#emailAddress#)")
	public void createAccount(Account account) throws SQLException {
		sqlMapper.insert("insertAccount", account);
	}

	@Update(sql = "update ACCOUNT set firstName = #firstName#,lastName = "
			+ "#lastName#,emailAddress = #emailAddress# where id = #id#")
	public void updateAccount(Account account) throws SQLException {
		sqlMapper.update("updateAccount", account);
	}

	@Delete(id = "deleteAccount", sql = "delete from ACCOUNT where id = #id#")
	public void deleteAccount(int id) throws SQLException {
		sqlMapper.delete("deleteAccount", id);
	}

	@Select(id = "queryAccounts", 
		sql = "select * from ACCOUNT "
			+ "<dynamic prepend=\"where\">"
			+ " <isNotNull prepend=\"and\" property=\"firstName\">"
			+ "    firstName = #firstName#" 
			+ " </isNotNull>"
			+ " <isNotNull prepend=\"and\" property=\"lastName\">"
			+ "    lastName = #lastName#" 
			+ " </isNotNull>"
			+ " <isNotNull prepend=\"and\" property=\"emailAddress\">"
			+ "    emailAddress = #emailAddress#" 
			+ " </isNotNull>"
			+ "</dynamic> " 
			+ "order by lastName", resltMap = "accountResultMap", 
			cacheModel = "account-cache")
	@Transactional(type = TransactionalType.READOLNY)
	/**
	 * 动态SQL查询
	 */
	public List<Account> queryAccounts(Account account) throws SQLException {
		return sqlMapper.queryForList("queryAccounts",account);
	}
}
AccountServiceTest.java
package org.jrest4guice.persistence.ibatis;

import java.sql.SQLException;
import java.util.List;
import junit.framework.Assert;
import org.jrest4guice.guice.GuiceContext;
import org.jrest4guice.guice.PersistenceGuiceContext;
import org.junit.BeforeClass;
import org.junit.Test;

public class AccountServiceTest {
	private static AccountService service;

	@BeforeClass
	public static void setUp() throws Exception {
		// 初始化JRest4Guice
		PersistenceGuiceContext.getInstance().useIbatis(
				"org.jrest4guice.persistence.ibatis").init();
		// 获取服务
		service = GuiceContext.getInstance().getBean(AccountService.class);
	}

	@Test
	public void doTest() {
		List<Account> accounts;
		try {
			Account account = new Account();
			account.setFirstName("张");
			account.setLastName("学友");
			account.setEmailAddress("jackey@rest4g.org");
			// 添加
			service.createAccount(account);

			account = new Account();
			account.setFirstName("刘");
			account.setLastName("学友");
			account.setEmailAddress("test@rest4g.org");
			// 添加
			service.createAccount(account);
			
			//查询(按lastName)
			Account queryCondition = new Account();
			queryCondition.setLastName("学友");
			accounts = service.queryAccounts(queryCondition);
			Assert.assertEquals(2, accounts.size());
			
			//查询(按firstName和lastName)
			queryCondition.setFirstName("张");
			accounts = service.queryAccounts(queryCondition);
			Assert.assertEquals(1, accounts.size());

			// 修改
			account = accounts.get(0);
			account.setFirstName("何");
			service.updateAccount(account);
			account = service.getAccountById(account.getId());
			Assert.assertNotNull(account);
			Assert.assertEquals("何", account.getFirstName());

			//查询所有
			accounts = service.findAll();
			Assert.assertEquals(2, accounts.size());

			// 删除
			for (Account ac : accounts){
				service.deleteAccount(ac.getId());
			}
			
			//断言删除的结果
			accounts = service.findAll();
			Assert.assertEquals(0, accounts.size());
		} catch (SQLException e) {
			Assert.fail(e.getLocalizedMessage());
		}
	}
}
分享到:
评论
15 楼 cnoss 2008-10-10  
piaoling 写道
感觉完全没有必要,根本不如以前的简洁


简洁,我个人的看法这样做更简洁,更贴近代码,只是像
    @Select(id = "queryAccounts",    
        sql = "select * from ACCOUNT "  
            + "<dynamic prepend=\"where\">"  
            + " <isNotNull prepend=\"and\" property=\"firstName\">"  
            + "    firstName = #firstName#"    
            + " </isNotNull>"  
            + " <isNotNull prepend=\"and\" property=\"lastName\">"  
            + "    lastName = #lastName#"    
            + " </isNotNull>"  
            + " <isNotNull prepend=\"and\" property=\"emailAddress\">"  
            + "    emailAddress = #emailAddress#"    
            + " </isNotNull>"  
            + "</dynamic> "    
            + "order by lastName", resltMap = "accountResultMap",    
            cacheModel = "account-cache")   

这样的写法确实有些“可怕”,不过很好彩,我的这个封装,除了提供对annotation的支持外,也支持原生的xml方式配置,这样你可以将那些“可怕”部分放入xml中。
14 楼 piaoling 2008-10-10  
感觉完全没有必要,根本不如以前的简洁
13 楼 tenderghost 2008-10-10  
Annotation这样用也真够可怕的
12 楼 melin 2008-10-10  
如果没有一个开发平台辅助工具。自己手动去维护这一套查询结果和对象属性之间的映射也很痛苦。特变是项目大了以后
11 楼 leasass 2008-10-10  
留名,我觉得不错,
10 楼 castte 2008-10-10  
哈哈


anyway。。ibatis维护起来都很烦人
9 楼 badqiu 2008-10-10  
引用
Ibatis配置文件中定义的sql语句是可以重用的(通过id来获取)

--------
SQL ID重用那还不如写的dao方法重用。或你要重用完全可以定义一个SQL常量

String DELETE_QUERY = "delete from ACCOUNT where id = #id#"
public void deleteAccount(int id) throws SQLException { 
    sqlMapper.delete(DELETE_QUERY, id);      
}


如果Ibatis提供那么多annotation,还不如增加api方法。只留一个@ResultMap映射annotation就行了。以便查询时使用映射
8 楼 cnoss 2008-10-10  
badqiu 写道
既然如此,Ibatis why not?
    public void deleteAccount(int id) throws SQLException {   
        sqlMapper.delete("delete from ACCOUNT where id = #id#", id);   
    } 

真怀疑Ibatis的作者为啥要提供annotation.



Ibatis配置文件中定义的sql语句是可以重用的(通过id来获取),它可以是其它查询的子查询。但如果写在指定的业务方法里面就实现不了这种共享与引用。

从业务的角度来看,数据的重用不是通过sql共享来实现的,而是通过服务方法来实现,服务之间对sql是透明的,所以你以上的方式也是正确的,但这已经超出的ibatis的定义范围。你的意思呢?
7 楼 badqiu 2008-10-10  
既然如此,Ibatis why not?
    public void deleteAccount(int id) throws SQLException {   
        sqlMapper.delete("delete from ACCOUNT where id = #id#", id);   
    } 

真怀疑Ibatis的作者为啥要提供annotation.
6 楼 cnoss 2008-10-10  
titanfoot 写道
感觉有些画蛇添足,过犹不及阿!哈哈


你的观点很尖锐,但你的方式很真诚,那么spring 2.5为什么也提供了annotation方式,而且未来的ibatis3也会提供对annotation的支持。
5 楼 宏基小键盘 2008-10-10  
等ibatis 3吧。
4 楼 cnoss 2008-10-10  
对于注解与配置文件的使用,我个人的看法是:对于不变的配置项采用注解,而对于可变的或者变化较多的使用xml之类的配置文件。使用注解可以和java代码紧密联系,开发时,很容易修改对象的sql,不用来回切换于java类与xml之间,使用配置文件,可以将可变的元素灵活的管理起来。
以上的实现除了对Ibatis提供了annotation的选择之外,还提供了统一的事务管理实现(通过@ Transactional来声明)
3 楼 titanfoot 2008-10-10  
感觉有些画蛇添足,过犹不及阿!哈哈
2 楼 stworthy 2008-10-10  
看到注解这么使用真觉得很可怕,代码中直接SQL还比它清楚。
1 楼 cats_tiger 2008-10-10  
引用
# @Select(id = "queryAccounts",  
         sql = "select * from ACCOUNT " 
             + "<dynamic prepend=\"where\">" 
             + " <isNotNull prepend=\"and\" property=\"firstName\">" 
             + "    firstName = #firstName#"  
             + " </isNotNull>" 
             + " <isNotNull prepend=\"and\" property=\"lastName\">" 
             + "    lastName = #lastName#"  
             + " </isNotNull>" 
             + " <isNotNull prepend=\"and\" property=\"emailAddress\">" 
             + "    emailAddress = #emailAddress#"  
             + " </isNotNull>" 
             + "</dynamic> "  
             + "order by lastName", resltMap = "accountResultMap",  
             cacheModel = "account-cache") 

东西是好东西,可惜把代码弄的很乱,还不如用XML呢。

相关推荐

    struts2.1 spring2.5 ibatis2.3 dwr3 annotation配置 集成

    struts2.1 spring2.5 ibatis2.3 dwr3 annotation配置 集成 此中例子不完整. 如要下载:http://download.csdn.net/source/2138885

    spring2.5 ibatis2.3 struts2.1 dwr3 annotation集成配置

    本主题聚焦于一个经典的Java企业级应用架构:Spring 2.5、iBatis 2.3、Struts 2.1 和 DWR 3 的整合,以及使用注解(Annotation)进行配置。这四个组件的结合可以构建出一个功能强大、可扩展性好、易于维护的Web应用...

    Spring + Ibatis设置定时任务

    要启用Spring的定时任务,首先需要在Spring配置文件(如`applicationContext.xml`)中添加`&lt;task:annotation-driven/&gt;`元素,这将激活对`@Scheduled`注解的支持。如果需要自定义调度器,可以创建一个实现`Task...

    ibatis生成实体工具

    标题中的“ibatis生成实体工具”指的是一个辅助开发的软件或脚本,它能够自动生成基于iBatis框架的实体类(Entity Beans)和数据库操作的映射文件。iBatis是一个优秀的持久层框架,它将SQL语句与Java代码分离,提供...

    spring+ibatis集成文档

    INSERT INTO ibatis VALUES('2', '2'); ``` ##### 2.2 DAO接口定义 定义一个通用的数据访问层接口`IDAO`,用于处理基本的CRUD操作: ```java package ch10.SpringAndIbatis; import java.util.List; public ...

    spring 集成ibatis

    8. **性能优化**:iBatis 支持动态 SQL,可以根据条件灵活构建 SQL 语句,避免硬编码,提高代码可读性和性能。同时,Spring 提供的缓存机制也可以与 iBatis 结合,提高数据访问效率。 通过以上知识点的整合,我们...

    spring+ibatis声明式事务Demo

    在IT行业中,Spring框架与iBatis(现为MyBatis)是两个广泛使用的开源工具。Spring是一个全面的Java企业级应用开发框架,而iBatis(MyBatis)则是一个优秀的持久层框架,它简化了数据库操作。当我们谈论"spring+...

    spring ibatis 配置(包括事务管理)

    在整合Spring和iBatis框架时,我们需要进行一系列的配置工作,以便于让Spring负责管理iBatis的数据访问层。Spring作为一个强大的IoC(Inversion of Control)和AOP(Aspect Oriented Programming)容器,可以方便地...

    spring_ibatis整合案例

    在IT行业中,Spring框架与iBatis(现为MyBatis)的整合是常见的数据访问层解决方案,尤其在企业级应用开发中极为普遍。Spring是一个全面的Java应用程序框架,提供了依赖注入、AOP(面向切面编程)、MVC(模型-视图-...

    spring+struts+ibatis用到的配置文件模板

    在实际应用中,Spring会作为容器管理Struts2的Action和iBatis的SqlSession,通过配置Spring的`&lt;bean&gt;`来注入Action和SqlSessionFactory。同时,Struts2的配置文件会引用Spring中的Bean来执行Action,iBatis的SQL查询...

    最简单的ibatis

    **Ibatis简介** Ibatis,一个轻量级的Java持久层...这就是Ibatis的基本使用方式,通过它,你可以轻松地管理和执行数据库操作,避免了直接操作JDBC带来的麻烦。Ibatis的简单易用性使其成为Java Web开发中的热门选择。

    简单的iBatis 实例

    2. **配置iBatis**:创建SqlMapConfig.xml文件,配置数据库连接信息,例如数据源、事务管理器等。例如: ```xml ``` 3. **编写Mapper XML 文件**:创建UserMapper.xml,定义SQL...

    ibatis 入门代码

    Ibatis支持动态SQL,可以通过`if`, `where`, `choose`, `when`, `otherwise`等标签实现条件判断,减少SQL拼接的麻烦。 **八、事务管理** Ibatis提供了基于Annotation的事务控制,可以结合Spring的@Transactional...

    ibatis SQL Map PPt

    Ibatis支持两种事务管理方式:手动事务和自动事务。手动事务需要开发者自己调用SqlSession的beginTransaction(), commit()和rollback()方法来控制事务的开始、提交和回滚。自动事务则可以通过配置 DataSource ...

    spring+ibatis

    标题 "spring+ibatis" 暗示了我们要探讨的是如何在Java开发中结合Spring框架与iBATIS(现在称为MyBatis)进行数据访问。Spring是一个全面的企业级应用框架,而MyBatis是一个轻量级的持久层框架,它简化了数据库操作...

    Spring+Ibatis集成开发实例.doc

    insert into ibatis values("2","2"); ``` 接下来,定义DAO(Data Access Object)接口,它是Java中的数据访问层接口,用于封装对数据库的操作。这里我们有一个名为`IDAO`的接口,包含获取列表、按名称或ID获取、...

    spring-mybatis-memcached.zip_Memcached java_annotation_mybatis_m

    因为 mybatis-memcached 不支持 MyBatis2(iBatis),只能用在 MyBatis3 里。但是因为有的项目还跑在 MyBatis2 版本上,所以也做一个例子。 mm-mybatis3-memcached 使用了 mybatis-memcached 。因为 simple-spring-...

    iBATIS SQL Maps

    6. **Transaction Management**:iBATIS支持JDBC和Spring两种事务管理方式,可以根据项目需求选择合适的方式进行配置。 7. **DAO(Data Access Object)接口**:在Java代码中,我们通常会创建一个DAO接口,然后通过...

    ibatis案例详解

    Ibatis 是一个轻量级的持久层框架,它与Java的ORM(对象关系映射)解决方案密切相关。在本文中,我们将深入探讨Ibatis的核心概念、配置以及如何通过一个实际案例来理解其工作原理。 首先,数据库脚本创建了一个名为...

    spring+springmvc+ibatis的整合例子

    在Java Web开发领域,Spring、SpringMVC和iBatis是三个非常重要的框架,它们的组合被称为SSM(Spring、SpringMVC、MyBatis)。SSM框架的整合使用能够帮助开发者实现高效、灵活和可扩展的Web应用程序。下面将详细讲解...

Global site tag (gtag.js) - Google Analytics