Hibernate中实体映射时的命名策略(1)
2016-09-23 17:44
316 查看
有时候在实体类映射成数据库表时,我们并不太注意生成的表和列的名称,都是使用默认的名称策略,有的是干脆不使用
1、 历史版本中命名策略
在Hibernate的旧版本中,如果要指定应用于全局的命名策略,那么必然要涉及到
我们一般不直接实现
首先我们先说明一下将要使用的三个类如下,和上一篇中使用的相同,分别是Person、Address和Direction类。
Person类
Address类:
Direction类:
接着我们自定义命名策略,这里使用了Apache的common依赖包,如下:
下面我们首先先看一下这4个方法,基本上这4个是最常用的:
定义了上面的映射策略,我们怎么让这个自定义的类起作用呢?
如果我们使用Spring Boot来构建我们的程序,那么这个就容易多了,只需要在配置文件
另外如果只是使用普通的web工程,那么可以使用两种方式来使我们的命名策略起作用:
通过编程,如下:
通过hibernate.cfg.xml文件配置:具体的配置开如下相关文章的第一篇,因为具体配置比较繁琐,而且也不经常用,这里就不赘述了;
了解完上面的内容和相关配置,我们就来看一下具体生成的效果如下:
我们来具体分析一下里面包含的内容和相关的问题:
首先先看看生成的表名,感觉跟我们设置的不对呀,我们的设定是
Person中基本类型的字段映射成
Person中引用类型address的中的基本类型字段映射成
Person中引用类型address中的引用类型字段分别映射成person_latitude、person_longitude,并没有按照我们自定义的生成策略去生成,这说明一个问题,我们定义的全局命名策略被
相关文章:
mysql运维-lower_case_table_names(大小写敏感)
@Column注解,直接使用字段名;有的则在
@Column注解中使用
name属性定义自己的名称,但是有时候比如说设计一个数据库有统一前缀或者后缀,上面两种方式就不适用了,而需要统一的设计命名策略,本篇文章对这部分进行总结!
1、 历史版本中命名策略NamingStrategy
在Hibernate的旧版本中,如果要指定应用于全局的命名策略,那么必然要涉及到NamingStrategy这个接口,所有想自定义命名策略的类都要直接或者间接地实现这个接口。这个接口的继承结构如下:
我们一般不直接实现
NamingStrategy接口,因为这样我们会实现所有的接口方法,有时候这并不是必要的,所以我们一般直接继承
NamingStrategy的实现类,比如
DefaultNamingStrategy,这是Hibernate的默认的命名策略,或者
ImprovedNamingStrategy使用
_分隔字段,具体选择哪个类来继承主要是看我们自己的需求。这里我们使用Hibernate默认的命名策略
DefaultNamingStrategy来继承。
首先我们先说明一下将要使用的三个类如下,和上一篇中使用的相同,分别是Person、Address和Direction类。
Person类
@Entity public class Person implements Serializable{ private static final long serialVersionUID = 8849870114127659929L; @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; @Embedded @AttributeOverrides({@AttributeOverride(name="direction.latitude", column=@Column(name = "person_latitude")), @AttributeOverride(name="direction.longitude", column = @Column(name = "person_longitude"))}) private Address address; }
Address类:
@Embeddable public class Address implements Serializable{ private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false) private String country; @Column(length = 30) private String province; @Column(unique = true) private String city; @Column(length = 50) private String detail; @Embedded private Direction direction; }
Direction类:
@Embeddable public class Direction implements Serializable{ @Column(nullable = false) private Integer longitude; private Integer latitude; }
接着我们自定义命名策略,这里使用了Apache的common依赖包,如下:
public class EntityNamingStrategy extends DefaultNamingStrategy { @Override public String propertyToColumnName(String propertyName) { String column = propertyName.replaceAll("\\.", "_"); return "C_" + column; } @Override public String classToTableName(String className) { return "T_" + StringUtils.capitalize(className); } @Override public String tableName(String tableName) { return super.tableName(tableName); } @Override public String columnName(String columnName) { return super.columnName(columnName); } }
下面我们首先先看一下这4个方法,基本上这4个是最常用的:
propertyToColumnName:这个是用来使用字段属性名或者字段属性路径表达式作为参数来映射成对应的列名,这里面的关键点就是使用路径表达式,这个是在使用引用类型字段,比如说自定义类型的字段时,要映射时会使用路径表达式,就如同上面在Person类中使用Address类型字段,这是传入到该方法中参数是address.country、address.city等;
classToTableName:这个方法就比较容易理解,就是传入对应的类的全限定类名,而不仅仅只是一个普通的类名,然后通过这个参数决定映射的表名;
tableName:是根据在映射文档中定义的表名来修改映射的策略,由于我们基本都使用注解来映射,所以这种方式不常用;
columnName:是根据在映射文档中定义的列名来修改映射的策略,由于我们基本都使用注解来映射,所以这种方式也不常用;
定义了上面的映射策略,我们怎么让这个自定义的类起作用呢?
如果我们使用Spring Boot来构建我们的程序,那么这个就容易多了,只需要在配置文件
application.properties中配置
spring.jpa.hibernate.naming-strategy为我们的自定义的命名策略
com.springboot.demo.mapping.EntityNamingStrategy即可;
另外如果只是使用普通的web工程,那么可以使用两种方式来使我们的命名策略起作用:
通过编程,如下:
通过hibernate.cfg.xml文件配置:具体的配置开如下相关文章的第一篇,因为具体配置比较繁琐,而且也不经常用,这里就不赘述了;
Configuration cfg = new Configuration().configure(); cfg.setNamingStrategy(new EntityNamingStrategy()); StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()); StandardServiceRegistry sr = srb.build(); SessionFactory factory = cfg.buildSessionFactory(sr);
了解完上面的内容和相关配置,我们就来看一下具体生成的效果如下:
我们来具体分析一下里面包含的内容和相关的问题:
首先先看看生成的表名,感觉跟我们设置的不对呀,我们的设定是
T_类名,但是生成的确是
T_类名字母全部小写,其实表名的生成不仅和我们的程序有关系,也和对应的数据库和操作系统有关系,由于我们使用的是MySQL数据库,在它的配置文件my.ini中有
lower_case_table_names用于控制表名的大小写,如下在Workbench中显示:
Person中基本类型的字段映射成
C_字段名,这是按照我们的逻辑来生成的;
Person中引用类型address的中的基本类型字段映射成
C_字段名,字段名被”_”分隔;
Person中引用类型address中的引用类型字段分别映射成person_latitude、person_longitude,并没有按照我们自定义的生成策略去生成,这说明一个问题,我们定义的全局命名策略被
@AttributeOverrides注解覆盖掉了,也就是说有了这个注解,我们的全局策略不起作用,这一点我们要注意,下面试验一下删除这个注解生成的表结构如下:
相关文章:
mysql运维-lower_case_table_names(大小写敏感)
相关文章推荐
- Hibernate中实体映射时的命名策略(2)
- hibernate生成实体时对应的映射文件中主键的生成策略
- 【Hibernate】--实体状体与主键生成策略
- Hibernate笔记之2实体映射细粒度划分
- Hibernate关联映射,级联(cascade),抓取策略(fetch)
- 通过 Hibernate 实现 JPA 对象关系模型之继承映射策略 (剖析DTPYE的横空出世)
- eclipse + JBoss 5 + EJB3开发指南(10):通过继承实体Bean,将单个表映射成多个表(单表策略,SINGLE_TABLE)
- Hibernate -- 映射实体关联关系(一对一关联关系)
- Hibernate映射之实体映射
- Hibernate实体关系映射——单边的一对一关系
- Hibernate实体关系映射
- Hibernate深入学习(一):实体映射文件中的package,auto-import,dynamic-insert,dynamic-update用法
- ant深入浅出(一)ant+xdoclet 生成hibernate配置文件以及实体映射文件
- 流程总结:Hibernate实体映射
- JPA实体继承实体的映射策略
- Hibernate实体关系映射—Annotation
- 映射实体Bean的关联关系 -Hibernate Annotations
- Hibernate的3种继承映射策略
- 通过 Hibernate 实现 JPA 对象关系模型之继承映射策略
- Hibernate实体对象继承策略