jpa+springdata
学习爱酷学习网尚硅谷springdata笔记:
1.在 Spring 配置文件
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:jpa="http://www.springframework.org/schema/data/jpa"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
- <!-- 配置自动扫描的包 -->
- <context:component-scan base-package="com.atguigu.springdata"></context:component-scan>
- <!-- 1. 配置数据源 -->
- <context:property-placeholder location="classpath:db.properties"/>
- <bean id="dataSource"
- class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <property name="user" value="${jdbc.user}"></property>
- <property name="password" value="${jdbc.password}"></property>
- <property name="driverClass" value="${jdbc.driverClass}"></property>
- <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
- <!-- 配置其他属性 -->
- </bean>
- <!-- 2. 配置 JPA 的 EntityManagerFactory -->
- <bean id="entityManagerFactory"
- class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
- <property name="dataSource" ref="dataSource"></property>
- <property name="jpaVendorAdapter">
- <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
- </property>
- <property name="packagesToScan" value="com.atguigu.springdata"></property>
- <property name="jpaProperties">
- <props>
- <!-- 二级缓存相关 -->
- <!--
- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
- <prop key="net.sf.ehcache.configurationResourceName">ehcache-hibernate.xml</prop>
- -->
- <!-- 生成的数据表的列的映射策略 -->
- <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
- <!-- hibernate 基本属性 -->
- <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
- <prop key="hibernate.show_sql">true</prop>
- <prop key="hibernate.format_sql">true</prop>
- <prop key="hibernate.hbm2ddl.auto">update</prop>
- </props>
- </property>
- </bean>
- <!-- 3. 配置事务管理器 -->
- <bean id="transactionManager"
- class="org.springframework.orm.jpa.JpaTransactionManager">
- <property name="entityManagerFactory" ref="entityManagerFactory"></property>
- </bean>
- <!-- 4. 配置支持注解的事务 -->
- <tx:annotation-driven transaction-manager="transactionManager"/>
- <!-- 5. 配置 SpringData -->
- <!-- 加入 jpa 的命名空间 -->
- <!-- base-package: 扫描 Repository Bean 所在的 package -->
- <jpa:repositories base-package="com.atguigu.springdata"
- entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
- </beans>
其中db.properties
- jdbc.user=root
- jdbc.password=1111
- jdbc.driverClass=com.mysql.jdbc.Driver
- jdbc.jdbcUrl=jdbc:mysql://localhost:3306/springdata
测试类:
- package com.atguigu.springdata.test;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.List;
- import javax.persistence.criteria.CriteriaBuilder;
- import javax.persistence.criteria.CriteriaQuery;
- import javax.persistence.criteria.Path;
- import javax.persistence.criteria.Predicate;
- import javax.persistence.criteria.Root;
- import javax.sql.DataSource;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.PageRequest;
- import org.springframework.data.domain.Sort;
- import org.springframework.data.domain.Sort.Direction;
- import org.springframework.data.domain.Sort.Order;
- import org.springframework.data.jpa.domain.Specification;
- import com.atguigu.springdata.Person;
- import com.atguigu.springdata.PersonRepsotory;
- import com.atguigu.springdata.PersonService;
- import com.atguigu.springdata.commonrepositorymethod.AddressRepository;
- public class SpringDataTest {
- private ApplicationContext ctx = null;
- private PersonRepsotory personRepsotory = null;
- private PersonService personService;
- {
- ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- personRepsotory = ctx.getBean(PersonRepsotory.class);
- personService = ctx.getBean(PersonService.class);
- }
- //使用自定义的方法,需要声明接口,并继承,同时完成实现类,此方法比较少用
- @Test
- public void testCustomRepositoryMethod(){
- personRepsotory.test();
- }
- /**
- * 目标: 实现带查询条件的分页. id > 5 的条件
- *
- * 调用 JpaSpecificationExecutor 的 Page<T> findAll(Specification<T> spec, Pageable pageable);
- * Specification: 封装了 JPA Criteria 查询的查询条件
- * Pageable: 封装了请求分页的信息: 例如 pageNo, pageSize, Sort
- */
- //使用继承JpaSpecificationExecutor的方法实现条件查询+分页
- @Test
- public void testJpaSpecificationExecutor(){
- int pageNo = 3 - 1;
- int pageSize = 5;
- PageRequest pageable = new PageRequest(pageNo, pageSize);
- //通常使用 Specification 的匿名内部类
- Specification<Person> specification = new Specification<Person>() {
- /**
- * @param *root: 代表查询的实体类.
- * @param query: 可以从中可到 Root 对象, 即告知 JPA Criteria 查询要查询哪一个实体类. 还可以
- * 来添加查询条件, 还可以结合 EntityManager 对象得到最终查询的 TypedQuery 对象.
- * @param *cb: CriteriaBuilder 对象. 用于创建 Criteria 相关对象的工厂. 当然可以从中获取到 Predicate 对象
- * @return: *Predicate 类型, 代表一个查询条件.
- */
- @Override
- public Predicate toPredicate(Root<Person> root,
- CriteriaQuery<?> query, CriteriaBuilder cb) {
- Path path = root.get("id");
- Predicate predicate = cb.gt(path, 5);
- return predicate;
- }
- };
- Page<Person> page = personRepsotory.findAll(specification, pageable);
- System.out.println("总记录数: " + page.getTotalElements());
- System.out.println("当前第几页: " + (page.getNumber() + 1));
- System.out.println("总页数: " + page.getTotalPages());
- System.out.println("当前页面的 List: " + page.getContent());
- System.out.println("当前页面的记录数: " + page.getNumberOfElements());
- }
- //使用继承JpaRepository的方法
- @Test
- public void testJpaRepository(){
- Person person = new Person();
- person.setBirth(new Date());
- person.setEmail("xy@atguigu.com");
- person.setLastName("xyz");
- person.setId(28);
- Person person2 = personRepsotory.saveAndFlush(person);
- System.out.println(person == person2);
- }
- //使用继承PagingAndSortingRespository的方法,实现分页
- @Test
- public void testPagingAndSortingRespository(){
- //pageNo 从 0 开始.
- int pageNo = 6 - 1;
- int pageSize = 5;
- //Pageable 接口通常使用的其 PageRequest 实现类. 其中封装了需要分页的信息
- //排序相关的. Sort 封装了排序的信息
- //Order 是具体针对于某一个属性进行升序还是降序.
- Order order1 = new Order(Direction.DESC, "id");
- Order order2 = new Order(Direction.ASC, "email");
- Sort sort = new Sort(order1, order2);
- PageRequest pageable = new PageRequest(pageNo, pageSize, sort);
- Page<Person> page = personRepsotory.findAll(pageable);
- System.out.println("总记录数: " + page.getTotalElements());
- System.out.println("当前第几页: " + (page.getNumber() + 1));
- System.out.println("总页数: " + page.getTotalPages());
- System.out.println("当前页面的 List: " + page.getContent());
- System.out.println("当前页面的记录数: " + page.getNumberOfElements());
- }
- //使用继承CrudReposiory的方法
- @Test
- public void testCrudReposiory(){
- List<Person> persons = new ArrayList<>();
- for(int i = 'a'; i <= 'z'; i++){
- Person person = new Person();
- person.setAddressId(i + 1);
- person.setBirth(new Date());
- person.setEmail((char)i + "" + (char)i + "@atguigu.com");
- person.setLastName((char)i + "" + (char)i);
- persons.add(person);
- }
- personService.savePersons(persons);
- }
- @Test
- public void testModifying(){
- // personRepsotory.updatePersonEmail(1, "mmmm@atguigu.com");
- personService.updatePersonEmail("mmmm@atguigu.com", 1);
- }
- //设置 nativeQuery=true 即可以使用原生的 SQL 查询
- @Test
- public void testNativeQuery(){
- long count = personRepsotory.getTotalCount();
- System.out.println(count);
- }
- //使用 @Query 几种传递参数的方式
- @Test
- public void testQueryAnnotationLikeParam(){
- // List<Person> persons = personRepsotory.testQueryAnnotationLikeParam("%A%", "%bb%");
- // System.out.println(persons.size());
- // List<Person> persons = personRepsotory.testQueryAnnotationLikeParam("A", "bb");
- // System.out.println(persons.size());
- List<Person> persons = personRepsotory.testQueryAnnotationLikeParam2("bb", "A");
- System.out.println(persons.size());
- }
- @Test
- public void testQueryAnnotationParams2(){
- List<Person> persons = personRepsotory.testQueryAnnotationParams2("aa@atguigu.com", "AA");
- System.out.println(persons);
- }
- @Test
- public void testQueryAnnotationParams1(){
- List<Person> persons = personRepsotory.testQueryAnnotationParams1("AA", "aa@atguigu.com");
- System.out.println(persons);
- }
- //使用 @Query 注解可以自定义 JPQL 语句以实现更灵活的查询
- @Test
- public void testQueryAnnotation(){
- Person person = personRepsotory.getMaxIdPerson();
- System.out.println(person);
- }
- //根据外键条件查询,注意下划线的使用,若无下滑线,将优先获取person的属性,下滑线则表示为外键
- @Test
- public void testKeyWords2(){
- List<Person> persons = personRepsotory.getByAddress_IdGreaterThan(1);
- System.out.println(persons);
- }
- //几种条件查询的例子
- @Test
- public void testKeyWords(){
- List<Person> persons = personRepsotory.getByLastNameStartingWithAndIdLessThan("X", 10);
- System.out.println(persons);
- persons = personRepsotory.getByLastNameEndingWithAndIdLessThan("X", 10);
- System.out.println(persons);
- persons = personRepsotory.getByEmailInAndBirthLessThan(Arrays.asList("AA@atguigu.com", "FF@atguigu.com",
- "SS@atguigu.com"), new Date());
- System.out.println(persons.size());
- }
- //获取lastname为AA的person
- @Test
- public void testHelloWorldSpringData() throws FileNotFoundException, IOException, InstantiationException, IllegalAccessException{
- System.out.println(personRepsotory.getClass().getName());
- Person person = personRepsotory.getByLastName("AA");
- System.out.println(person);
- }
- //验证数据库连接是否成功
- @Test
- public void testDataSource() throws SQLException {
- DataSource dataSource = ctx.getBean(DataSource.class);
- System.out.println(dataSource.getConnection());
- }
- }
持久层类:
- package com.atguigu.springdata;
- import java.util.Date;
- import java.util.List;
- import org.springframework.data.jpa.repository.JpaRepository;
- import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
- import org.springframework.data.jpa.repository.Modifying;
- import org.springframework.data.jpa.repository.Query;
- import org.springframework.data.repository.query.Param;
- /**
- * 1. Repository 是一个空接口. 即是一个标记接口
- * 2. 若我们定义的接口继承了 Repository, 则该接口会被 IOC 容器识别为一个 Repository Bean.
- * 纳入到 IOC 容器中. 进而可以在该接口中定义满足一定规范的方法.
- *
- * 3. 实际上, 也可以通过 @RepositoryDefinition 注解来替代继承 Repository 接口
- */
- /**
- * 在 Repository 子接口中声明方法
- * 1. 不是随便声明的. 而需要符合一定的规范
- * 2. 查询方法以 find | read | get 开头
- * 3. 涉及条件查询时,条件的属性用条件关键字连接
- * 4. 要注意的是:条件属性以首字母大写。
- * 5. 支持属性的级联查询. 若当前类有符合条件的属性, 则优先使用, 而不使用级联属性.
- * 若需要使用级联属性, 则属性之间使用 _ 进行连接.
- */
- //@RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)
- public interface PersonRepsotory extends
- JpaRepository<Person, Integer>,
- JpaSpecificationExecutor<Person>, PersonDao{
- //根据 lastName 来获取对应的 Person
- Person getByLastName(String lastName);
- //WHERE lastName LIKE ?% AND id < ?
- List<Person> getByLastNameStartingWithAndIdLessThan(String lastName, Integer id);
- //WHERE lastName LIKE %? AND id < ?
- List<Person> getByLastNameEndingWithAndIdLessThan(String lastName, Integer id);
- //WHERE email IN (?, ?, ?) OR birth < ?
- List<Person> getByEmailInAndBirthLessThan(List<String> emails, Date birth);
- //WHERE a.id > ?
- List<Person> getByAddress_IdGreaterThan(Integer id);
- //查询 id 值最大的那个 Person
- //使用 @Query 注解可以自定义 JPQL 语句以实现更灵活的查询
- @Query("SELECT p FROM Person p WHERE p.id = (SELECT max(p2.id) FROM Person p2)")
- Person getMaxIdPerson();
- //为 @Query 注解传递参数的方式1: 使用占位符.
- @Query("SELECT p FROM Person p WHERE p.lastName = ?1 AND p.email = ?2")
- List<Person> testQueryAnnotationParams1(String lastName, String email);
- //为 @Query 注解传递参数的方式1: 命名参数的方式.
- @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);
- //SpringData 允许在占位符上添加 %%.
- @Query("SELECT p FROM Person p WHERE p.lastName LIKE %?1% OR p.email LIKE %?2%")
- List<Person> testQueryAnnotationLikeParam(String lastName, String email);
- //SpringData 允许在占位符上添加 %%.
- @Query("SELECT p FROM Person p WHERE p.lastName LIKE %:lastName% OR p.email LIKE %:email%")
- List<Person> testQueryAnnotationLikeParam2(@Param("email") String email, @Param("lastName") String lastName);
- //设置 nativeQuery=true 即可以使用原生的 SQL 查询
- @Query(value="SELECT count(id) FROM jpa_persons", nativeQuery=true)
- long getTotalCount();
- //可以通过自定义的 JPQL 完成 UPDATE 和 DELETE 操作. 注意: JPQL 不支持使用 INSERT
- //在 @Query 注解中编写 JPQL 语句, 但必须使用 @Modifying 进行修饰. 以通知 SpringData, 这是一个 UPDATE 或 DELETE 操作
- //UPDATE 或 DELETE 操作需要使用事务, 此时需要定义 Service 层. 在 Service 层的方法上添加事务操作.
- //默认情况下, SpringData 的每个方法上有事务, 但都是一个只读事务. 他们不能完成修改操作!
- @Modifying
- @Query("UPDATE Person p SET p.email = :email WHERE id = :id")
- void updatePersonEmail(@Param("id") Integer id, @Param("email") String email);
- }
自定义方法时,声明的接口:
- package com.atguigu.springdata;
- public interface PersonDao {
- void test();
- }
其实现类:使用原生entityManager
- package com.atguigu.springdata;
- import javax.persistence.EntityManager;
- import javax.persistence.PersistenceContext;
- public class PersonRepsotoryImpl implements PersonDao {
- @PersistenceContext
- private EntityManager entityManager;
- @Override
- public void test() {
- Person person = entityManager.find(Person.class, 11);
- System.out.println("-->" + person);
- }
- }
PersonService:用于测试需要事务包裹的方法
- package com.atguigu.springdata;
- import java.util.List;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- @Service
- public class PersonService {
- @Autowired
- private PersonRepsotory personRepsotory;
- @Transactional
- public void savePersons(List<Person> persons){
- personRepsotory.save(persons);
- }
- @Transactional
- public void updatePersonEmail(String email, Integer id){
- personRepsotory.updatePersonEmail(id, email);
- }
- }
与数据库表单对应的实体类:
- package com.atguigu.springdata;
- import java.util.Date;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.ManyToOne;
- import javax.persistence.Table;
- @Table(name="JPA_PERSONS")
- @Entity
- public class Person {
- private Integer id;
- private String lastName;
- private String email;
- private Date birth;
- private Address address;
- private Integer addressId;
- @GeneratedValue
- @Id
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getLastName() {
- return lastName;
- }
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
- public String getEmail() {
- return email;
- }
- public void setEmail(String email) {
- this.email = email;
- }
- public Date getBirth() {
- return birth;
- }
- public void setBirth(Date birth) {
- this.birth = birth;
- }
- @Column(name="ADD_ID")
- public Integer getAddressId() {
- return addressId;
- }
- public void setAddressId(Integer addressId) {
- this.addressId = addressId;
- }
- @JoinColumn(name="ADDRESS_ID")
- @ManyToOne
- public Address getAddress() {
- return address;
- }
- public void setAddress(Address address) {
- this.address = address;
- }
- @Override
- public String toString() {
- return "Person [id=" + id + ", lastName=" + lastName + ", email="
- + email + ", brith=" + birth + "]";
- }
- }
- package com.atguigu.springdata;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.Table;
- @Table(name="JPA_ADDRESSES")
- @Entity
- public class Address {
- private Integer id;
- private String province;
- private String city;
- @GeneratedValue
- @Id
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getProvince() {
- return province;
- }
- public void setProvince(String province) {
- this.province = province;
- }
- public String getCity() {
- return city;
- }
- public void setCity(String city) {
- this.city = city;
- }
- }
使用的jar包:
项目结构:
补充:
jpa+springdata的更多相关文章
- JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 1
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7703679.html ------------------------------------ ...
- JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 2
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7704914.html ------------------------------------ ...
- JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 3
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7718741.html ------------------------------------ ...
- JPA + SpringData 操作数据库 ---- 深入了解 SpringData
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7735616.html ------------------------------------ ...
- (转)JPA + SpringData
jpa + spring data 约定优于配置 convention over configuration http://www.cnblogs.com/crawl/p/7703679.html 原 ...
- JPA + SpringData 操作数据库--Helloworld实例
前言:谈起操作数据库,大致可以分为几个阶段:首先是 JDBC 阶段,初学 JDBC 可能会使用原生的 JDBC 的 API,再然后可能会使用数据库连接池,比如:c3p0.dbcp,还有一些第三方工具, ...
- SpringMVC+JPA+SpringData配置
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> ...
- Spring、SpringMVC、SpringData + JPA 整合详解
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7759874.html ------------------------------------ ...
- SpringBoot图文教程12—SpringData Jpa的基本使用
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
随机推荐
- 原生Ajax总结
HTTP协议 传统的请求和Ajax请求 Ajax定义 Asynchronous JavaScript and XML. Ajax异步的,JavaScript程序希望与服务器直接通信而不需要重新加载页面 ...
- Ios生产证书申请(含推送证书)
一.Mac机上生成请求文件. Mac机上点击证书助手 => 从证书颁发机构请求证书 => 得到CertificateSigningRequest.certSigningRequest请求文 ...
- Android5.0以下出现NoClassDefFoundError
事发起因 大周末的,突然接到老大的电话说很多用户无法安装新上线的APK,让我紧急Fix(现Android项目就我一己之力).但奇怪的是也没有Bug Reporter,而且开发过程中也一直没问题.根据上 ...
- 4.C#WinForm基础图片(显示和隐藏)
要求: 软件上有一张图片,默认是隐藏的.用户在文本框中输入身份证号(131226198105223452),点击按钮,如果年龄大于18岁,则显示图片. 知识点: 取当前年份,Date Time Now ...
- ASP.NET 截获服务器生成的将要发送到客户端的html的方法
有时候我们需要在将服务器端生成的html发送带客户端之前对这些html进行操作,比如生成静态html加之保存.改变生成的html中的某些内容等等,那么久可以通过如下的方案解决. 我总结了两种方式,个人 ...
- JSTL标签 参考手册
前言 ========================================================================= JSTL标签库,是日常开发经常使用的,也是众多 ...
- 《高性能javascript》 领悟随笔之-------DOM编程篇
<高性能javascript> 领悟随笔之-------DOM编程篇一 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...
- PHP基础知识第三趴
今天如约放送函数部分吧,毕竟预告都出了,"广电"也没禁我......
- 用jmeter通过ssl验证访问https
找了一个支付宝的网站尝试.https://memberprod.alipay.com/account/reg/index.htm 我用的是chrome,点这个小锁 如果是IE也可以在网页上右键,属性, ...
- Maven+Spring+Spring MVC+MyBatis+MySQL,搭建SSM框架环境【转】
项目建设完成之后的结构: 数据库的表结构如下: 环境建设:搭建Maven环境.Tomcat环境.需要MySql 数据库支持,使用的编程工具Eclipse (这些是前期准备): 开始创建工程: 1.创建 ...