Spring Data Jpa+Hibernate 入门2

来源:互联网 发布:艾媒咨询知乎 编辑:程序博客网 时间:2024/06/05 10:00

基于上一篇文章:入门

Repository:

package com.ncsi.SpringData.Repository;import java.util.List;import javax.persistence.QueryHint;import org.springframework.data.jpa.repository.Modifying;import org.springframework.data.jpa.repository.Query;import org.springframework.data.jpa.repository.QueryHints;import org.springframework.data.repository.Repository;import org.springframework.data.repository.query.Param;import org.springframework.transaction.annotation.Transactional;import com.ncsi.SpringData.Entity.Person;//Repository<Person,Integer> :person为实体类   Integer为主键的类型/** * 重要说明:这里我们不能使用别的方法名字。必须以 get 开头,by 是固定写法(拼接成方法名的时候首字母大写),表示一个连接词, * lastName 是 Person 类的一个属性(拼接成方法名的时候首字母大写)。 * @author P1311529 * */public interface PersonRepository  extends Repository<Person,Integer>{    Person getById(Integer id);    //根据lastName来获取对应的Person    Person getByLastName(String lastName);    //where  LastName like  ?% and id <?    List<Person> getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);    //where email in(?,?,?)  and id <?    List<Person> getByEmailInOrIdLessThan(List<String> emails ,Integer id);    //where  jpa_person.id>?    List<Person> getByIdGreaterThan(Integer id);    //查询最大的id    //使用@Query注解可以自定义JPQL语句,语句可以实现更灵活的查询     @Query("SELECT p FROM Person p WHERE p.id=(SELECT max(p2.id) FROM Person p2)")      Person getMaxIdPerson();      //为@Query注解传递参数的方式1:使用占位符    @QueryHints({@QueryHint(name = "org.hibernate.cacheable", value = "true")})    @Query("SELECT P FROM Person P where P.lastName=?1 AND P.email=?2")     List<Person> testQueryAnnotationParams1(String lastName,String email);     //为@Query注解传递参数的方式2:使用命名参数方式      @QueryHints({@QueryHint(name = "org.hibernate.cacheable", value = "true")})    @Query("SELECT P FROM Person P where P.lastName=:lastName AND P.email=:email")      List<Person> testQueryAnnotationParams2(@Param("email")String email,@Param("lastName")String lastName);    //Spring  data 在运行时添加占位符%%    @QueryHints({@QueryHint(name = "org.hibernate.cacheable", value = "true")})    @Query("select P from Person P where P.lastName like %?1% and P.email like %?2%")    List<Person> testQueryAnnotationLikeParam(String lastName,String email);    //使用nativeQuery=true 就可以使用源生sql    @Query(value="select count(id) from jpa_person",nativeQuery=true)    public long getTotalNumber();    //可以通过自定义的JPQL 完成update和delete操作,注意:JPQL不支持Insert操作      //在@Query注解中编写JPQL语句,但必须使用@Modify进行修饰,以通知SpringData,这是一个Update或者Delete      //Update或者delete操作,需要使用事务,此时需要定义Service层,在service层的方法上添加事务操作      //默认情况下,SpringData的每个方法上有事务,但都是一个只读事务,他们不能完成修改操作      @Transactional    @Modifying    @Query("update from Person p set p.lastName=:lastName  where p.id=:id")    public void updateLastName(@Param("lastName")String lastName,@Param("id")Integer id);}

Tests:

