Jpa之关联对象(单向多对多)

Jpa之关联对象(单向多对多),第1张

多对多的关系会生成一张中间表来建立关联,可以对中间表进行配置,以达到满意的效果!

@JoinTable描述了多对多关系的数据表关系。name属性指定中间表名称,joinColumns定义中间表与Teacher表的外键关系。

中间表tea_stu的tea_id列是Teacher表的主键列对应的外键列,inverseJoinColumns定义了中间表与另外一端(Student)的外键关系。

执行了11条SQL,先插入老师的信息,再插入学生的信息,再更新中间表的信息(学生与老师的关系)。

当没有去使用list集合时,此时并没有去执行查询list集合数据,说明是延迟加载!

小结:

1.配置单向多对多的关系时,只需要使用注解@manyTomany

2.多对多会生成中间表来维护双方的关系

3.需要重新配置中间表的信息时,需要使用注解@JoinTable(name="中间表名",joinColumns = @JoinColumn(name = "当前表的外键名"),inverseJoinColumns=@JoinColumn(name = "关联表的外键名"))。

4.添加数据时,都会发送大量的SQL,不仅要添加两张表的数据,还要添加中间表的关系,所以效率低。

修改查询

@Modifying

@Query("update User u set u.firstname = ?1 where u.lastname = ?2")

int setFixedFirstnameFor(String firstname, String lastname)

使用 Sort 和 JpaSort

public interface UserRepository extends JpaRepository {

  @Query("select u from User u where u.lastname like ?1%")

  List findByAndSort(String lastname, Sort sort)

  @Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")

  List findByAsArrayAndSort(String lastname, Sort sort)

}

repo.findByAndSort("lannister", new Sort("firstname"))           

repo.findByAndSort("stark", new Sort("LENGTH(firstname)"))       

repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)"))

repo.findByAsArrayAndSort("bolton", new Sort("fn_len"))   

使用已命名参数

public interface UserRepository extends JpaRepository {

  @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")

  User findByLastnameOrFirstname(@Param("lastname") String lastname,

                                @Param("firstname") String firstname)

}   

原生SQL分页

public interface UserRepository extends JpaRepository {

  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",

    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",

    nativeQuery = true)

  Page findByLastname(String lastname, Pageable pageable)

}

Sort sort =newSort(Sort.Direction.DESC,"createTime")//创建时间降序排序Pageable pageable =newPageRequest(pageNumber,pageSize,sort)

使用原生SQL

public interface UserRepository extends JpaRepository {

  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)

  User findByEmailAddress(String emailAddress)

}

为了消除不确定性,可以在方法名内使用下划线“_”手动定义隔断点。

List findByAddress_ZipCode(ZipCode zipCode)

查询方法建立

distinct flag

ignoring case

order by

public interface PersonRepository extends Repository {

  List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname)

  // Enables the distinct flag for the query  List findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname)

  List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname)

  // Enabling ignoring case for an individual property  List findByLastnameIgnoreCase(String lastname)

  // Enabling ignoring case for all suitable properties  List findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname)

  // Enabling static ORDER BY for a query  List findByLastnameOrderByFirstnameAsc(String lastname)

  List findByLastnameOrderByFirstnameDesc(String lastname)

}

异步查询结果

@Async

Future findByFirstname(String firstname)           

@Async

CompletableFuture findOneByFirstname(String firstname)

@Async

ListenableFuture findOneByLastname(String lastname)

Like模糊查询

@Query(value = "select name,author,price from Book b where b.name like %:name%")

List findByNameMatch(@Param("name") String name)

In 查询

@Query(value = "select * from trade$seek_purchase_offer where sp_id in (:spIds) and of_enuu = :enUu", nativeQuery = true)

    List getSeekPurchaseOfferList(@Param("spIds") List spIds, @Param("enUu") Long enUu)

MappedSuperClass:

映射为非实体父类,该实体父类不会生成对应的数据表

@OneToOne

@Entity

@Table(name = "costume_all_id")

public class AllId extends AbstractEntity {

    private static final long serialVersionUID = 1L

    @OneToOne(cascade = CascadeType.ALL)

    @JoinColumn(name = "costume_member_fk")

    private Member member// 用户表外键

}

@OneToMany和@ManyToOne

@Entity

@Table(name = "costume_organization")

public class Organization extends AbstractEntity {

    private static final long serialVersionUID = 1L

    @Column(nullable = false, length = 50)

    private String name// 组织名称

    @OneToMany(mappedBy = "organization")

    private Set departmentSet// 部门集合

}

@Entity

@Table(name = "costume_department")

public class Department extends AbstractEntity {

    private static final long serialVersionUID = 1L

    @Column(nullable = false, length = 50)

    private String name// 部门名称

    @ManyToOne(optional = false)

    private Organization organization// 组织外键

    @ManyToMany

    private Set memberSet// 用户表外键

    public Organization getOrganization() {

        return organization

    }

    @JsonBackReference

    public void setOrganization(Organization organization) {

        this.organization = organization

    }

}

@ManyToMany

Entity

@Table(name = "costume_member")

public class Member extends AbstractEntity {

    private static final long serialVersionUID = 1L

    @Column(nullable = false, length = 20)

    private String name

    @ManyToMany

    @JoinTable(joinColumns = { @JoinColumn(name = "member_id") }, inverseJoinColumns = {

            @JoinColumn(name = "department_id") }) //被控方表字段名

    private Set departmentSet// 部门表外键

    public Set getDepartmentSet() {

        return departmentSet

    }

    @JsonBackReference

    public void setDepartmentSet(Set departmentSet)

    {

        this.departmentSet = departmentSet

    }

}

HQL通过旅店名称查询旅店以及城市的所有信息 直接返回实体类

