首页 > 其他分享 >(二)JPA 连接工厂、主键生成策略、DDL自动更新

(二)JPA 连接工厂、主键生成策略、DDL自动更新

时间:2022-09-24 00:12:22浏览次数:77  
标签:EntityManager course JPA 数据表 entityManager static 自动更新 主键

(一)JPA的快速入门

2、JPA连接工厂

通过之前的 代码 实现已经清楚的发现了整个的JPA实现步骤,但是这个步骤似乎有一些繁琐了,毕竟最终所关心的一定是EntityManager对象实例,而要想获取到此对象的实例,那么要经过许多的步骤,这样如果每一次都重复的进行处理,会非常的繁琐了,那么就需要进行代码的抽象规定。

        // 创建JPA Entity工厂
        EntityManagerFactory factory =
                Persistence.createEntityManagerFactory("YootkJPA");
        // JPA操作对象
        EntityManager entityManager = factory.createEntityManager();

对等概念: DataSource -> EntityMannagerFactory

​ Connection -> EntityMannager,每一个对象的实例都表示一个Session的操作

所以此时可以考虑将部分的代码移交给JPA的专属连接管理类,用这个类可以基于ThreadLocal实现EntityManager存储,这样每一次通过该类的方法获取EntityManager的时候如果不关闭,则获取到的是同一个实例

对于上叙测试类的优化。

  • 一个工具类,简化EntityManagerFactory的创建与关闭
public class JPAEntityFactory {
    /**
     * JPA持久单元
     */
    private static final String PERSISTENCE_UNIT = "YootkJPA";
    /**
     * 等同于 数据源
     */
    private static EntityManagerFactory entityManagerFactory;
    /**
     * EntityManager 等同于 连接
     */
    private static ThreadLocal<EntityManager> entityManagerThreadLocal =
            new ThreadLocal<>();

    static {
        // 初始化创建数据源 静态代码块只会创建一次
        rebuildEntityManagerFactory();
    }
    
    /**
     * 获取连接
     */
    public static EntityManager getEntityManager() {
        // 本机线程获取连接
        EntityManager entityManager = entityManagerThreadLocal.get();
        if (entityManager == null) {
            // 从数据源获取新的连接
            entityManager = getEntityManagerFactory().createEntityManager();
            // 存入本地线程
            entityManagerThreadLocal.set(entityManager);
        }
        return entityManager;
    }
    
    private static EntityManagerFactory getEntityManagerFactory() {
        if (entityManagerFactory == null) {
            // 创建数据源
            rebuildEntityManagerFactory();
        }
        return entityManagerFactory;
    }
    
    private static void rebuildEntityManagerFactory() {
        // 持久单元 创建 数据源
        entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
    }
    
    /**
     * 关闭EntityManager
     */
    public static void close() {
        // 获取实例
        EntityManager entityManager = entityManagerThreadLocal.get();
        if (entityManager != null) {
            // 关闭连接  entityManager类似于Connection
            entityManager.close();
            // 删除本地线程中的连接
            entityManagerThreadLocal.remove();
        }
    }
}

修改测试类:

    @Test
    public void testAdd2() {
        // 获取连接
        EntityManager entityManager = JPAEntityFactory.getEntityManager();
        // 开启事务
        entityManager.getTransaction().begin();
        Course course = new Course();
        course.setCname("Spring编程实战");
        // 字符串 日期对象
        course.setStart(DateUtil.stringToDate("2022-09-19"));
        course.setEnd(DateUtil.stringToDate("2022-12-30"));
        course.setCredit(2);
        course.setNum(88);
        // 执行插入
        entityManager.persist(course);
        // 提交事务
        entityManager.getTransaction().commit();
        // 关闭连接
        JPAEntityFactory.close();
    }

3、主键生成

在JPA开发之中,主键数据的生成主要是基于@Id注解定义的,而在实际的项目开发之中,数据表的设计结构是有所不同的,所以JPA为了适应这些不同的数据表的定义,也提供有不同的主键生成策略。

image-20220923235348927

3、DDL自动更新

在实际的开发之中你是否会出现这样的一种比较 尴尬 的问题,在进行开发的时候有人修改数据表,而后当前的实体类结构和数据表的结构不统一,但是在JPA设计的时候,充分的考虑到了这种数据表修改的问题(表可能存在,也可能不存在,或者表的结构可能修改了),所以在这样的环境下就需要让代码可以自动的进行数据表的纠正。

在传统的项目开发之中,常规的做法是先进行数据表的创建,而后在围绕数据表进行业务功能的实现。在每次业务发生改变时,也是先进行表结构的修改,而后再进行程序的变更,这样的数据库维护是非常繁琐的,考虑到数据库更新以及 数据库移植 方面的设计,在 Hibernate 之中提供了 DDL 自动创建以及表更新策略

