还需要编写DAO代码吗?SQL+接口就足够了!

标准的Java DAO写法:

  1. 定义DAO接口;
  2. 编写DAO实现类;
  3. 在实现类中编写JDBC代码。

写JDBC代码非常枯燥而且容易出错,因此,增强的DAO可以用类似Spring的JdbcTemplate简化JDBC代码,不过仍然需要大量的ConnectionCallback,PreparedStatementCallbac等。

如果仅定义DAO接口,并利用Java 5 Annotation写好SQL语句,其余的工作全部由底层框架完成:

  • 自动将接口方法的参数绑定到SQL的参数;
  • 自动将ResultSet映射到Object;
  • ...

现在,利用Express Persistence,完全可以实现!

让我们用Express Persistence实现一个完整的DAO:

假定数据库表User包含字段如下:

id varchar(32) primary key,
name varchar(50) not null,
gender bit not null,
age int not null.

并且定义好JavaBean TestUser:

public class TestUser {

  private String id;

  private String name;

  private boolean gender;

  private int age;

  // getters and setters here...

}

现在,我们就可以定义TestUserDao接口了:

public interface TestUserDao {

    @Unique
    @MappedBy(TestUserRowMapper.class)
    @Query("select * from User u where u.id=:id")
    TestUser queryById(@Param("id") String id);

    @MappedBy(TestUserRowMapper.class)
    @Query("select * from User u order by u.id")
    List<TestUser> queryAll();

    @MappedBy(TestUserRowMapper.class)
    @Query("select * from User u order by u.id")
    List<TestUser> queryFrom(@FirstResult int first);

    @MappedBy(TestUserRowMapper.class)
    @Query("select * from User u order by u.id")
    List<TestUser> queryMax(@MaxResults int max);

    @MappedBy(TestUserRowMapper.class)
    @Query("select * from User u order by u.id")
    List<TestUser> queryRange(@FirstResult int first, @MaxResults int max);

    @Update("insert into User(id, name, gender, age) values(:id, :name, :gender, :age)")
    void createUser(@Param("id") String id, @Param("name") String name, @Param("gender") boolean gender, @Param("age") int age);

    @Update("update User set name=:name where id=:id")
    int updateUserName(@Param("id") String id, @Param("name") String name);

    @Update("delete from User where id=:id")
    int deleteUser(@Param("id") String id);
}

注意到@Query和@Update,SQL语句直接写在里面。为了让SQL参数和方法参数绑定,必须使用:xxx标记SQL参数,并为方法参数标记对应的@Param("xxx")。(有点麻烦,难道不能直接通过方法参数名字绑定?哈哈,编译后的.class就只有类型没有名字了)

例如,更新UserName的SQL语句:

update User set name=:name where id=:id

对应的绑定参数是:name和:id,因此方法参数要这么写:

int updateUserName(@Param("id") String id, @Param("name") String name);

没有实现类?没错,不需要实现类,我们就可以直接使用:

public static void main(String[] args) throws Exception {
    // get data source from somewhere:
    DataSource dataSource = ...
    // create TransactionManager and DAOFactory:
    JdbcTransactionManager txManager = new JdbcTransactionManager(dataSource);
    JdbcDaoFactory daoFactory = new JdbcDaoFactory(new HSQLDBDialect());
    // now create DAO:
    TestUserDao dao = daoFactory.createDao(TestUserDao.class, txManager);
    // ok, now we can do CRUD by DAO now, but need transaction support:
    Transaction tx = txManager.beginTransaction();
    try {
        // create 10 user:
        for (int i=0; i<10; i++)
            dao.createUser("123456789012345678901234567890f" + i, "name-" + i, true, 20 + i);
        // query users with offset and limit:
        List<TestUser> users = dao.queryRange(3, 5);
        // print user name, the output should be:
        // name-3
        // name-4
        // name-5
        // name-6
        // name-7
        for (TestUser user : users)
            System.out.println(user.getName());
        // delete user with name 'name-3':
        int n = dao.deleteUser(users.get(0).getId());
        System.out.println(n + " user deleted.");
        tx.commit();
    }
    catch(Exception e) {
        if (! tx.isRollbackOnly())
            tx.rollback();
    }
    catch(Error e) {
        if (! tx.isRollbackOnly())
            tx.rollback();
    }
}

 

核心代码:

TestUserDao dao = daoFactory.createDao(TestUserDao.class, txManager);

通过DaoFactory,我们得到一个实现了TestUserDao接口的实例,通过该实例,直接操作数据库!

时间: 2024-10-30 03:39:52

还需要编写DAO代码吗?SQL+接口就足够了!的相关文章

link编写的代码如何使用尾递归?为什么尾递归还会堆栈溢出?

问题描述 link编写的代码如何使用尾递归?为什么尾递归还会堆栈溢出? link编写的代码如何使用尾递归?为什么尾递归还会堆栈溢出? 解决方案 检查下你的代码真的是尾递归的么?你可以在递归深处抛出一个异常,看堆栈. 解决方案二: 是你死死循环了吧,先找自己问题

