对于任何一个 ORM 工具,大都是根据配置者约定了解你打算怎么把一张数据表与你的 Java 对象 映射到一起。默认的 Nutz.Dao 采用 Java 注解(Annotation) 的方式描述这个映射,但是,当然 世界上还有很多其它的映射方式,比如用各种配置文件,比如 JPA 的注解,或者你很想把这个 映射关系写在数据库的几张表里,甚至一个 Excel 表格里(你就觉得这样很酷)
从 1.b.38 之后,Nutz.Dao 开放了自己的 Entity 接口,你就可以定义自己的映射存放方式了。
Class<?> ---> Entity<?> ---> PojoMaker ---> DaoStatement ---> DaoExecutor ---> JDBC
| | | | |
\------------------------ NutDao 的实现流程 -----------------------/
从上图,我们可以清楚的看到,Nutz.Dao 会首先分析你传入的 Class<?>
,然后将将映射关系
保存成一个 Entity<?>
,也就是说通过找个 Entity<?>
,NutDao 可以了解到调用者打算怎么
映射数据表和Java类。
通过 EntityMaker 接口,Nutz 封装了这个过程,你可以重载 NutDao 的一个函数:
public class MyDao extends NutDao {
protected EntityMaker createEntityMaker() {
return new MyEntityMaker();
}
}
之后,如果使用 MyDao,那么实体的生成方式就是你说了算啦 ^_^
通过在你的 POJO 类上标注注解,可以让 Nutz 来理解你打算怎么映射字段,这里我们举几个例子
@Table
public class PetBean {
...
@Column //提醒一下,对于@Name注解来说这一行是多余的
@Name // 代表字符型注解, 数值型主键用@Id
@ColDefine(type=ColType.VARCHAR, width=64)
private String name;
Pet pet = dao.fetch(Pet.class,"abc");
VARCHAR(64)
dao.create(XXX.class)
设计的,因为它要生成建表语句通常一个字段,你只需要:
@Column
private int age;
@Column("pname")
private String parentName;
如果你的 POJO 没有任何一个字段标注了 @Column,那么相当于你所有的字段都是数据库字段。 否则,仅仅是标注了 @Column 的字段才被认为是数据库字段
注意, @Column的规则是, 要么不写(Pojo类全部属性当字段映射),要么全写(Pojo带@Id/@Name/@Colunm的属性才当字段映射)
EntityMaker 接口负责具体的 Entity 生成,你可以参看一下它的源代码:
package org.nutz.dao.entity;
public interface EntityMaker {
<T> Entity<T> make(Class<T> type);
}
Entity<T>
也是一个接口,当然,默认实现类 NutEntity<T>
应该能满足你大多数需求,我想
至力于想扩展 Entity 生成方式的同学,会直接阅读相关的源代码作为参考,所以这里就不啰嗦了。
动态实体
Map<String,Object> map = new HashMap<String,Object>();
map.put(".table", "t_person");
map.put("name", "abc");
map.put("age", 18);
dao.update(map);
你给的 Map 只要多一个固定的名值对 ".table",那么我就能知道你想操作的数据库表名。 所以,你还可以:
Map<String,Object> map = new HashMap<String,Object>();
map.put(".table", "t_person");
map.put("name", "abc");
map.put("age", 18);
dao.insert(map);
实际上,NutDao 是根据给定的 Map,先构建了一个 Entity<?>
,然后之后的事情就顺理
成章了。这个特性从另外一方面也验证了现在的实体机制,它的确工作的还不错 :)
虽然,我们极其反感用数据库关键字做字段名的行为,但是,我们还是提供了一些解决版本
单个字段的解决
// since 1.r.59
@Column(wrap=true)
String index;
nutz默认把枚举映射为字符串,若数据库中对应的列为int的话,需要特别声明一下
@ColDefine(type=ColType.INT)
private UserType userType;
本页面的文字允许在知识共享 署名-相同方式共享 3.0协议和GNU自由文档许可证下修改和再使用。