文章目录

  • 一、有关表的注解
  • 1.1 @table
  • 1.2 @Entity
  • 1.3 @Index
  • 1.4 @UniqueConstraint
  • 二、字段上的注解
  • 2.1 @Id
  • 2.2 @GeneratedValue
  • 2.3 主键生成策略
  • 2.3 @Column
  • 三、表之间的关联
  • 3.1 mysql删除表
  • 3.2 @ManyToOne
  • 3.3 OneToMany(mappedBy = "accountUser")
  • 3.4 mappedBy = "accountUser"
  • 3.5 注意
  • 3.6 AccountUser 查找UserIpfsFile
  • 四、出错
  • 4.1 找不到实体类


一、有关表的注解

1.1 @table

  • name: 用来指定要映射的表名
  • catalog: 指定table数据库中的路径,这里指数据库名
  • schema: 映射到哪个schema,用户名
  • uniqueConstraints: 可以创建单个字段或者联合的唯一约束,只有在创建表成功时才执行
  • indexes:索引,可以指定联合索引,也是只有表生成成功才有效
    参考:@Entity @Table注解
@Entity
@Table(name = "UserInfo",uniqueConstraints = {@UniqueConstraint(columnNames = {"sid","email"}),@UniqueConstraint(columnNames = {"email"})},
indexes = {@Index(columnList = "emial")})
public class UserInfo {
......
}

1.2 @Entity

表明这是一个实体类,要与数据库做orm映射,默认表的名字就是类名,表中的字段就是类中的属性。

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
    String name() default "";
}

1.3 @Index

@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface Index {
    String name() default "";

    String columnList();

    boolean unique() default false;
}
  • name
    置顶索引名称
  • columnList
    指定索引所在的列
  • 创建复合索引

只要指定索引的名称即可,根据复合索引的创建顺序来配合最左匹配原则。

@Table(name = "UserInfo",uniqueConstraints = {@UniqueConstraint(columnNames = {"sid","email"}),@UniqueConstraint(columnNames = {"email"})},
indexes = {@Index(columnList = "email",name = "email"),
           @Index(columnList = "email",name = "GOGO"),
           @Index(columnList = "sname",name = "GOGO"),
           })

1.4 @UniqueConstraint

  • 唯一约束
@Entity
@Table(name = "UserInfo",uniqueConstraints = {@UniqueConstraint(columnNames = {"sid","email"}),@UniqueConstraint(columnNames = {"email"})},
indexes = {@Index(columnList = "email",name = "email"),
           @Index(columnList = "email",name = "GOGO"),
           @Index(columnList = "sname",name = "GOGO"),
           })

二、字段上的注解

2.1 @Id

  • 注意注解的引用包
mport javax.persistence.*;

声明一个实体类的属性映射为数据库的主键列该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。

2.2 @GeneratedValue

用于标注主键的生成策略,通过strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer对应identity,MySQL 对应 auto increment。

2.3 主键生成策略

参考:JPA @Id 和 @GeneratedValue 注解详解

public enum GenerationType {
    TABLE,
    SEQUENCE,
    IDENTITY,
    AUTO;

    private GenerationType() {
    }
}

在javax.persistence.GenerationType中定义了以下几种可供选择的策略:
–IDENTITY:采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式;
–AUTO: JPA自动选择合适的策略,是默认选项;
–SEQUENCE:通过序列产生主键,通过@SequenceGenerator 注解指定序列名,MySql不支持这种方式
–TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。

2.3 @Column

name
定义了被标注字段在数据库表中所对应字段的名称;
unique
表示该字段是否为唯一标识,默认为false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table标记中的@UniqueConstraint。
nullable
表示该字段是否可以为null值,默认为true。
insertable
表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值。
updatable
表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。
columnDefinition(大多数情况,几乎不用)
表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。(也就是说,如果DB中表已经建好,该属性没有必要使用。)
table
表示当映射多个表时,指定表的表中的字段。默认值为主表的表名。
length
表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。
precision和scale
precision属性和scale属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。

参考:@Column注解及属性详解

举例:

ublic class UserInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(insertable = false,updatable = false)
    int sid;
    String sname;
    String email;
    String address;
    @Column(nullable = false)
    String phone;
    @Column(columnDefinition = "varchar(200) not null")
    String info;
    @Column(precision = 10,scale = 2)
    float height;
    ......
}

三、表之间的关联

3.1 mysql删除表

  • 删除表数据和表结构
DROP TABLE account_user;

3.2 @ManyToOne

@Entity
@Getter
@Setter
@NoArgsConstructor
public class UserIpfsFile {
    @Id
    @Generated
    int ipfsId;
    @Column(length = 400)
    String ipfsFileIndex;
    @ManyToOne()
    public AccountUser accountUser;
}

3.3 OneToMany(mappedBy = “accountUser”)

  • mappedBy:关联表中的关联实体类
@Getter
@Setter
@Entity
@NoArgsConstructor
@ToString
public class AccountUser {
    @Id@GeneratedValue
    int pid;
    String p12FilePath;
    String accountPasswod;
    //Sm2User sm2User;
    @Column(length = 400)
    String sm2PublicKey;
    @Column(length = 400)
    String sm2PrivateKey;
    @OneToMany(mappedBy = "accountUser")
    public List<UserIpfsFile> userIpfsFileList= new ArrayList<UserIpfsFile>();
    }

3.4 mappedBy = “accountUser”

  • 一般是表名
  • 在oneToMany中设置

比如:一个teacher负责多个学生,在学生表中就会设置@manyToOne
public Teacher teacher;
来表示这个teacher(标记为flag)关联这个学生,在teacher表中的@oneToMany的mappedBy 就是上面的teacher(标记的flag)。

3.5 注意

设置关联关系后,在创建表的时候会创建外键

3.6 AccountUser 查找UserIpfsFile

  • 一个AccountUser 关联多个UserIpfsFile
  • 启动spring boot,jpa会自动根据关联关系创建外键,比如:上述UserIpfsFile 本来只有两个字段ipfsFileIndex和ipfsId,会多一个关联字段:account_user_pid,该字段会和AccountUser 的主键pid关联

java捕获唯一索引异常D jpa唯一索引_字段

  • AccountUser 查找关联的UserIpfsFile 集合
    可以直接通过getUserIpfsFileList查找,也可以在UserIpfsDao中自定义finallByAccountUser_pid查找方法
@Repository
public interface UserIpfsDao extends JpaRepository<UserIpfsFile, Integer> {
    public List<UserIpfsFile> findAllByAccountUser_Pid(int pid);
}

四、出错

4.1 找不到实体类

Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.example.demo.Entity.People