//实体:
@Entity
@Table(name)
//主键:
@Id
@GeneratedValue(strategy, generator)
@SequenceGenerator(name, sequenceName)
//映射
@Column(name, nullable, length, insertable, updatable,columnDefinition)
//关系
@OneToOne、@OneToMany、@ManyToOne、@ManyToMany
@OrderBy
//其他
@Transient: 标识属性会被忽略
@Temporal:Date类型
@UpdateTimestamp - 更新时自动更新时间
@CreationTimestamp - 创建时自动更新时间
@Version - 版本号,更新时自动加1
使用 GeneratedValue
注释自动生成的实体标识可以是数值类型字段如 byte
、short
、int
、long
等,或者它们对应的包装器类型 Byte
、Short
、Integer
、Long
等,也可以是字符串类型。
public enum GenerationType {
TABLE,
SEQUENCE,
IDENTITY,
AUTO;
private GenerationType() {
}
}
TABLE:使用一个特定的数据库表格来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
IDENTITY:主键由数据库自动生成(主要是自动增长型)
AUTO:主键由程序控制。 (默认策略)例如:
@GeneratedValue(strategy=GenerationType.AUTO, generator = "uuid-string")
@SequenceGenerator
如果实体标识的自动生策略是 GenerationType.SEQUENCE
,开发者需要为实体标识字段提供 SequenceGenerator
注释,它的参数描述了使用序列号生成实体标识的具体细节。
@Column会根据属性的数据类型自动映射数据库的类型。可以定义在属性上,也可以定义在get方法上。其中name属性用于指定在数据库中的命名策略,
@Temporal(TemporalType.DATE) 会得到形如’yyyy-MM-dd’ 格式的日期
@Temporal(TemporalType.TIME) 会得到形如’HH:MM:SS’ 格式的日期。
@Temporal(TemporalType.TIMESTAMP) 会得到形如’HH:MM:SS’ 格式的日期
//按下面的配置会在数据库生成一张ttt的表。
@Entity
@Table(name = "ttt")
public class T {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(columnDefinition = "varchar",length =12,nullable = false)
private String name;
@Column //采用默认
private int age;
@Column(columnDefinition = "varchar(30) not null")//可以直接写定义sql
private String email;
@Column(length = 8) //只表明长度
private String address;
//下面两个属性一和id一般放在基类
@CreationTimestamp
private Date createTime;
@UpdateTimestamp
private Date updateTime;
//get/set方法....
}
注意:上述要自动建表生效,必须在配置文件中配置:这里采用更新策略,修改实体后,不会删除表重新建。
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto
的四个属性的含义见下表:
属性值 | 作用 |
---|---|
create | 每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。 |
create-drop | 每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。 |
update | 最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。 |
validate | 每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。 |
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
#打印sql
spring.jpa.show-sql=true
##########其他配置####################
###spring.jpa.database 指定目标数据库.
###spring.jpa.hibernate.implicit-strategy 指定命名策略.
例如:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
会采用驼峰方式,大写字符会在数据库中变小写,并用 - 分割。
说明:
spring.jpa.hibernate.ddl-auto = 指定DDL mode (none, validate, update, create, create-drop). 当使用内嵌数据库时,默认是create-drop,否则为none.
lombok和JPA配合使用,会使代码简洁很多。日志的使用需要在intellJ中装lombok插件。
1.首先引入依赖:
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
2.常用注解和作用:
@Getter / @Setter 给某个属性添加
@ToString
@NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor
@Data :相当于@Getter和@Setter的结合
@Builder:可以使用链式调用进行构造实体
@Slf4j / @CommonsLog / @Log4j2: 使用对应的日志框架
说明:
@Getter/@Setter :可以免于写get/set方法。
@ToString: 会自动生成toString方法
@NoArgsConstructor:生成无参构造方法
@RequiredArgsConstructor:
会生成一个包含常量,和标识了NotNull的变量的构造方法。生成的构造方法是私有 的private。
@Data:
相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode
这5个注解的合集.
@Slf4j: 使用日志,可以直接调用log.xx() 进行日志输出(需要安装lombok插件)
可以得知,当使用@Data
注解时,则有了@EqualsAndHashCode
注解,那么就会在此类中存在equals(Object other)
和 hashCode()
方法,且不会使用父类的属性,这就导致了可能的问题。
比如,有多个类有相同的部分属性,把它们定义到父类中,恰好id(数据库主键)也在父类中,那么就会存在部分对象在比较时,它们并不相等,却因为lombok自动生成的equals(Object other)
和 hashCode()
方法判定为相等,从而导致出错。
因此:在使用@Data
时同时加上@EqualsAndHashCode(callSuper=true)
注解
常用示例:
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name = "alert")
public class Alert extends BaseEntity{
private String alertName;
private String alertContent;
private String alertDetail;
private int alertTimes;
private int alertSeverity;//告警等级
private String deviceId;
private String deviceName;
}
构造实体时:
Alert.builder().deviceName("xx").build();