文章目录

  • 1 概述
  • 2 Hibernate 增删改查
  • 3 Spring Data JPA
    • 3.1 概述
    • 3.2 增删改查
    • 3.3 原理

1 概述

  1. JPA的全称是Java Persistence API, 即Java持久化API,内部是由一系列的接口和抽象类构成。

  2. JPA优势

    1. 标准化:JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
    2. 容器级特性的支持:JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
    3. 简单方便:JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity 进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成
    4. 查询能力:JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
    5. 高级特性:JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
  3. JPA 和 Hibernate 关系

    1. JPA规范本质上就是一种ORM规范,注意不是ORM框架,因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。

    2. JPA 和 Hibernate 的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现

    3. 图解

2 Hibernate 增删改查

  • 下面例子主要讲 JPA 基于 Hibernate 方式实现增删改查。下面会讲 Spring Data JPA,这个才是学习的重点。但 Hibernate 和 Spring Data JPA 类似,因此可以了解下 Hibernate。

  • 常用注解说明

    注解 说明 属性说明
    @Entity 指定当前类是实体类
    (一般情况下,实体类属性与数据库字段一一对应)
    @Table 指定实体类和表之间的对应关系 name 属性用于指定表名
    @Id 指定当前字段是主键
    @GeneratedValue 指定主键的生成方式 strategy 属性用于指定主键生成策略
    @Column 指定实体类属性和数据库表之间的对应关系 name 指定数据库表的列名称
    unique 是否唯一
    nullable 是否可以为空
    insertable 是否可以插入
    updateable 是否可以更新
    columnDefinition 定义建表时创建此列的DDL
    @SecondaryTable 从表名

