springData-JPA知识点总结

前几天总结springboot,挺大牛说集成JPA比较不错,于是就拿过来试试!

底层数据库操作笼统讲就是增删改查,例如JDBC模板,Hibernate,Mybaties,JPA。接下来尝试springBootJPA旅程

1. @Column(nullable = false)

内容扩展

  • unique=true是指这个字段的值在这张表里不能重复,所有记录值都要唯一,就像主键那样。

  • nullable=false是这个字段在保存时必需有值,不能还是null值就调用save去保存入库。

  • 这两个用法是不同的,需要看个人需要,互相不可取代,根据个人需要可以两个都设置也可以只设置其中一个。

  • hibernate常用方法介绍:

  1. delete(Object entity) 删除指定的持久化实例在程序中一般先用    Assert.notNull和 Assert.isTrue断言entity是否为空 和 entity的id是否大于0,否则事务回滚。再用get(Class entityClass,Serializable id,LockMode lockMode)加锁查询出持久化实例,一般用lockMode.update悲观锁,最后用delete(Object entity)来删除此实例。

  2. deleteAll(Collection entities) 删除集合内全部持久化实例entities必须为持久化实例,否则报数据库异常错误。

  3. find(String queryString) 根据HQL查询字符串来返回实例集合find方法在执行时会先查找缓存,如果缓存找不到再查找数据库,如果再找不到就会返回null。

  4. get(Class entityClass,Serializable id)根据主键加载特定持久化实例在程序中一般先用     Assert.isTrue断言id是否大于0,若大于0继续执行,若查到数据则返回实例,否则返回空不同于load,load若有数据则返回实例,否则报出ObjectNotFoundEcception异常,相比来说get效率高些。

  5. save(Object entity) 保存新的实例,在程序中一般先用    Assert.notNull断言实体是否为空,在进行保存。


@Query

1. 一个使用@Query注解的简单例子

@Query(value = "select name,author,price from Book b where b.price>?1 and b.price findByPriceRange(long price1, long price2);

 

2.  Like表达式

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

 

3. 使用Native SQL Query

所谓本地查询,就是使用原生的sql语句(根据数据库的不同,在sql的语法或结构方面可能有所区别)进行查询数据库的操作。

@Query(value = "select * from book b where b.name=?1", nativeQuery = true)
List findByName(String name);

 

4. 使用@Param注解注入参数

@Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price")
List findByNamedParam(@Param("name") String name, @Param("author") String author,
        @Param("price") long price);

 

5. SPEL表达式(使用时请参考最后的补充说明)

   '#{#entityName}'值为'Book'对象对应的数据表名称(book)。

public interface BookQueryRepositoryExample extends Repository{

       @Query(value = "select * from #{#entityName} b where b.name=?1", nativeQuery = true)
       List findByName(String name);

}

 

6. 一个较完整的例子

复制代码
复制代码
public interface BookQueryRepositoryExample extends Repository {
    @Query(value = "select * from Book b where b.name=?1", nativeQuery = true) 
    List findByName(String name);// 此方法sql将会报错(java.lang.IllegalArgumentException),看出原因了吗,若没看出来,请看下一个例子

    @Query(value = "select name,author,price from Book b where b.price>?1 and b.price findByPriceRange(long price1, long price2);

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

    @Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price")
    List findByNamedParam(@Param("name") String name, @Param("author") String author,
            @Param("price") long price);

}
复制代码
复制代码

 

7.  解释例6中错误的原因:

     因为指定了nativeQuery = true,即使用原生的sql语句查询。使用java对象'Book'作为表名来查自然是不对的。只需将Book替换为表名book。

@Query(value = "select * from book b where b.name=?1", nativeQuery = true)
List findByName(String name);

 

 

补充说明(2017-01-12):

  有同学提出来了,例子5中用'#{#entityName}'为啥取不到值啊?

  先来说一说'#{#entityName}'到底是个啥。从字面来看,'#{#entityName}'不就是实体类的名称么,对,他就是。

  实体类Book,使用@Entity注解后,spring会将实体类Book纳入管理。默认'#{#entityName}'的值就是'Book'。

  但是如果使用了@Entity(name = "book")来注解实体类Book,此时'#{#entityName}'的值就变成了'book'。

  到此,事情就明了了,只需要在用@Entity来注解实体类时指定name为此实体类对应的表名。在原生sql语句中,就可以把'#{#entityName}'来作为数据表名使用。


你可能感兴趣的:(springData-JPA知识点总结)