今天系统看了一下hibernate实战查询的前两章,感觉写的非常好,结合Spring
,认为以下几点比较常用。
系统:Ubuntu IDE: IDEA 框架:Spring
绑定参数
绑定定位参数
1 2 3 4 5
| public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.emailAddress = ?1") User findByEmailAddress(String emailAddress); }
|
context中?1
是emailAddress
的索引,即对应的是第一个参数emailAddress。
绑定命名参数
1 2 3 4 5 6
| public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname") User findByLastnameOrFirstname(@Param("lastname") String lastname, @Param("firstname") String firstname); }
|
这段代码就很容易明白了。用@Param
注解给hql
语句中的参数命名。
限制查询
where
where
是用来写一些查询条件的。
1
| select u from User u where u.name = '山里的坏孩子'
|
IN
1 2 3 4 5 6 7 8 9
| List<String> ListName = new ArrayList<>(); ListName.add("zhangsan"); ListName.add("lisi"); public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.username in :listName") User findByListName(@Param("listName") List<String> listName); }
|
将返回用户名为zhangsan,lisi的User
LIKE
Like跟sql中没有什么区别,join%
是以join开头,%join
是以join结尾,%join%
是包含join的通配符。
1 2 3 4 5 6 7
| String firstName = "join"; public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.firstname like %?1") List<User> findByFirstnameEndsWith(String firstname); }
|
ORDER BY
排序 asc
升序,desc
降序。
1 2 3 4
| public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u order by u.firstname desc ") List<User> findByFirstname(); }
|
DISTINCT
数据库中可能有重复的记录,DISTINCT
关键字就是用来去重的。
1
| select distinct u from User u
|
集合的表达式
ONE
在查询的时候我们也会使用函数做一下简单的处理。hql
中还是给我们提供了一部分函数
1
| select u from User u where size(u.items) > 1
|
查出拥有物品数大于1的所有用户。
TWO
1 2 3 4
| public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where :item member of u.items") User findByLastnameOrFirstname(@Param("item") Item item); }
|
找出有item这个具体物品的所有用户
联结
显式联结
对于hql
的四种连接,请参考文章Spring中@Query实现hql的四种连接
ON
ON
只是用来添加联结的额外的联结条件。用where
也可以。
子查询
子查询是先执行子查询然后执行父查询。
1 2
| select u from User u where(select count(i) from Item i where i.seller = u)>1
|
取出买出商品多于一个的用户。
这个内查询是一个相关的子查询,他指的是一个来自外查询的别名(u)。
当然外查询也可以不相关。
防止sql注入攻击
我们讲一个sql注入的例子
1 2 3 4 5
| String searchString = getValueEnteredByUser(); //获取用户输入的搜国字段 Query query = em.createQuery( "select i from Item i where i.name = '" + searchString + "'" );
|
如果用户输入的是fooo' and callSomeStoredProcedure() and 'bar' = 'bar
。这样就不是一个简单的字符串搜索,话iahui执行数据库中的一个存储过程!
防止sql注入的最简单的方法就是不要拼凑sql语句和要对用户输入数据进行验证。
起别名
其中u
就是别名,是对象的引用,是为了方便查询条件中调用对象的属性,我们可以写成user
这个更容易辨别,但是我们说前辈们早已留下了规范,起别名的规范就是要简洁和简单,只要在本语句中唯一就可以。