编写PHP代码总结

  1- 编写模块化代码  良好的PHP代码应该是模块化代码.PHP的面向对象的编程功能是一些特别强大的工 具,可以把你的应用程序分解成函数或方法.你应该尽可能多的从你的应用程序的服务器端分开前端的HTML/CSS/JavaScript代码.你也可以在 任何PHP框架上遵循MVC(模型-视图-控制器)模式.  2- 代码编写规范 良好的PHP代码应该有一套完整的代码编写规范.通过对变量和函数的命名,统一的方法访问数据库和对错误的处理,以及同样的代码缩进方式等来达到编程规范,这样可以使你的代码更具

【框架】[MyBatis]DAO层只写接口,不用写实现类

转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] 团队开发一个项目,由老大架了一个框架,遇到了DAO层不用写接口了,我也是用了2次才记住这个事的,因为自己一直都是习惯于写DAO层的实现类,所以,习惯性的还是写了个实现类.于是遇到错误了. 找不到那个方法.问了团队的人才知道,方法名和Mapper中配置的id名必须一样. 实现: 一.配置Spring集成MyBatis: <beans xmlns="http://www.spri

如何编写更好的SQL查询:终极指南-第一部分

结构化查询语言(SQL)是数据挖掘分析行业不可或缺的一项技能,总的来说,学习这个技能是比较容易的.对于SQL来说,编写查询语句只是第一步,确保查询语句高效并且适合于你的数据库操作工作,才是最重要的.这个教程将会提供给你一些步骤,来评估你的查询语句. 首先,应该了解学习SQL对于数据挖掘分析这个工作的重要性; 接下来,应该学习SQL查询语句的处理和执行过程,以便可以更好的了解到,编写高质量的查询有多重要.具体说来就是,应该了解查询语句是如何被解析.重写.优化和最终评估的; 掌握了上面一点之后,你不

如何编写更好的SQL查询:终极指南-第二部分

上一篇文章中,我们学习了 SQL 查询是如何执行的以及在编写 SQL 查询语句时需要注意的地方. 下面,我进一步学习查询方法以及查询优化.   基于集合和程序的方法进行查询 反向模型中隐含的事实是,建立查询时基于集合和程序的方法之间存在着不同. 查询的程序方法是一种非常类似于编程的方法:你告诉系统需要做些什么以及如何做.例如上一篇文章中的示例,通过执行一个函数然后调用另一个函数来查询数据库,或者使用包含循环.条件和用户定义函数(UDF)的逻辑方式来获得最终查询结果.你会发现通过这种方式,一直在请

高效编写CSS代码:WEBJX分享15个CSS开发工具

文章简介:对于Web开发人员来说,好用的CSS工具可以让那些枯燥的工作变得有趣,并且还可以帮你更高效的编写CSS代码,在这里向大家推荐15个必不可少的CSS开发工具和应用. 对于Web开发人员来说,好用的CSS工具可以让那些枯燥的工作变得有趣,并且还可以帮你更高效的编写CSS代码,在这里向大家推荐15个必不可少的CSS开发工具和应用. 1. CSS Desk : An online CSS Sandbox 这是一个支持即时预览的在线CSS编辑工具,无需安装任何形式的插件或是软件,就能在线编辑CS

优质编写网页代码 有利于搜索引擎

网页代码的编写是否简洁和具有逻辑性也是评估搜索引擎优化工作的一个重要指标.       一.遵循WEB标准       建议广大网页设计师遵循国际互联网标准组织(W3C)所推荐的WEB标准来编写网页源码,而不是继续沿用传统的TABLE表格布局方式来制作网页.       Web标准是一些规范的集合,是由W3C和其他的标准化组织共同制定的,用它来创建和解释网页的基本内容.这些规范是专门为了那些在网上发布的可向后兼容的文档所设计的,使其能够被大多数人所访问.       遵循WEB标准来编写网页,可

PHP实例说明编写PHP代码的5个好习惯

5个PHP编程的好习惯 有些人问,优秀程序员和大牛有什么区别,大概有10到20种吧.因为大牛有很好的编程习惯和丰富的经验,所以他们非常的高效.如果不好的编程习惯出现在你的代码里,你的代码效率就会降低.本文阐述一些好的编程习惯,他们可以让你成为更好的程序员. 这些习惯能让你的代码在高效运行的同时提高可维护性.你写代码的时候,可能大部分时间都浪费在维护上了,程序的维护代价很高.培养良好的编程习惯,如模块化设计,可以让你的代码可读性更好,从而容易维护. 代码中的问题往往伴随着不良的编程习惯,而且后者会

在.NET下编写中文代码程序

程序|中文 在.NET下编写中文代码程序 郑佐2005-3-9 一年前,有一次在用Access数据库编程的时候,通过VS.NET数据设计器向导生成数据层代码,查看生成的代码,发现有许多中文,原来数据库中的表名和字段名用的就是中文,程序正常运行,查看相关文档才知道原来VS.NET默认的编码是UTF-8.不久前在一篇blog上看到讲易语言,所以干脆用VS.NET写一些中文代码来玩一下,结果就像平常写程序一样没有什么区别. 有点怪怪的味道,故把代码贴出来. using System; namespac