JPA:实体类注解配置

JPA 中可以使用一套比较简洁的注解来配置实体类信息,并且通过给出的大量默认值让这一配置显得格外的方便;

JPA的实体注解的访问方式主要分为三种:

字段访问:把注解都写在对象的字段上面,字段必须不是public的

属性访问:把注解写在getter方法上面,属性也必须有setter方法,方法必须是public和protected的。

混合访问:即指在此类上同时使用了字段访问和属性访问。

上面说的配置访问的方式主要体现在@Access 注解上。这个注解可以放到类上面就可以表示整个类的访问方式,也可以放到某个字段或getter方法上,达到某个字段用某种方式访问的效果,如果没有配置默认使用字段访问模式。

由于注解太多,这里在一个实体类中展示常用的一些注解,演示使用的是字段访问模式;

//标识此类为JPA实体类

@Entity
public class UserProfile implements Serializable {


    /**
    *  @Id 用于标识当前字段是表的主键
    *
    *  有了主键,那么肯定就需要定义主键生成策略了。常用的策略一个是自增长,一个是序列。
    *
    *  小编这里用的是 通过一张表,来管理ID的生成,该策略的主要思路是;
    *  在表中定义一个key列 来标识该行记录存属于某实体的id值,value列 则为一个 数字;如:
    *
    **************************************************
    *
    *              key列      |     值列             |
    *
    **************************************************
    *
    *             UserProfile |      1               |
    *
    ***************************************************
    *
    * 这个value 并不代表id。它还有个乘数比如100.那么1就表示(1*100)个数。
    *
    * 这100个数就被放到内存里面了,等这100个数用完后,
    *
    *  就去数据库里面拿发现数据库里面是1.那么就是说要把+1的值拿到内存里面
    *
    *   也就是 100 - 200 了。这样数据中的值就变成2了。
    *
    * 我们在来@TableGenerator里面定义的数据就好理解了,这种ID创建表的表面,key列,value列, 
    *      
    *当前表对应的key值。 乘数的值,产生的id的初始化值
    *
    * 这个创建器定义好后,我们还需要做的一步就是告诉JPA我们用的是哪个策略 
    * @GeneratedValue  strategy选择用表作为ID生成策略,然后在关联上 上面配置好的创建器。
    **/
    @Id
    @TableGenerator(name = "UserProfile", table = "ID_SEQUENCE", 
                pkColumnName = "ID_KEY", valueColumnName = "VALUE", 
              pkColumnValue = "UserProfile", allocationSize = 100, initialValue = 0)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "UserProfile")
    private int id;

    /**
     *
     * @Column 来设置该字段对应数据库表的一些信息.
     * 如:是否唯一,能不能为空,长度多少,对应的列名(缺省等于字段名)
     */
    @Column(unique = true, nullable = false, length = 45)
    private String username;

    /**
     * @Log 用来标识大数据字段
     */
    @Log
    private String content;

    /**
     * @Basic 该注解标识 当前字段是一个基础数据库字段;
     * 包括(八大基本类型,Date,String,BigDecimal,BigInteger,byte[],char[])
     * fetch 属性用来标识 这个字段 使不使用 懒加载,这里配置的是使用。@Basic中缺省是饥渴加载。
     */
    @Basic(fetch = FetchType.LAZY)
    @Column(nullable = false, length = 45)
    private String password;

    /**
     * @OneToOne 用于关联另一张表且是一对一的情况。如果配置mappedBy那么说明当前的是主表,
     * 关联的那个表示从表,当前表的id被作为外键在关联表上了
     */
    @OneToOne(mappedBy = "userProfile")
    private UserDetail detail;

    /**
     * @Enumerated 这个注解作用在 枚举上面,表示枚举存储到数据库的形式。
     * 有两种一种是存枚举的名字,一种是存序号。
     * 小编这里推荐存名字,浅显易懂。 
     * 存序号的号,要额外注意,那就是加入新的值是,只能往已有的值后面加。
     * 否则实际值和数据库中存的序号就对应不上了
     */
    @Enumerated(EnumType.STRING)
    private UserStatus status;

    /**
     * @ManyToOne用于关联另一张表且是多对一的情况,当前实体是多方故需要只有关联方主键作为外键。
     * 多对一的 fetch缺省是饥渴模式,所以根据自身的业务可以进行调整
     * @JoinColumn 对持有的外键列,进行配置,如:列名,是否允许控制。。。
     */
    @ManyToOne(optional = true)
    @JoinColumn(name = "locationId", nullable = true)
    private Location location;


    /**
     * @OneToMany 用于关联另一张表且是一对多的情况,当前实体是一方所以不想要持有外键,
     * 只需要配置一下和关联实体中的哪个字段关联即可,fetch缺省是懒加载
     */
    @OneToMany(mappedBy = "userProfile")
    private List userProfileHistory;


    /**
     * @Temporal 用来确定时间类型的。值得对应如下
     *   TIMESTAMP  ---》 java.sql.Timestamp
     *   DATE ----》java.sql.Date
     *   TIME ----》 java.sql.Time
     *  一般使用时间戳。 用不到具体分秒时的就选用DATE 了。
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    /**
     * @ManyToMany 用于关联另一张表且是多对多的情况,fetch缺省是懒加载。
     * 构建多对多,需要定义一下中间表的配置
     * @JoinTable 就是用来定义中间表的, name表名称。 
     * inverseJoinColumns 定义关联实体的主键 列的信息,
     * joinColumns 定义当前实体的主键 列信息。定义好后大致如下
     **************************************************
     *              role_id      |     user_id        |
     **************************************************
     *             1             |      1             |
     **************************************************
     * OK 为了方便多对多的管理,多数情况下 会有 级联删除,我被删除啦关联的你也应该被删除。
     * 上面这种业务 可以在 @ManyToMany cascade属性上进行配置。
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "role_user", 
               inverseJoinColumns = { @JoinColumn(name = "role_id") }, 
                joinColumns = { @JoinColumn(name = "user_id") })
    private List roles;


    /**
     *
     * @Version 应用在需要进行一些字段维护的实体上。该字段是用来做 乐观锁的。
     *
     * 那么说到了乐观锁:这里就简单的描述一下,举一个例子吧。
     *
     * 小明同学要请假陪女票过七夕,在OA 上提交了请假3天的请假条。
     * 经理看到了,觉得太久了给他扣掉了一天。人力看到了也觉得请3天太久了,也给他扣了一天。
     * 那么我们期望的值就是小明的请假条批的是一天。然而经理和人力都是在请假条是3天的那个状态看到的,
     * 然后扣一天也是在3的基础上。那么真实情况就变成了2天。
     * 小明当然就开心了,但我们还是要杜绝这种事情的发生,毕竟不是真实想要的结果.
     * 来看乐观锁是怎么解决这一问题的。我们先为每条记录都加一个版本字段,
     * 那么在某条记录添加时版本的初始值为0,
     * 一条记录被修改了它的版本就会+1. 
     * 我们回到上面那个例子,经理进行修改的请假条版本为0(没有被改过). 
     * 首先这条记录和数据库中的对应记录的版本做对比,OK 都是0,可以修改,那么经理这条记录就修改成功,版本+1.
     * 人力修改的记录也过来了,人力修改的这条记录的版本也是0(查出来看的时候也没被改过),
     * 那么和数据库中的版本进行对比,一比发现版本对不上,不能修改,就会抛出一个叫乐观锁的异常,打断这次修改.
     * 接收到乐观锁异常后,可以提示用户再操作,或者系统再回调一次。
     *
     */
    @Version
    private int version;

} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在SpringBoot中,集成JPA需要通过配置类来实现。以下是一个示例: ```java @Configuration @EnableJpaRepositories(basePackages = {"com.example.demo.repository"}) //JPA仓库的扫描路径 @EnableTransactionManagement //开启事务管理 public class JpaConfig { @Autowired private DataSource dataSource; @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource); em.setPackagesToScan("com.example.demo.entity"); //JPA实体类扫描路径 JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); return em; } @Bean public PlatformTransactionManager transactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); return transactionManager; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } } ``` 在配置类中,我们首先使用`@EnableJpaRepositories`注解指定JPA仓库的扫描路径,这样Spring容器就能够自动创建JpaRepository实现类的实例。 接着,使用`@EnableTransactionManagement`注解开启事务管理。 然后,我们定义了`entityManagerFactory`方法,用于创建`EntityManagerFactory`实例。在这个方法中,我们设置了数据源和JPA实体类的扫描路径,并使用`HibernateJpaVendorAdapter`作为JPA厂商适配器。 接下来,我们定义了`transactionManager`方法,用于创建`PlatformTransactionManager`实例,并将`EntityManagerFactory`实例设置为其属性。 最后,我们定义了`exceptionTranslation`方法,用于处理JPA产生的异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值