package com.ncsi.SpringData;import java.util.ArrayList;import java.util.List;import javax.sql.DataSource;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.ncsi.SpringData.Entity.Person;import com.ncsi.SpringData.Repository.PersonRepository;public class DataSourceTest {        private ApplicationContext ctx;        private PersonRepository personRepository;        {            ctx = new ClassPathXmlApplicationContext("springdata.xml");            personRepository = ctx.getBean(PersonRepository.class);        }        @Test        public void testDataSource(){            DataSource dataSource = (DataSource) ctx.getBean("dataSource");            System.out.println(dataSource);        }        @Test        public void testJPA(){        }        @Test        public void testHelloWorldSpringData() {            System.out.println(personRepository.getClass().getName());            Person person = personRepository.getById(1);            System.out.println(person);             Person person2=personRepository.getByLastName("liu");             System.out.println("----华丽的分割线");             System.out.println(person2);        }        @Test        public void testgetByLastNameStaringWithAndIdLessThan(){            List<Person> ListPerson =personRepository.getByLastNameStartingWithAndIdLessThan("l",3);            System.out.println(ListPerson);        }        @Test        public void testgetByEmialInOrIdLessThan(){            List<String> emails =new ArrayList<String>();            emails.add("@qq.com");            emails.add("@qq.com1");            List<Person> persons =personRepository.getByEmailInOrIdLessThan(emails, 4);            System.out.println(persons);        }        @Test        public void testgetByIdGreaterThan(){            List<Person> persons=personRepository.getByIdGreaterThan(4);            System.out.println(persons);        }        @Test         public void testgetMaxIdPerson(){            Person p =personRepository.getMaxIdPerson();            System.out.println(p);        }        @Test        public void testAnnationparams(){            List<Person> p=personRepository.testQueryAnnotationParams1("liu", "@qq.com");            System.out.println(p);            List<Person> p2=personRepository.testQueryAnnotationParams2("@qq.com", "liu");            System.out.println(p2);            List<Person> p3=personRepository.testQueryAnnotationLikeParam("li", "1");            System.out.println(p3);        }        @Test          public void testQueryLikeAnnotationParam(){              List<Person> persons=personRepository.testQueryAnnotationLikeParam("%l%", "%@qq.c%");              System.out.println(persons);          }        @Test        public void testModifying(){            personRepository.updateLastName("liu", 5);        }    }

1.什么是SpringData?

Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。

2.Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:

And — 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
Or — 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
Between — 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
LessThan — 等价于 SQL 中的 “<”,比如 findBySalaryLessThan(int max);
GreaterThan — 等价于 SQL 中的”>”,比如 findBySalaryGreaterThan(int min);
IsNull — 等价于 SQL 中的 “is null”,比如 findByUsernameIsNull();
IsNotNull — 等价于 SQL 中的 “is not null”,比如 findByUsernameIsNotNull();
NotNull — 与 IsNotNull 等价;
Like — 等价于 SQL 中的 “like”,比如 findByUsernameLike(String user);
NotLike — 等价于 SQL 中的 “not like”,比如 findByUsernameNotLike(String user);
OrderBy — 等价于 SQL 中的 “order by”,比如 findByUsernameOrderBySalaryAsc(String user);
Not — 等价于 SQL 中的 “! =”,比如 findByUsernameNot(String user);
In — 等价于 SQL 中的 “in”,比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
NotIn — 等价于 SQL 中的 “not in”,比如 findByUsernameNotIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;


其实这就是Spring Data JPA为我们封装了,只要按照Spring Data JPA的规范来定义,就会自动为我们生成一个默认的代理实现类。

3.Repository 接口

?基础的 Repository提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:
–Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类
–CrudRepository:继承Repository,实现了一组CRUD相关的方法
–PagingAndSortingRepository:继承CrudRepository,实现了一组分页排序相关的方法
–JpaRepository:继承PagingAndSortingRepository,实现一组JPA规范相关的方法
–自定义的 XxxxRepository需要继承 JpaRepository,这样的XxxxRepository接口就具备了通用的数据访问控制层的能力。
–JpaSpecificationExecutor:不属于Repository体系,实现一组JPACriteria查询相关的方法

4.@Query 注解

?这种查询可以声明在 Repository方法中,摆脱像命名查询那样的约束,将查询直接在相应的接口方法中声明,结构更为清晰,这是Springdata 的特有实现。
//查询id值最大的那个person
//使用@Query注解可以自定义JPQL语句,语句可以实现更灵活的查询
@Query(“SELECT p FROM Person p WHERE p.id=(SELECT max(p2.id) FROM Person p2)”)
Person getMaxIdPerson();

5.@Modifying 注解
@Query 与 @Modifying这两个annotation一起声明,可定义个性化更新操作,例如只涉及某些字段更新时最为常用,示例如下
//可以通过自定义的JPQL 完成update和delete操作,注意:JPQL不支持Insert操作
//在@Query注解中编写JPQL语句,但必须使用@Modify进行修饰,以通知SpringData,这是一个Update或者Delete
//Update或者delete操作,需要使用事务,此时需要定义Service层,在service层的方法上添加事务操作
//默认情况下,SpringData的每个方法上有事务,但都是一个只读事务,他们不能完成修改操作
@Transactional
@Modifying
@Query(“update Person p set p.email=:email where id=:id”)
void updatePersonEmail(@Param(“id”)Integer id,@Param(“email”)String email);

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: table is not Mapped

在写sql语句时 repository中
//查询最大的id

@Query("SELECT p FROM Person p WHERE p.id=(SELECT max(p2.id) FROM Person p2)")  Person getMaxIdPerson();  

表不是数据库中的表,而是实体类 通过@Table 才能与数据库关联

原创粉丝点击