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

简介: 标准的Java DAO写法: 定义DAO接口; 编写DAO实现类; 在实现类中编写JDBC代码。 写JDBC代码非常枯燥而且容易出错,因此,增强的DAO可以用类似Spring的JdbcTemplate简化JDBC代码,不过仍然需要大量的ConnectionCallback,PreparedStatementCallbac等。 如果仅定义DAO接口,并利用Java 5 Ann

标准的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接口的实例,通过该实例,直接操作数据库!

相关文章
|
19天前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
27 10
|
23天前
|
SQL 关系型数据库 MySQL
创建SQL数据库的基本步骤与代码指南
在信息时代,数据管理显得尤为重要,其中数据库系统已成为信息技术架构的关键部分。而当我们谈论数据库系统时,SQL(结构化查询语言)无疑是其中最核心的工具之一。本文将详细介绍如何使用SQL创建数据库,包括编写相应的代码和必要的步骤。由于篇幅限制,本文可能无法达到您要求的2000字长度,但会尽量涵盖创建数
21 3
|
18天前
|
SQL 监控 关系型数据库
SQL错误代码1303解析与处理方法
在SQL编程和数据库管理中,遇到错误代码是常有的事,其中错误代码1303在不同数据库系统中可能代表不同的含义
|
23天前
|
SQL 安全 关系型数据库
SQL错误代码1303解析与解决方案:深入理解并应对权限问题
在数据库管理和开发过程中,遇到错误代码是常见的事情,每个错误代码都代表着一种特定的问题
|
3月前
|
存储 SQL 安全
【数据库高手的秘密武器:深度解析SQL视图与存储过程的魅力——封装复杂逻辑,实现代码高复用性的终极指南】
【8月更文挑战第31天】本文通过具体代码示例介绍 SQL 视图与存储过程的创建及应用优势。视图作为虚拟表,可简化复杂查询并提升代码可维护性;存储过程则预编译 SQL 语句,支持复杂逻辑与事务处理,增强代码复用性和安全性。通过创建视图 `high_earners` 和存储过程 `get_employee_details` 及 `update_salary` 的实例,展示了二者在实际项目中的强大功能。
38 1
|
2月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
96 0
|
3月前
|
JSON 数据格式 Java
化繁为简的魔法:Struts 2 与 JSON 联手打造超流畅数据交换体验,让应用飞起来!
【8月更文挑战第31天】在现代 Web 开发中,JSON 成为数据交换的主流格式,以其轻量、易读和易解析的特点受到青睐。Struts 2 内置对 JSON 的支持,结合 Jackson 库可便捷实现数据传输。本文通过具体示例展示了如何在 Struts 2 中进行 JSON 数据的序列化与反序列化,并结合 AJAX 技术提升 Web 应用的响应速度和用户体验。
97 0
|
3月前
|
SQL 数据库 索引
SQL 编程最佳实践简直太牛啦!带你编写高效又可维护的 SQL 代码,轻松应对数据库挑战!
【8月更文挑战第31天】在SQL编程中,高效与可维护的代码至关重要,不仅能提升数据库性能,还降低维护成本。本文通过案例分析探讨SQL最佳实践:避免全表扫描,利用索引加速查询;合理使用JOIN,避免性能问题;避免使用`SELECT *`,减少不必要的数据传输;使用`COMMIT`和`ROLLBACK`确保事务一致性;添加注释提高代码可读性。遵循这些实践,不仅提升性能,还便于后期维护和扩展。应根据具体情况选择合适方法并持续优化SQL代码。
43 0
|
3月前
|
SQL 安全 Java
访问者模式问题之在上面的 SQL 结构定义中, sealed 接口的作用如何理解
访问者模式问题之在上面的 SQL 结构定义中, sealed 接口的作用如何理解
|
3月前
|
SQL Java 数据库连接
【Azure 应用服务】Java ODBC代码中,启用 Managed Identity 登录 SQL Server 报错 Managed Identity authentication is not available
【Azure 应用服务】Java ODBC代码中,启用 Managed Identity 登录 SQL Server 报错 Managed Identity authentication is not available