当前位置: 首页 > news >正文

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

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

下载:http://code.google.com/p/express-me/downloads/list

文档:http://code.google.com/p/express-me/wiki/ExpressPersistence

相关文章:

  • 百度关闭竞价排名部分功能,以提升用户体验
  • linux 更新nodejs到最新
  • 移动MM初探之一:苹果APP Store模式将不再赢利?
  • 七大热门商业智能产品(非开源)
  • azure 最佳实践 3--最小协同操作
  • linux-2.6.26内核中ARM中断实现详解(2)
  • azure 最佳实践4 --可水平扩展的设计
  • 开发即过程!立此纪念一个IT新名词的诞生
  • azure 最佳实践5--使用分区
  • asp.net Webapi登录azureAD并调用azure graph api
  • (翻译)terry crowley: 写给程序员
  • 推荐x61使用nhc软件控制风扇
  • azure 最佳实践-- 系统运维
  • 全角字符unicode码对应表
  • azure 最佳实践 -- 尽量使用托管服务
  • Android优雅地处理按钮重复点击
  • Centos6.8 使用rpm安装mysql5.7
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • git 常用命令
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • java正则表式的使用
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Quartz初级教程
  • 分享几个不错的工具
  • 解决iview多表头动态更改列元素发生的错误
  • 配置 PM2 实现代码自动发布
  • 前端相关框架总和
  • 前嗅ForeSpider教程:创建模板
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (13):Silverlight 2 数据与通信之WebRequest
  • (C语言)球球大作战
  • (Oracle)SQL优化技巧(一):分页查询
  • (动态规划)5. 最长回文子串 java解决
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • .net framework 4.0中如何 输出 form 的name属性。
  • .NET Remoting学习笔记(三)信道
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .Net7 环境安装配置
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .NET命令行(CLI)常用命令
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • //解决validator验证插件多个name相同只验证第一的问题
  • /etc/skel 目录作用
  • @ResponseBody
  • [2019/05/17]解决springboot测试List接口时JSON传参异常