项目搭建

  • SQL脚本

    CREATE TABLE `t_users`(`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(64) NOT NULL DEFAULT '',`gender` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1 male,2 female',`age` int(11) NOT NULL DEFAULT '0',`telphone` varchar(255) NOT NULL DEFAULT '',`register_mode` varchar(255) NOT NULL DEFAULT '' COMMENT 'byphone,bywechat,byalipay',PRIMARY KEY (`id`),UNIQUE KEY `telphone_unique_index` (`telphone`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;INSERT INTO `t_users` VALUES(1,'zhangsan',1,30,'18362610001','byphone');
    INSERT INTO `t_users` VALUES(2,'lisi',1,20,'18362610002','byphone');
    INSERT INTO `t_users` VALUES(3,'wangwu',1,1,'18362610003','byphone');
    INSERT INTO `t_users` VALUES(4,'zhaoliu',1,31,'18362610004','byphone');
    INSERT INTO `t_users` VALUES(5,'xiaohong',2,20,'18362610005','byphone');
    
  • 项目结构如下

  1. 创建普通maven工程,并导入依赖

    <properties><hibernate.version>5.5.9.Final</hibernate.version><log4j.version>1.2.17</log4j.version><mysql.version>8.0.21</mysql.version><junit.version>4.13</junit.version><lombok.version>1.18.12</lombok.version>
    </properties>
    <dependencies><!-- hibernate对jpa的支持包 --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version></dependency><!-- c3p0 --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-c3p0</artifactId><version>${hibernate.version}</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>compile</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency>
    </dependencies>
    
  2. 配置文件

    • resources/META-INF/persistence.xml ,手动创建 META-INF 目录,必须为该路径、否则找不到配置文件!
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"><!-- 配置持久化单元格,transaction-type="RESOURCE_LOCAL"即本地事务管理,若改为JTA代表分布式事务管理--><persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL"><!--jpa的实现方式(由hibernate实现) --><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><properties><property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/><property name="javax.persistence.jdbc.url"value="jdbc:mysql://192.168.181.160:3306/test?serverTimezone=CTT"/><property name="javax.persistence.jdbc.user" value="root"/><property name="javax.persistence.jdbc.password" value="root"/><property name="hibernate.show_sql" value="true"/><property name="hibernate.hbm2ddl.auto" value="update"/><!--最后一行表示jpa实现方的配置信息name="hibernate.hbm2ddl.auto" 表示自动创建数据库表value="update" 即程序运行时创建表(如果有表,不会创建表),value="create"表示程序运行时创建数据库表(如果有表,先删除表再创建)value="none"表示不会创建表--></properties></persistence-unit>
    </persistence>
    
  3. 编写实体类

    package entity;import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    import javax.persistence.*;@Entity
    @Table(name = "t_users")
    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    public class UserEntity {@Id// 指定主键自增策略由数据库自动生成(主要是自动增长型)@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer id;@Column(name = "name")private String name;@Column(name = "gender")private Integer gender;@Column(name = "age")private Integer age;@Column(name = "telphone")private String telphone;@Column(name = "register_mode")private String registerMode;// 因为主键自增,故需要除主键外的构造函数(get、set方法用lombok注解生成)// 若是不要构造方法的话,set每个属性也可public UserEntity(String name, Integer gender, Integer age, String telphone, String registerMode) {this.name = name;this.gender = gender;this.age = age;this.telphone = telphone;this.registerMode = registerMode;}
    }
    
  4. 测试

    package test;import entity.UserEntity;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;import javax.persistence.*;
    import java.util.List;public class MyTest {private EntityManagerFactory factory;private EntityManager entityManager;private EntityTransaction tx;@Beforepublic void before() {/*** JPA 基于 Hibernate 方式实现增删改查的步骤如下** 1.加载配置文件创建工厂(实体管理器工厂)对象* 注:配置文件要写在META-INF/persistence.xml下,若是直接放在resources下找不到* 配置文件 persistence.xml 中 name="myJpa"*/factory = Persistence.createEntityManagerFactory("myJpa");// 2.通过实体管理器工厂获取实体管理器entityManager = factory.createEntityManager();// 3.获取事务对象tx = entityManager.getTransaction();// 4.开启事务tx.begin();// 5.完成增删改查操作(即下面的各个测试类)}@Afterpublic void after() {// 6.提交事务(回滚事务)tx.commit();// 7.释放资源entityManager.close();factory.close();}/*** 测试一:根据主键id进行查询*/@Testpublic void test1() {UserEntity user = entityManager.find(UserEntity.class, 2);System.out.println(user);// UserEntity(id=2, name=lisi, gender=1, age=20, telphone=18362610002, registerMode=byphone)}/*** 测试二:查询所有* 使用JPQL语法,注意此时操作的是实体类而不是表名,* 因此from对象是 UserEntity 而不是 t_users*/@Testpublic void test2() {String jpql = new String("from UserEntity");Query query = entityManager.createQuery(jpql);List list = query.getResultList();list.forEach(element -> System.out.println(element));/*** UserEntity(id=1, name=zhangsan, gender=1, age=30, telphone=18362610001, registerMode=byphone)* UserEntity(id=2, name=lisi, gender=1, age=20, telphone=18362610002, registerMode=byphone)* UserEntity(id=3, name=wangwu, gender=1, age=1, telphone=18362610003, registerMode=byphone)* UserEntity(id=4, name=zhaoliu, gender=1, age=31, telphone=18362610004, registerMode=byphone)* UserEntity(id=5, name=xiaohong, gender=2, age=20, telphone=18362610005, registerMode=byphone)*/}/*** 测试三:添加* <p>* persist():持久化即保存(添加)操作*/@Testpublic void test3() {UserEntity userEntity = new UserEntity("小明", 2, 18, "18362610009", "bywechat");entityManager.persist(userEntity);}/*** 测试四:删除* (先根据id查询账户,再删除)*/@Testpublic void test4() {UserEntity userEntity = entityManager.find(UserEntity.class, 3);entityManager.remove(userEntity);}/*** 测试五:修改* (先查,赋新值,清缓存[可省],修改)*/@Testpublic void test5() {UserEntity userEntity = entityManager.find(UserEntity.class, 5);userEntity.setName("小小红");entityManager.clear(); // 可省entityManager.merge(userEntity);}/*** 下面的查询可以看看,大部分就是换了个jpql* <p>* 测试六:分页查询*/@Testpublic void test6() {String jpql = new String("from UserEntity");Query query = entityManager.createQuery(jpql);// 设置起始索引和每页显示条数query.setFirstResult(0);query.setMaxResults(3);List list = query.getResultList();list.forEach(element -> System.out.println(element));/*** 结果* UserEntity(id=1, name=zhangsan, gender=1, age=30, telphone=18362610001, registerMode=byphone)* UserEntity(id=2, name=lisi, gender=1, age=20, telphone=18362610002, registerMode=byphone)* UserEntity(id=4, name=zhaoliu, gender=1, age=31, telphone=18362610004, registerMode=byphone)** ps:结果集的下标从0开始*/}/*** 测试七:条件查询*/@Testpublic void test7() {String jpql = new String("from UserEntity where name like ?1");Query query = entityManager.createQuery(jpql);// SQL中的 ?1 表示第一个参数,此处表示对第一个参数赋值query.setParameter(1, "%小%");List list = query.getResultList();for (Object obj : list) {System.out.println(obj);}/*** UserEntity(id=5, name=小小红, gender=2, age=20, telphone=18362610005, registerMode=byphone)* UserEntity(id=6, name=小明, gender=2, age=18, telphone=18362610009, registerMode=bywechat)*/}/*** 测试八:排序查询*/@Testpublic void test8() {String jpql = new String("from UserEntity order by id desc");Query query = entityManager.createQuery(jpql);List list = query.getResultList();list.forEach(e -> System.out.println(e));/*** UserEntity(id=6, name=小明, gender=2, age=18, telphone=18362610009, registerMode=bywechat)* UserEntity(id=5, name=小小红, gender=2, age=20, telphone=18362610005, registerMode=byphone)* UserEntity(id=4, name=zhaoliu, gender=1, age=31, telphone=18362610004, registerMode=byphone)* UserEntity(id=2, name=lisi, gender=1, age=20, telphone=18362610002, registerMode=byphone)* UserEntity(id=1, name=zhangsan, gender=1, age=30, telphone=18362610001, registerMode=byphone)*/}/*** 测试九:统计个数* <p>* getSingleResult():得到唯一结果集*/@Testpublic void test9() {String jpql = new String("select count(id) from UserEntity");Query query = entityManager.createQuery(jpql);Object count = query.getSingleResult();System.out.println("count = " + count);// count = 5}
    }
    

3 Spring Data JPA

3.1 概述

  • Spring Data JPAJPAHibernate 之间的关系如下
  1. JPA是一套规范,内部是由接口和抽象类组成的。
  2. Hibernate 是一套成熟的 ORM 框架,而且 Hibernate 实现了 JPA 规范,所以也可以称 Hibernate 为 JPA 的一种实现方式,我们使用 JPA 的 API 编程,意味着站在更高的角度上看待问题(面向接口编程)。
  3. Spring Data JPA 是 Spring 提供的一套对 JPA 操作更加高级的封装,是在 JPA 规范下的专门用来进行数据持久化的解决方案。

3.2 增删改查

  1. SQL脚本略,同上面的 Hibernate

    CREATE TABLE `t_users`(`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(64) NOT NULL DEFAULT '',`gender` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1 male,2 female',`age` int(11) NOT NULL DEFAULT '0',`telphone` varchar(255) NOT NULL DEFAULT '',`register_mode` varchar(255) NOT NULL DEFAULT '' COMMENT 'byphone,bywechat,byalipay',PRIMARY KEY (`id`),UNIQUE KEY `telphone_unique_index` (`telphone`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;INSERT INTO `t_users` VALUES(1,'zhangsan',1,30,'18362610001','byphone');
    INSERT INTO `t_users` VALUES(2,'lisi',1,20,'18362610002','byphone');
    INSERT INTO `t_users` VALUES(3,'wangwu',1,1,'18362610003','byphone');
    INSERT INTO `t_users` VALUES(4,'zhaoliu',1,31,'18362610004','byphone');
    INSERT INTO `t_users` VALUES(5,'xiaohong',2,20,'18362610005','byphone');
    
  2. 项目结构如下

  3. 创建普通maven工程,导入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn</groupId><artifactId>spring-data-jpa</artifactId><version>1.0-SNAPSHOT</version><properties><!--1. 最新版data-jpa的版本是2.6.0,但使用该版本时,各种依赖冲突问题,尝试许久也未解决,简直要人老命~2. 故使用较低版本的data-jpa进行项目搭建,该项目了解即可,以后都是使用springboot项目整合jpa了3. 另外,本项目中连接池 c3p0 也已经废弃了,由maven官网可知,2007年以后就不在更新维护了;若是其他项目使用连接池,可用 druid连接池 代替4. so,该项目看看即可,若是使用原生spring整合data jpa,升级版本时会遇到各种依赖冲突问题。自己解决可太难了,现在体会到springboot项目的强大了吧?!--><!-- <jpa.version>2.6.0</jpa.version> --><jpa.version>1.9.0.RELEASE</jpa.version><spring.version>5.2.19.RELEASE</spring.version><aspectj.version>1.9.7</aspectj.version><hibernate.version>5.5.9.Final</hibernate.version><slf4j.version>2.0.0-alpha5</slf4j.version><log4j.version>1.2.17</log4j.version><c3p0.version>0.9.1.2</c3p0.version><mysql.version>8.0.21</mysql.version><junit.version>4.12</junit.version><el.version>2.2.4</el.version><lombok.version>1.18.12</lombok.version><jaxb.version>3.0.2</jaxb.version></properties><dependencies><!-- spring 相关依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><!-- spring data 相关,引入该依赖后必需引入下面的俩 el 依赖 --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>${jpa.version}</version></dependency><dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>${el.version}</version></dependency><dependency><groupId>org.glassfish.web</groupId><artifactId>javax.el</artifactId><version>${el.version}</version></dependency><!-- hibernate 依赖(data jpa 需要配合 hibernate 使用) --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>${hibernate.version}</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version></dependency><!-- aspectJ依赖,aop需要用到--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${aspectj.version}</version></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- c3p0 连接池--><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>${c3p0.version}</version></dependency><!-- log 依赖--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency></dependencies><!--指定编译的字节码版本,自己使用的是jdk11,因此指定编译的版本为java11默认是java5,否则需要自己修改IDEA中的配置--><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version><configuration><source>11</source><target>11</target></configuration></plugin></plugins></build>
    </project>
    
  4. 配置文件

    <?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:jdbc="http://www.springframework.org/schema/jdbc"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.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/data/jpahttp://www.springframework.org/schema/data/jpa/spring-jpa.xsd"><!-- 1.配置数据源 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://192.168.192.134:3306/test?serverTimezone=CTT"/><property name="user" value="root"/><property name="password" value="root"/></bean><!-- 2.配置entityManagerFactory,并把它交给spring容器管理--><bean id="entityManagerFactoty" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource"/><!--配置的扫描的包(实体类所在的包) --><property name="packagesToScan" value="cn.entity"/><!-- jpa的实现厂家 --><property name="persistenceProvider"><bean class="org.hibernate.jpa.HibernatePersistenceProvider"/></property><!--jpa的供应商适配器 --><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><!--配置是否自动创建数据库表 --><property name="generateDdl" value="false"/><!--指定数据库类型 --><property name="database" value="MYSQL"/><!--数据库方言:支持的特有语法 --><property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/><!--是否显示sql --><property name="showSql" value="true"/></bean></property><!--jpa的方言 :高级的特性 --><property name="jpaDialect"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/></property></bean><!--3.配置事务管理器 --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactoty"/></bean><!--4.整合spring data JPA--><jpa:repositories base-package="cn.repository" transaction-manager-ref="transactionManager"entity-manager-factory-ref="entityManagerFactoty"/><!-- 5.txAdvice--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="save*" propagation="REQUIRED"/><tx:method name="insert*" propagation="REQUIRED"/><tx:method name="delete*" propagation="REQUIRED"/><tx:method name="update*" propagation="REQUIRED"/><tx:method name="get*" read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice><!-- 6.aop(切点定位到业务层实现类)--><aop:config><aop:pointcut id="pointcut" expression="execution(* cn.service.impl.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/></aop:config><!-- 7. 配置包扫描--><context:component-scan base-package="cn"/>
    </beans>
    
  5. 编写实体类

    package cn.entity;
    import lombok.Data;
    import javax.persistence.*;@Entity
    @Table(name = "t_users")
    @Data
    public class UserEntity {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer id;@Column(name = "name")private String name;@Column(name = "gender")private Integer gender;@Column(name = "age")private Integer age;@Column(name = "telphone")private String telphone;@Column(name = "register_mode")private String registerMode;
    }
    
  6. 编写持久层

    package cn.repository;import cn.entity.UserEntity;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;public interface UserRepository extends JpaRepository<UserEntity, Integer>, JpaSpecificationExecutor<UserEntity> {}
    
  7. 测试

    package test;import cn.entity.UserEntity;
    import cn.repository.UserRepository;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath:application.xml")
    public class MyTest {@Autowiredprivate UserRepository userRepository;/*** 测试添加*/@Testpublic void testSave() {UserEntity userEntity = new UserEntity();userEntity.setName("小明");userEntity.setGender(2);userEntity.setAge(22);userEntity.setTelphone("18362610009");userEntity.setRegisterMode("bywechat");userRepository.save(userEntity);}/*** 测试删除*/@Testpublic void testDelete() {userRepository.delete(6);}/*** 测试修改* <p>* 思路* 1. 先根据id查实体类* 2. 然后修改* 3. 最后调用save方法更新* <p>* save方法的解释:* 1. id在数据库中不存在,即为插入insert* 2. id在数据库中已存在,即为更新update*/@Testpublic void testUpdate() {UserEntity userEntity = userRepository.findOne(2);userEntity.setName("李小四");userEntity.setRegisterMode("bywechat");userRepository.save(userEntity);}/*** 测试查找(根据主键查)*/@Testpublic void testFindOne() {/*** 注:新版 data-jpa (version=2.6.0) 版本中* 接口有改动,应该用 UserEntity userEntity = userRepository.getById(1);* 但是自己使用原生Spring整合出现依赖冲突问题,简直要人老命~~~* 以后使用SpringBoot时,data-jpa改成最新版本*/UserEntity userEntity = userRepository.findOne(1);System.out.println(userEntity);// UserEntity(id=1, name=zhangsan, gender=1, age=30, telphone=18362610001, registerMode=byphone)}/*** 测试查找(查询所有)*/@Testpublic void testFindAll() {List<UserEntity> users = userRepository.findAll();for (UserEntity user : users) {System.out.println(user);}/*** UserEntity(id=1, name=zhangsan, gender=1, age=30, telphone=18362610001, registerMode=byphone)* UserEntity(id=2, name=lisi, gender=1, age=20, telphone=18362610002, registerMode=byphone)* UserEntity(id=3, name=wangwu, gender=1, age=1, telphone=18362610003, registerMode=byphone)* UserEntity(id=4, name=zhaoliu, gender=1, age=31, telphone=18362610004, registerMode=byphone)* UserEntity(id=5, name=xiaohong, gender=2, age=20, telphone=18362610005, registerMode=byphone)*/}
    }
    

IDEA 工具中,解决 “错误: 不支持发行版本 5”

  • 法一:修改项目配置

    1. File -> Project Structure -> Modules(则需修改)
    2. File -> Settings -> Build,Execution,Deployment -> Compiler -> Java Compiler -> Target bytecode version(则需修改)
  • 法二:pom文件中指定编译的字节码版本

    <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version><configuration><source>11</source><target>11</target></configuration></plugin></plugins>
    </build>
    

补充:SpringBoot 整合 JPA

  • 见以前博客 SpringBoot二:整合其他框架
  • 以后均用 SpringBoot 整合 JPA 使用,不再使用纯 Spring 整合 JPA,升级版本时、发生版本冲突要人老命~~~

3.3 原理

  1. 继承关系图

    • 上面持久层代码 UserRepository extends JpaRepository, JpaSpecificationExecutor (或由上图也可以看出),因此在 UserRepository 接口中,没有写一行代码,却能实现增删改查等基本操作。下面将对 JpaRepositoryJpaSpecificationExecutor 这俩接口中的方法进行介绍。
  2. JpaRepository :该接口封装了基本的CURD操作

    /*** 注:JpaRepository 继承 PagingAndSortingRepository,而 PagingAndSortingRepository 又继承 CrudRepository*/// 1. JpaRepository 接口源码
    public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {List<T> findAll();List<T> findAll(Sort var1);List<T> findAll(Iterable<ID> var1);<S extends T> List<S> save(Iterable<S> var1);void flush();<S extends T> S saveAndFlush(S var1);void deleteInBatch(Iterable<T> var1);void deleteAllInBatch();T getOne(ID var1);
    }// 2. PagingAndSortingRepository 接口源码
    public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {Iterable<T> findAll(Sort var1);Page<T> findAll(Pageable var1);
    }// 3. CrudRepository 接口源码
    public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {<S extends T> S save(S var1);<S extends T> Iterable<S> save(Iterable<S> var1);T findOne(ID var1);boolean exists(ID var1);Iterable<T> findAll();Iterable<T> findAll(Iterable<ID> var1);long count();void delete(ID var1);void delete(T var1);void delete(Iterable<? extends T> var1);void deleteAll();
    }
    
  3. JpaSpecificationExecutor :该接口封装了复杂的查询(如分页查询、动态SQL查询)等 【动态SQL是重点,后面会单独写文章介绍用法】

    public interface JpaSpecificationExecutor<T> {T findOne(Specification<T> var1);List<T> findAll(Specification<T> var1);Page<T> findAll(Specification<T> var1, Pageable var2);List<T> findAll(Specification<T> var1, Sort var2);long count(Specification<T> var1);
    }
    
  • 源码链接 blogs-jpa

JPA一:理论知识和入门程序相关推荐

  1. 关于mpi的理论知识以及编写程序来实现数据积分中的梯形积分法。

    几乎所有人的第一个程序是从"hello,world"程序开始学习的 #include "mpi.h" #include <stdio.h> int ...

  2. 软件测试理论知识(入门篇)

    一.测试基础 知识点1.软件生命周期 阶段 主要人员 主要任务 输出文档 计划 项目经理 指定整个项目的计划(目标.人员.预算) 项目计划 需求分析 产品经理.需求分析人员 进一步确定用户的需求 描述 ...

  3. 数据库入门理论知识介绍以及编译安装MySql

    数据库入门理论知识介绍以及编译安装MySql 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 前言: 1.目前90%以上的公司面临的运维的瓶颈都在后端 最常见的2大瓶颈就是: 1&g ...

  4. RHEL8.0快速入门系列笔记--理论知识储备(一)

    RHEL8.0快速入门系列笔记–理论知识储备(一) 红帽公司发布Linux8.0系统已经有一段时间,最近准备学习关于RHEL8.0的相关新特性.根据官方介绍:RHEL8.0在云/容器化工作负载方面做了 ...

  5. SpringBoot简介、SpringBoot 入门程序搭建、与JDBC、Druid、Mybatis和SpringData JPA的整合

    一.SpringBoot 简介: spring boot并不是一个全新的框架,它不是spring解决方案的一个替代品,而是spring的一个封装.所以,你以前可以用spring做的事情,现在用spri ...

  6. 十 ARM9(2440)的IIC——理论知识及程序实例

    原文地址:十 ARM9(2440)的IIC--理论知识及程序实例作者:骨Zi里德骄傲 概述 S3C2440A RISC 微处理器可以支持一个多主控IIC 总线串行接口.一条专用串行数据线(SDA)和一 ...

  7. 知识点总结Day01——JAVA基础知识、开发环境搭建、入门程序、常量、变量及数据类型

    目录 第一章 前言 一.Java概述 1.什么是Java 2.什么是编程语言 3.Java发展历史 二.计算机基础知识 1.二进制 2.字节 3.常见的DOS命令 第二章 Java开发环境搭建 一.搭 ...

  8. 软件测试用例优秀例子_新手入门:想要做好软件测试,这些理论知识,你得好好掌握...

    对于很多测试新手来说,想要把自己的测试技术练得更精进,扎实自己的理论知识是必不可少的一门功课.下面,我们就一起来复习一下,那些让我们一知半解或者记不全的理论知识吧. 1.什么是软件测试? 最老套但是测 ...

  9. Spring入门程序的编写(实验一+第一章知识总结)

    这是一个Spring入门程序: main()方法中并没有通过New关键字来创建UserDao接口的实现类对象,而是通过Spring容器来获取实现类对象,这就是Spring IoC容器 的工作机制. 它 ...

最新文章

  1. 人脸标记检测:ICCV2019论文解析
  2. 程序员最常见的谎话,太准了
  3. Java EE 8,当前状态是什么:自2015年底以来已完成工作的案例研究
  4. windos 2008安装php5.3,windows 2008 + php 5.3.29配置
  5. java调python报错Cannot create PyString with non-byte value
  6. python客户画像_Python数据分析学习笔记05:用户画像
  7. 谷歌AI掌门人Jeff Dean获冯诺依曼奖;微软计划自研PC和服务器芯片;Ruby 3.0 RC1发布|极客头条...
  8. unix环境高级编程基础知识之第一篇
  9. ejb2.0详细开发过程
  10. DirectX11 指定材质
  11. mac制作linux启动盘,Mac 下制作开机启动盘,做了一个Centos7 的系统U盘
  12. 未来互联网+大数据时代
  13. HTML网页设计制作大作业(div+css)--(四大名著 5页 )
  14. MMDet——基于Chamfer Distance评估点集
  15. 全新安装Windows10系统(PE下)
  16. AcWing2022寒假每日一题(1 月 2 日 ~ 1 月 6 日)
  17. 有计算机考试励志的文案,抖音冲刺高考励志文案
  18. 【读书笔记】科学:无尽的前沿——科学是一种提出问题的方式
  19. 男人的魅力不在于财富,而在于精神深度
  20. leetcode_592. 分数加减运算

热门文章

  1. android新闻列表,Android中实现简单的新闻列表
  2. 体素滤波算法python实现
  3. 无人机深度学习虚拟现实平台构建
  4. fluter的环境搭配及android studio开发
  5. GitHub的使用方法
  6. Win10打补丁KB4022725出现0x80073712错误
  7. 笔记:文澜:桥接视觉和语言的大规模多模态预训练 WenLan: Bridging Vision and Language by Large-Scale Multi-Modal Pre-Training
  8. 从零破解一款轻量级滑动验证码
  9. 智能代还行业怎么样?合法吗?代还APP开发靠谱吗?
  10. 中国ai创业公司 排行榜_加入AI创业公司之前,您需要问6个问题