/**

* 关联查询

*

* @return

*/

@Query(value = "select new pers.zpw.domain.CityHohel(t1.name AS cityName,t2.name AS hotelName) from  TCity t1 left  join THotel t2 on t1.id=t2.city where t2.name =:name")

List findCityAndHotelByHQLResultObj(@Param("name") String name)

@Data

public class CityHohel {

        private String cityName

        private String hotelName

        public CityHohel(String cityName, String hotelName) {

            this.cityName = cityName

            this.hotelName = hotelName

        }

}

实例2

@Entity 

@Table(name="orders") 

public class Order { 

    private String orderid 

    private Float amount = 0f 

    private Set items = new HashSet() 

    @Id 

    @Column(length = 12) 

    public String getOrderid() { 

        return orderid 

    } 

    public void setOrderid(String orderid) { 

        this.orderid = orderid 

    } 

    @Column(nullable = false) 

    public Float getAmount() { 

        return amount 

    } 

    public void setAmount(Float amount) { 

        this.amount = amount 

    } 

@OneToMany(cascade = { CascadeType.REFRESH, CascadeType.PERSIST,CascadeType.MERGE, CascadeType.REMOVE },mappedBy ="order") //这里配置关系,并且确定关系维护端和被维护端。mappBy表示关系被维护端,只有关系端有权去更新外键。这里还有注意OneToMany默认的加载方式是赖加载。当看到设置关系中最后一个单词是Many,那么该加载默认为懒加载 

    public Set getItems() { 

        return items 

    } 

    public void setItems(Set items) { 

        this.items = items 

    } 

        /** 

          *该方法用于向order中加order项 

          /* 

    public void addOrderItem(OrderItem orderItem){ 

        orderItem.setOrder(this)//用关系维护端来维护关系 

        this.items.add(orderItem) 

    } 

}

@Entity 

public class OrderItem { 

    private Integer id 

    private String productName 

    private Float sellPrice = 0f 

    private Order order 

    @Id 

    @GeneratedValue 

    public Integer getId() { 

        return id 

    } 

    public void setId(Integer id) { 

        this.id = id 

    } 

    @Column(length = 40, nullable = false) 

    public String getProductName() { 

        return productName 

    } 

    public void setProductName(String productName) { 

        this.productName = productName 

    } 

    @Column(nullable = false) 

    public Float getSellPrice() { 

        return sellPrice 

    } 

    public void setSellPrice(Float sellPrice) { 

        this.sellPrice = sellPrice 

    } 

    @ManyToOne(cascade = {CascadeType.MERGE,CascadeType.REFRESH }, optional = true) 

    @JoinColumn(name="order_id")//这里设置JoinColum设置了外键的名字,并且orderItem是关系维护端 

    public Order getOrder() { 

        return order 

    } 

    public void setOrder(Order order) { 

        this.order = order 

    } 

缓存

  

    org.springframework.boot  

    spring-boot-starter-cache  

@Configuration  

@EnableCaching  

public class CacheConfig {  

}  

@Cacheable

Spring 在执行 @Cacheable 标注的方法前先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,执行该方法并将方法返回值放进缓存。

参数: value缓存名、 key缓存键值、 condition满足缓存条件、unless否决缓存条件

@Cacheable(value = "user", key = "#id")  

public User findById(final Long id) {  

    System.out.println("cache miss, invoke find by id, id:" + id)  

    for (User user : users) {  

        if (user.getId().equals(id)) {  

            return user  

        }  

    }  

    return null  

}  

@CachePut

和 @Cacheable 类似,但会把方法的返回值放入缓存中, 主要用于数据新增和修改方法。

@CachePut(value = "user", key = "#user.id")  

public User save(User user) {  

    users.add(user)  

    return user  

@CacheEvict

方法执行成功后会从缓存中移除相应数据。

参数: value缓存名、 key缓存键值、 condition满足缓存条件、 unless否决缓存条件、 allEntries是否移除所有数据(设置为true时会移除所有缓存)

@CacheEvict(value = "user", key = "#user.id") // 移除指定key的数据  

public User delete(User user) {  

    users.remove(user)  

    return user  

}  

@CacheEvict(value = "user", allEntries = true) // 移除所有数据  

public void deleteAll() {  

    users.clear()  

}  

spring.cache.type=none ***设置缓存无效化

集成EhCache

  

    net.sf.ehcache  

    ehcache  

         xsi:noNamespaceSchemaLocation="ehcache.xsd">  

      

src\main\resources/application.properties

spring.cache.ehcache.config=classpath:ehcache.xml

如果想自定义设置一些个性化参数时,通过Java Config形式配置。

@Configuration  

@EnableCaching  

public class CacheConfig {  

    @Bean  

    public CacheManager cacheManager() {  

        return new EhCacheCacheManager(ehCacheCacheManager().getObject())  

    }  

    @Bean  

    public EhCacheManagerFactoryBean ehCacheCacheManager() {  

        EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean()  

        cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"))  

        cmfb.setShared(true)  

        return cmfb  

    }  

}  

组合CacheManager

从多个CacheManager中轮询得到相应的Cache。

@Configuration  

@EnableCaching  

public class CacheConfig {  

    @Bean  

    public CacheManager compositeCacheManager(RedisTemplate redisTemplate) {  

        CompositeCacheManager cacheManager = new CompositeCacheManager(new ConcurrentMapCacheManager(), new SimpleCacheManager())  

        cacheManager.setFallbackToNoOpCache(false)  

        cacheManager.afterPropertiesSet()  

        return cacheManager  

    }  


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/7914452.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-11
下一篇2023-04-11

发表评论

登录后才能评论

评论列表(0条)

    保存