image-20220921111235152

JPA现在主要是基于 Hibernate 实现,那么 Hibernate 开发框架最早的一个特点就在于 可移植性,也就是说一个项目是在MySQL数据库下开发的,那么通过简单的配置修改,可以让代码直接在Oracle数据库中运行。

对于当前市面上可以见到的ORM开发框架来讲,只有JPA标准规定了数据库移植性的话题,而Hibernate 实现了JPA标准,所以只有Hibernate 开发框架具有移植性的功能,而像大家所熟悉的MyBatis是没有这样的功能

DDL更新策略

image-20220921111527086

3.1、使用

去到JPA配置文件中,修改DDL更新策略、

3.1.1、create

每次加载时,根据实体类生成表,如果表存在于数据库,会先删除

            <!-- JPA更新策略 -->
            <property name="hibernate.hbm2ddl.auto" value="create"/>

image-20220921123218377

查看执行日志信:可以看到 drop table if exists course (删除表,然后会依据实体类,重新创建表)

3.1.2、update

如果表不存在,重建表。

存在:如:实体类某个字段,在数据表中不存在,这个时候会添加。但是,删除实体类的某个字段,数据库对应的字段并不会删除。

修改实体类: 添加教师

image-20220921125003973

修改配置文件-更新策略为update

image-20220921125110845

查看执行日志:

表不存在,创建表

create table course (
cid bigint not null auto_increment,
cname varchar(255),
credit integer,
end date,
num integer,
start date,
teacher varchar(255),
primary key (cid)
) engine=InnoDB

排除属性

假如,我们相使实体类中的某个字段,在执行时,不创建数据库中的对应字段。使用@Transient即可

image-20220921130257497

标签:EntityManager,course,JPA,数据表,entityManager,static,自动更新,主键
From: https://www.cnblogs.com/look-word/p/16724725.html

相关文章

  • 使用Watchtower实现Docker容器自动更新
    前言:通常情况下我们手动更新容器的步骤比较繁琐,需要四个步骤:1.停止容器2.删除容器3.检查镜像更新情况,更新镜像4.重新启动容器容器少还无所谓,但要是需要更新大量的......
  • SpringDataJpa使用原生sql的小坑
     1.jpa中的count小坑在SpringDataJpa中repository层的@Query注解内写原生sql,如果有传入Pageable分页查询,即分页数据的pageSize大于原生sql查询出的数据,程序会正......
  • (一)JPA的快速入门
    JPA简介JPA是什么JPA是JavaPersistenceAPI的缩写,是一套由Java官方制定的ORM标准。当制定这套标准以后,市场上就出现很多JPA框架。如:OpenJPA(apache),EclipseTop(linktop)(e......
  • oracle主键约束新增和删除
    目录oracle主键约束新增和删除1、新增主键2、删除主键oracle主键约束新增和删除主键命名规范:pk_开头,一个表不能有两个主键约束,但可以有多个检查约束1、新增主键语法al......
  • Spring data Jpa 自定义hql分页,添加动态参数校验1
    一,配置好jpa环境直接上代码1,控制器  其中 pageNumber和pageSize是我们自己前端传,filter中以字符串方式包含所需要的参数2.server  用json将参数解......
  • SqlServer 约束(主键,外键,检查,非空,默认,唯一)
    主键-primarykey除外键约束外都可创建表单时直接赋予如:1createtable表名(2Idbigintprimarykey,3IdCardnvarchar(60)check(len(IdCard)>=......
  • 微信小程序版本自动更新
    公司的小程序项目上线,后期还会有小型的版本迭代.为了让用户能在我们进行版本迭代后及时使用最新版本的功能.做了以下优化..小程序的销毁当用户点击左上角关闭,或者......
  • mysql 在insert时防止出现主键冲突错误的方法
    在mysql中插入数据的时候常常因为主键存在而冲突报错,下面有两个解决方法:1、在insert语句中添加ignore关键字,如:insertignoreintotable(id,name)values('1','usern......
  • python自动更新pom文件
    前言项目越来越多,版本管理越来越麻烦,在项目上我使用mavenversion来进行版本管理。主要还是在分布式项目中模块众多的场景中使用,毕竟各个模块对外的版本需要保持统一......
  • springboot集成mybatis获取插入数据的主键
    问题:我们想在插入一条数据后同时能够返回这条数据在表中的id,Mybatis提供了@SelectKey注解。student为数据表,主键自增SelectKey的四个属性:selectKey会将SELECTLAS......