IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

HS4J Kit 介绍

淘宝数据平台与产品部官方博客 tbdata.org 2011-06-14 13:48:57 累计浏览 3,568 次
本机暂存

    HS4J Kit是HS4J贡献项目, 它的灵感来自ORM(对象关系映射), 通过使用Annotation(注解)对领域对象进行声明, 即可实现对HS4J的调用, 省去编写和维护较为底层的模板式代码.

    举例而言, 在一个管理用户信息的业务场景中通常都会有:

01 class User {
02   Long id;
03   String name;
04   Integer age;
05 }
06 
07 interface UserRepository {
08   void add(User user);
09   void delete(User user);
10   User findBy(long id);
11   void update(User user);
12 }
01 CREATE TABLE `user_t` (
02   `id` int(10) unsigned NOT NULL,
03   `name` varchar(50) DEFAULT NULL,
04   `age` int(3) DEFAULT NULL,
05   PRIMARY KEY (`id`),
06   KEY `NAME` (`name`),
07   KEY `AGE` (`age`)
08 ) ENGINE=InnoDB
若直接使用HS4J提供的API, 代码会如HS4J Getting Started的示例一样, 模式化的重复. 对象结构简单还不是问题, 一旦对象字段十多个, 而且还老是要变化, 可想而知噩梦才刚刚开始.

    使用Kit提供的注解来声明的话, 一切HS4J的调用操作全部将透明化:

01 @Repository(database="test", table="user_t")
02 interface UserRepository {
03   @HandlerSocket(INSERT)
04   @EntityClass(User.class)
05   void add(User user);
06   ...
07 }
接下来要写的代码就是:
01 HSClient hsClient = new HSClientImpl(new InetSocketAddress(9999));
02 ProxyFactory proxyFactory = new HandlerSocketProxyFactory(hsClient);
03 UserRepository proxy = proxyFactory.newProxyOf(UserRepository.class);
04 
05 proxy.add(new User(1L, "killme2008", 18));
06 
07 hsClient.shutdown();
抛开必要的初始化和销毁的代码, 除了一行必须的业务代码没有任何多余的.

    这里没有配置表的列(Columns), 而是通过EntityClass来告诉Kit默认使用User的所有字段映射为表的所有列, 前提是User的字段名与表列名一致.

    若列名与字段名无法一致的时候, 可以ColumnName来声明:

01 class User {
02   @ColumnName("uid")
03   Long id;
04   ...
05 }
查询方法怎么声明呢?
01 @HandlerSocket(FIND)
02 @EntityClass(User.class)
03 ResultIterator findBy(@Operator(EQ) long id);
业务代码会是:
01 ResultIterator itr = proxy.findBy(1L);
02 while (itr.next()) {
03   User user = itr.get();
04   ...
05 }
缺省情况下, 使用表的主键作为Index的key. 与add不同的是:
  • 使用ResultIterator作为返回值类型, 其实目的是为了简单的封装ResultSet;
  • 使用Operator对参数id进行了注解, 告诉HS4J对id使用EQ操作.
  •     查询场景通常会有分页的需求, 这就会使用到Offset和Limit两个注解:

    01 @HandlerSocket(FIND)
    02 @Index("AGE")
    03 @EntityClass(User.class)
    04 ResultIterator findUserAgeGreaterThan(@Operator(GT) int age, @Offset int offset, @Limit int limit);
    上面都是全字段写入或读取, 在部分修改的场景中如何注解呢?
    01 @HandlerSocket(UPDATE)
    02 @Columns("age")
    03 @Index("NAME")
    04 void updateUserAge(@Operator(EQ) String name, int age);
    通过Colunms告诉HS4J打开的Index仅对age进行操作, 并以name为key, 是用age参数作为value.

        修改多值的情况下, 请保证参数声明的顺序和Columns定义的顺序一致:

    01 @HandlerSocket(UPDATE)
    02 @Columns({"name", "age"})
    03 void updateUserNameAndAge(@Operator(EQ)long id, String name, int age);
    主要的用法介绍到此, 还其他的用法就不再累述了, 请参看单元测试代码举一反三吧!

    同分类推荐文章

    1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
    2. Go 实验特性详解 (2026-06-21 10:05:27)
    3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

    查看更多 后端 文章 →

    建议继续学习

    1. SmartSprites - 命令行形式的CSS Sprites生成器 (累计阅读 123,895)
    2. Java开发岗位面试题归类汇总 (累计阅读 22,157)
    3. android 开发入门 (累计阅读 19,529)
    4. 我的PHP,Python和Ruby之路 (累计阅读 13,149)
    5. HashMap解决hash冲突的方法 (累计阅读 12,654)
    6. 一个大二学生有关如何成为一名软件工程师的疑问及答复 (累计阅读 9,181)
    7. Java程序员应该知道的10个eclipse调试技巧 (累计阅读 8,014)
    8. 如何让员工忠于公司? (累计阅读 7,940)
    9. Java技术路线 (累计阅读 7,726)
    10. 聊聊ThoughtWorks面试 (累计阅读 7,615)