zoukankan      html  css  js  c++  java
  • JPA 对象关系映射

    H2内嵌数据库的使用

    SpringBoot可以自动的配置内嵌的H2、HSQL、Derby数据库。

    步骤
    1.引入相关的依赖
    2.在配置文件进行相关的配置

    spring.h2.console.enabled=true //开启web console功能 http://localhost:8080/h2-console/
    spring.datasource.platform=h2 //数据库平台是H2,可选
    spring.h2.console.path=/h2 //设置访问路径 localhost:port/h2

    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.url=jdbc:h2:./data/db 是相对路径
    spring.datasource.password=
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect 使用的语言
    spring.datasource.schema=
    spring.datasource.data=

    spring.jpa.show-sql = true //打印SQL语句
    spring.jpa.hibernate.ddl-auto=update //三个可选值create , update , none

    JPA提供的实体类注解

    @Entity表明该类为实体类
    @Table(name="table_name")实体类对应数据库中表的名字
    @Id 表明该属性是主键
    @GeneratedValue(strategy=)增长方式,声明增长方式的一种 ; @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")声明主键的增长方式的第二种方法
    @Column(name = "id",length = 36) 每个属性都必须要的注释,声明该属性与数据库表中与之对应的字段

    主键生成策略

      •      GenerationType.IDENTITY: 自增 如 mysql数据库底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
        
      •      GenerationType.GenerationType.SEQUENCE: 序列 如 oracle数据库底层数据库必须支持序列
        
      •     GenerationType.GenerationType.TABLE: jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
        
      •     GenerationType.GenerationType.AUTO: 由程序自动的帮助我们选择主键生成策略
        

    对象的三种状态
    Managed:持久化受管对象,有id值,已经和Persistence Context建立了关联的对象。

    Datached:游离态离线对象,有id值,但没有和Persistence Context建立关联的对象。

    Removed:删除的对象,有id值,尚且和Persistence Context有关联,但是已经准备好从数据库中删除

    状态名 作为java对象存在 在实体管理器中存在 在数据库存在

    New yes no no

    Managed yes yes yes

    Detached no no no

    Removed yes yes no

    JPA操作数据库的步骤

    1.配置文件,配置数据库 spring.datasource节点配置数据库驱动,url,用户密码; spring.jpa 节点配置spring,jpa.hibernate.ddl_auto,spring.jpa.hibernate.naming.strategy命名策略,默认即可,spring.jpa.properties.hibernate.dialect = hibernate的语言

    2.实现接口,JpaRepository 封装了基本的CRUD ; JpaSpecificationExcutor 复杂的操作

    JpaRepository 接口的方法 在接口的所以方法中,除了保存,查找操作无需要对象的主键外,其余操作都需要用到对象的主键,也就是说无论是删除操作,还是修改操作都需要在进行前标识对象的主键,表明你对那个对象操作。Object.SetId(Id)

    save方法,保存对象时,事务会自动提交,所以执行语句后,数据库插入新的数据;但是 update,delete时,对象的更新不但需要主键,还需要手动提交事务,或者使用flush操作后,数据库才会同步操作,因为update,delete的对象操作的是一级缓存里面的对象。

    接口的方法
    findAll
    count, delete, deleteAll, deleteAll, deleteById, existsById, findById, save
    count, exists, findAll, findOne

    此外还可以在接口定义更多的方法,可以搭配注解使用

    @Query("SELECT p FROM Person p WHERE name LIKE %?1%")
    Person findByName(String name);

    @Query("SELECT p FROM Person p WHERE name LIKE %:name%")
    Person findByName(@Param("name") String name);

    @Modifying
    @Query("UPDATE Person p SET p.name = :name WHERE p.id = :id")
    void updatePersonName(@Param("id") Integer id, @Param("name") String name);

    @Modifying注解来标识该方法执行的是更新或者删除操作

    查询参数
    命名查询 :param ; 位置参数 ?1

    命名模糊查询
    命名查询例子
    public Customer findByCustName(String custName); 根据CustName进行查询

    public List findByCustNameLike(String custName);根据CustName进行模糊查询

    public Customer findByCustNameLikeAndCustIndustry(String custName,String custIndustry);多条件的模糊查询和精准查询

    findBy --> from xxx(实体类),属性名称 --> where custName =
    是对jpql查询更深一层的封装
    findBy查询,根据后面的属性查询

    对象关系:
    一对一:@OneToOne()
    一对多,多对一:@OneToMany
    多对多:@ManyToMany

    例子:
    一对多 和多对一:
    @OneToMany(targetEntity=)
    @JoinColumn(name= referencedColumn=)外键

    一对多的属性要注意设置拥有外键的实体类内,即一端;当然多端也是可以设置的。

    多对多:
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "me_article_tag",中间表的名字
    joinColumns = {@JoinColumn(name = "article_id")},中间表与主控方启用的外键
    inverseJoinColumns = {@JoinColumn(name = "tag_id")}) 中间表与另外一方的启用的外键
    private List tags;

    如果关系不是单向的,是双向的,双方都可以维护这段关系,那么需要配置mappedBy属性,该属性的值可以为对象的类名称,小写。

    mappedBy是OneToOne、OneToMany和ManyToMany这三种关联关系的属性。
    mappedBy和JoinColumn/JoinTable总是互斥的,有mappedBy属性,那么就不该有JoinColumn/JoinTable注解。

    fetch属性是 是否开启懒加载
    cascade属性是 级联
    CascadeType.REFRESH:级联刷新,当多个用户同时作操作一个实体,为了用户取到的数据是实时的,在用实体中的数据之前就可以调用一下refresh()方法
    CascadeType.REMOVE:级联删除,当调用remove()方法删除Order实体时会先级联删除OrderItem的相关数据
    CascadeType.MERGE:级联更新,当调用了Merge()方法,如果Order中的数据改变了会相应的更新OrderItem中的数据
    CascadeType.ALL:包含以上所有级联属性。要谨慎使用。
    CascadeType.PERSIST:级联保存,当调用了Persist() 方法,会级联保存相应的数据

    spring与hibernate整合

    1.创建EntityManagerFactory,加载配置文件,引用数据源
    2.从工厂,获取EntityManager对象
    3.实体类管理器,控制事务操作,manager.getTransaction()
    4.执行增删改查,提交事务。

    1,entityManager.persist(Object entity);  新增数据;
    如果entity的主键不为空,而数据库没有该主键,会抛出异常;
    如果entity的主键不为空,而数据库有该主键,且entity的其他字段与数据库不同,persist后不会更新数据库;

    2、entityManager.find(Class entityClass, Object primaryKey);  根据主键查找数据;
    如果主键格式不正确,会抛出illegalArgumentException异常;
    如果主键在数据库未找到数据返回null;

    3、entityManager.remove(Object entity);  删除数据;
    只能将Managed状态的Entity实例删除,由此Entity实例状态变为Removed;

    4、entityManager.merge(T entity);   将Detached状态的Entity实例转至Managed状态; 更新

    5、entityManager.clear(); 将所有的Entity实例状态转至Detached状态;

    6、entityManager.flush(); 将所有Managed状态的Entity实例同步到数据库;

    7、entityManager.refresh(Object entity); 加载Entity实例后,数据库该条数据被修改,refresh该实例,能得到数据库最新的修改,覆盖原来的Entity实例;

  • 相关阅读:
    1、Python的初识与简介
    解密解密
    python看是32位还是64
    linux实战一段,安装python3(centos)
    前段技巧
    django后端safe和前端safe的方法
    测试
    python小知识整理
    ajax格式
    111
  • 原文地址:https://www.cnblogs.com/lin7155/p/13758313.html
Copyright © 2011-2022 走看看