技术标签: spring java spring框架 hibernate
目录
Java Persistence API:Java对象持久化API
JDK5.0 平台的标准 ORM 规范,可以让 Java 程序用统一方式访问持久层
JPA 和 Hibernate 的关系
JPA 是 Hibernate 的一个抽象(JDBC Interface 与 JDBC驱动的关系)
JPA 本质上就是一种 ORM 规范,不是 ORM 框架,因为 JPA 并未提供 ORM 实现,它只提供了 API 接口,具体的实现由 ORM 厂商提供实现
Hibernate 是 一个 ORM 框架,同时也是一种 JPA 的实现
Hibernate 从3.2版本开始兼容 JPA
Hibernate 使用起来是XML配置文件的方式,而 JPA 是注解的方式,而注解是JDK5.0中自带的,所以并不需要再引入第三方Jar包,实际上就是来学习如何使用注解的方式来使用 Hibernate
要使用到 JPA 的哪些技术
ORM 映射元数据:JPA 支持 XML 和 JDK5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架将实体对象持久化到数据库表中
JPA 的 API:利用实体对象,操作 JPA 提供的接口进行 CRUD 操作,简化开发者编程代码
查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言去查询数据
使用Maven构建项目,项目名为:jpa
配置pom.xml
<properties>
<spring.version>5.2.6.RELEASE</spring.version>
<hibernate.version>5.4.10.Final</hibernate.version>
<mysql.version>8.0.21</mysql.version>
<ehcache.version>3.8.1</ehcache.version>
<jpa.version>1.0.1.Final</jpa.version>
<slf4j.version>1.7.25</slf4j.version>
<aspectj.version>1.9.5</aspectj.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</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-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 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>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-hikaricp</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>${jpa.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
创建 com.javakc.jpa 包
创建 entity 包并在其目录下创建实体类
创建 dao 包并在其目录下创建数据层实现类
在 resources 目录下创建 jdbc.properties 配置文件
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///jpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
jdbc.user=root
jdbc.password=123456
在 resources 目录下创建 spring-jpa.xml 配置文件
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.javakc.jpa"></context:component-scan>
<!-- 加载配置文件 -->
<context:property-placeholder location="jdbc.properties"></context:property-placeholder>
<!-- 配置 Hikari 数据源 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="username" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置 EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- JPA 提供商的适配器 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<!-- 配置实体类所在的包 -->
<property name="packagesToScan" value="com.javakc.jpa.entity"></property>
<!-- 配置 JPA 的基本属性 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 配置 JPA 使用的事物管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 配置支持基于注解的事物配置 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
创建测试类
import com.javakc.jpa.dao.JpaDao;
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;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-jpa.xml"})
public class JpaTest {
@Autowired
private JpaDao jpaDao;
@Test
public void test() {
}
}
@Entity
标注用于实体类声明语句之前,指出该Java 类为实体类,将映射到指定的数据库表
@Table
当实体类与其映射的数据库表名不同名时需要使用 @Table 标注说明,该标注与 @Entity 标注并列使用,置于实体类声明语句之前,可写于单独语句行,也可与声明语句同行
@Table 标注的常用选项是 name,用于指明数据库的表名
@Table标注还有一个两个选项 catalog 和 schema 用于设置表所属的数据库目录或模式,通常为数据库名。uniqueConstraints 选项用于设置约束条件,通常不须设置
@Id
标注用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前
@GeneratedValue
用于标注主键的生成策略,通过 strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略
在 javax.persistence.GenerationType 中定义了以下几种可供选择的策略:
IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式
AUTO: JPA自动选择合适的策略,是默认选项
SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式
TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植
@Column
当实体的属性与其映射的数据库表的列不同名时需要使用@Column 标注说明,该属性通常置于实体的属性声明语句之前,还可与 @Id 标注一起使用
常用属性是 name,用于设置映射数据库表的列名。此外,该标注还包含其它多个属性,如:unique 、nullable、length 等
@Transient
表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性
如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic
@Temporal
在核心的 Java API 中并没有定义 Date 类型的精度(temporal precision). 而在数据库中,表示 Date 类型的数据有 DATE, TIME, 和 TIMESTAMP 三种精度(即单纯的日期,时间,或者两者 兼备). 在进行属性映射时可使用 @Temporal 注解来调整精度
一级缓存:会话级别,对同一个id进行两次加载,不会发送两条sql给数据库,但会话关闭,一级缓存就会失效
二级缓存:全局级别,一级缓存会话关闭,缓存也不会失效
在 JPA 规范中, EntityManager 是完成持久化操作的核心对象。实体作为普通 Java 对象,只有在调用 EntityManager 将其持久化后才会变成持久化对象。EntityManager 对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。
实体的状态:
临时状态: 新创建的对象,尚未拥有持久性主键,不处于缓存中,数据库中也没有对应的记录
持久化状态:已经拥有持久性主键,位于缓存中,数据库中有对应记录
游离状态:拥有持久化主键,不处于缓存中,数据库中可能存在对应的记录
删除状态: 曾经位于缓存中,曾在数据库中有过记录,但现在已被删除
persist:
用于将新创建的 Entity 纳入到 EntityManager 的管理。该方法执行后,传入 persist() 方法的 Entity 对象转换成持久化状态
如果传入 persist() 方法的 Entity 对象已经处于持久化状态,则 persist() 方法什么都不做
如果对删除状态的 Entity 进行 persist() 操作,会转换为持久化状态
如果对游离状态的实体执行 persist() 操作,可能会在 persist() 方法抛出 EntityExistException(也有可能是在flush或事务提交后抛出)
public void persist() { Student student = new Student(); student.setStudentName("AA"); student.setBirthday(new Date()); student.setCreateDate(new Date()); entityManager.persist(student); System.out.println(student.getId()); }
find:
返回指定的 OID 对应的实体类对象,如果这个实体存在于当前的持久化环境,则返回一个被缓存的对象;否则会创建一个新的 Entity, 并加载数据库中相关信息;若 OID 不存在于数据库中,则返回一个 null。第一个参数为被查询的实体类类型,第二个参数为待查找实体的主键值
public void find() { Student student = entityManager.find(Student.class, 1); Student student2 = entityManager.find(Student.class, 1); System.out.println("-----------"); System.out.println(student); System.out.println(student2); }
getReference:
与find()方法类似,不同的是:如果缓存中不存在指定的 Entity, EntityManager 会创建一个 Entity 类的代理,但是不会立即加载数据库中的信息,只有第一次真正使用此 Entity 的属性才加载,所以如果此 OID 在数据库不存在,getReference() 不会返回 null 值, 而是抛出EntityNotFoundException
public void getReference() { Student student = entityManager.getReference(Student.class, 1); System.out.println("-----------"); System.out.println(student); }
remove
删除实例。如果实例是被管理的,即与数据库实体记录关联,则同时会删除关联的数据库记录
public void remove() { Student student = entityManager.find(Student.class, 1); entityManager.remove(student); }
merge:merge() 用于处理 Entity 的同步。即数据库的插入和更新操作
创建一个新的对象,把临时对象的属性复制到新的对象中,然后对新的对象执行持久化操作。所以新的对象中有id,但以前的临时对象中没有id
public void merge1() { Student student = new Student(); student.setStudentName("AA"); student.setBirthday(new Date()); student.setCreateDate(new Date()); Student student2 = entityManager.merge(student); System.out.println("student#id=" + student.getId()); System.out.println("student2#id=" + student2.getId()); }
传入一个游离对象, 即传入的对象有 OID,如果在 EntityManager 缓存中没有该对象,如果在数据库中没有对应的记录,JPA 会创建一个新的对象, 然后把当前游离对象的属性复制到新创建的对象中,对新创建的对象执行 insert 操作
public void merge2() { Student student = new Student(); student.setStudentName("AA"); student.setBirthday(new Date()); student.setCreateDate(new Date()); student.setId(100); Student student2 = entityManager.merge(student); System.out.println("student#id=" + student.getId()); System.out.println("student2#id=" + student2.getId()); }
传入一个游离对象, 即传入的对象有 OID,如果在 EntityManager 缓存中没有该对象,如果在数据库中有对应的记录,JPA 查询到对应的记录, 返回查询对象, 再然后会把游离对象的属性复制到查询到的对象中,对查询到的对象执行 update 操作
public void merge3() { Student student = new Student(); student.setStudentName("BB"); student.setBirthday(new Date()); student.setCreateDate(new Date()); student.setId(1); entityManager.merge(student); }
在双向的一对一关联中,需要在不维护关系端中的 @OneToOne 注解中指定 mappedBy,以指定是这一关联中的被维护端。同时需要在关系维护端建立外键列指向关系被维护端的主键列
设置关系
// ## 使用 @OneToOne 来映射 1-1 关联关系 // ## 在当前表中维护关系需要使用 @JoinColumn 来进行映射, 在 1-1 关联关系中需要添加 unique=true @OneToOne @JoinColumn(name = "student_id", unique = true) private Student student;
// ## 当前表不维护关联关系,没有外键,使用 @OneToOne 来进行映射, 需要设置 mappedBy="student",如果两边都维护关联关系则会多出无用sql语句 @OneToOne(mappedBy = "student") private Card card;
测试
保存
/** * 双向 1-1 的关联关系,建议先去保存不维护外键的一方,这样不会多出 update 语句 */ public void oneToOnePersist() { Student student = new Student(); student.setStudentName("BB"); Card card = new Card(); card.setCardNum("110"); // ## 设置关联关系 student.setCard(card); card.setStudent(student); // ## 保存 entityManager.persist(student); entityManager.persist(card); }
获取1
/** * 获取维护外键的一方,默认会使用左外连接获取其关联的对象 * 可通过 @OneToOne 的 fetch 属性来修改加载策略(@OneToOne(fetch = FetchType.LAZY)) */ public void oneToOneFind() { Card card = entityManager.find(Card.class, 1); System.out.println(card.getCardNum()); System.out.println(card.getStudent().getClass().getName()); }
获取2
/** * 获取不维护外键的一方,默认会使用左外连接获取其关联的对象 * 可通过 @OneToOne 的 fetch 属性来修改加载策略,但依然会查询另一方,来初始化关联对象 * 所以不建议修改加载策略 */ public void oneToOneFind2() { Student student = entityManager.find(Student.class, 10); System.out.println(student.getStudentName()); System.out.println(student.getCard().getClass().getName()); }
单向一对多关系中,在 1 端设置 @OneToMany 注解,并使用 @JoinColumn 指定外键列的名称
设置关系
// ## 使用 @OneToMany 映射单向 1-n 关联关系 // ## 使用 @JoinColumn 映射外键列的名称 @OneToMany @JoinColumn(name = "classroom_id") private List<Student> studentList = new ArrayList<>();
测试
保存
/** * 单向 1-n 关联关系保存时一定会多出 update 语句 * 因为 n 端在插入数据时不会同时插入外键列需要用修改来补充外键值 */ public void oneToManyPersist() { ClassRoom classRoom = new ClassRoom(); classRoom.setClassRoomName("javakc80"); Student student1 = new Student(); student1.setStudentName("CC"); student1.setBirthday(new Date()); student1.setCreateDate(new Date()); Student student2 = new Student(); student2.setStudentName("DD"); student2.setBirthday(new Date()); student2.setCreateDate(new Date()); // ## 设置关联关系 classRoom.getStudentList().add(student1); classRoom.getStudentList().add(student2); // ## 保存 entityManager.persist(classRoom); entityManager.persist(student1); entityManager.persist(student2); }
获取
/** * 默认为关联的 n 端使用懒加载策略 * 可通过 @OneToMany 的 fetch 属性来修改加载策略关闭懒加载 */ public void oneToManyFind() { ClassRoom classRoom = entityManager.find(ClassRoom.class, 1); System.out.println(classRoom.getClassRoomName()); System.out.println(classRoom.getStudentList().size()); }
删除
/** * 默认删除 1 端的数据前,先把关联的 n 端的外键置空,再删除 1 端数据 * 可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略 */ public void oneToManyRemove() { ClassRoom classRoom = entityManager.find(ClassRoom.class, 1); entityManager.remove(classRoom); }
修改
public void oneToManyUpdate() { ClassRoom classRoom = entityManager.find(ClassRoom.class, 1); classRoom.getStudentList().get(0).setStudentName("FFF"); }
单向多对一关系中,在 n 端设置 @ManyToOne 注解,并使用 @JoinColumn 指定外键名称
设置关系
// ## 使用 @ManyToOne 映射单向 n-1 关联关系 // ## 使用 @JoinColumn 映射外键 @ManyToOne @JoinColumn(name = "classroom_id") private ClassRoom classRoom;
测试
保存
/** * 先保存 1 的一端,后保存 n 的一端,这样不会多出额外的 update 语句 */ public void manyToOnePersist() { ClassRoom classRoom = new ClassRoom(); classRoom.setClassRoomName("javakc80"); Student student1 = new Student(); student1.setStudentName("CC"); student1.setBirthday(new Date()); student1.setCreateDate(new Date()); Student student2 = new Student(); student2.setStudentName("DD"); student2.setBirthday(new Date()); student2.setCreateDate(new Date()); // ## 设置关联关系 student1.setClassRoom(classRoom); student2.setClassRoom(classRoom); // ## 保存 entityManager.persist(classRoom); entityManager.persist(student1); entityManager.persist(student2); }
获取
/** * 使用左外连接的方式获取 n 端的对象和其关联的 1 端的对象数据 * 可通过 @ManyToOne 的 fetch 属性来修改加载策略 */ public void manyToOneFind() { Student student = entityManager.find(Student.class, 1); System.out.println(student.getStudentName()); System.out.println(student.getClassRoom().getClassRoomName()); }
删除1
public void manyToOneRemove1() { Student student = entityManager.find(Student.class, 1); // ## 删除 n 端 entityManager.remove(student); }
删除2
public void manyToOneRemove2() { ClassRoom classRoom = entityManager.find(ClassRoom.class, 1); // ## 删除 1 端 entityManager.remove(classRoom); }
修改
public void manyToOneUpdate() { Student student = entityManager.find(Student.class, 1); student.getClassRoom().setClassRoomName("javakc"); }
双向关系中,必须存在一个关系维护端,在 JPA 规范中,要求 many 的一方作为关系的维护端, one 的一端不维护关系。 可以在 one 方指定 @OneToMany 注解,并设置 mappedBy 属性,以指定它这一端不维护关联关系,many 为维护端。 在 many 方指定 @ManyToOne 注解,并使用 @JoinColumn 指定外键名称
设置关系
// ## 使用 @ManyToOne 映射 n-1 关联关系 // ## 使用 @JoinColumn 映射外键 @ManyToOne @JoinColumn(name = "classroom_id") private ClassRoom classRoom;
// ## 使用 @OneToMany 映射 1-n 关联关系 // ## 使用 @JoinColumn 映射外键列的名称 // ## 在 1 端的 @OneToMany 中使用 mappedBy 属性放弃维护关系, 就无需再使用 @JoinColumn 注解 @OneToMany(mappedBy = "classRoom") private List<Student> studentList = new ArrayList<>();
测试
保存
/** * 先保存 1 的一端,后保存 n 的一端,这样不会多出额外的 update 语句 * 在双向关系下,保存 1 端会出现额外的 update 语句 * 建议使用 n 端来维护关联关系,1 端不维护关联关系, 这样就会减少 update 语句 * 注意: 在 1 端的 @OneToMany 中使用 mappedBy 属性, 就无需再使用 @JoinColumn 注解 */ public void manyToOnePersist() { ClassRoom classRoom = new ClassRoom(); classRoom.setClassRoomName("javakc80"); Student student1 = new Student(); student1.setStudentName("CC"); student1.setBirthday(new Date()); student1.setCreateDate(new Date()); Student student2 = new Student(); student2.setStudentName("DD"); student2.setBirthday(new Date()); student2.setCreateDate(new Date()); // ## 设置关联关系 student1.setClassRoom(classRoom); student2.setClassRoom(classRoom); classRoom.getStudentList().add(student1); classRoom.getStudentList().add(student2); // ## 保存 entityManager.persist(classRoom); entityManager.persist(student1); entityManager.persist(student2); }
在双向多对多关系中,我们必须指定一个关系维护端,可以通过 @ManyToMany 注解中指定 mappedBy 属性来标识放弃关系维护
设置关系
// ## 使用 @ManyToMany 映射 n-n 关联关系 // ## @JoinTable(name = "中间表名", // ## joinColumns = @JoinColumn(name = "本类的外键"), // ## inverseJoinColumns = @JoinColumn(name = "对方类的外键")) @ManyToMany @JoinTable(name = "jpa_course_student", joinColumns = @JoinColumn(name = "course_id"), inverseJoinColumns = @JoinColumn(name = "student_id")) private List<Student> studentList = new ArrayList<>();
// ## 使用 @ManyToMany 映射 n-n 关联关系 // ## 使用 mappedBy 属性放弃维护关系 @ManyToMany(mappedBy = "studentList") private List<Course> courseList = new ArrayList<>();
测试
保存
public void manyToManyPersist() { Course course1 = new Course(); course1.setCourseName("钢琴"); Course course2 = new Course(); course2.setCourseName("美术"); Student student1 = new Student(); student1.setStudentName("小明"); Student student2 = new Student(); student2.setStudentName("小红"); // ## 设置关联关系 course1.getStudentList().add(student1); course1.getStudentList().add(student2); course2.getStudentList().add(student1); course2.getStudentList().add(student2); student1.getCourseList().add(course1); student1.getCourseList().add(course2); student2.getCourseList().add(course1); student2.getCourseList().add(course2); // ## 保存 entityManager.persist(course1); entityManager.persist(course2); entityManager.persist(student1); entityManager.persist(student2); }
获取
public void manyToManyFind() { Course course = entityManager.find(Course.class, 1); System.out.println(course.getCourseName()); System.out.println(course.getStudentList().size()); }
JPQL语言,即 Java Persistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异
public void query() { String jpql = "FROM Student"; Query query = entityManager.createQuery(jpql); List<Student> list = query.getResultList(); System.out.println(list.size()); }
public void nativeQuery() { String sql = "select * from jpa_student s"; Query query = entityManager.createNativeQuery(sql); List list = query.getResultList(); System.out.println(list.size()); }
文章浏览阅读282次。wxWidgets:常用表达式wxWidgets:常用表达式不同风味的正则表达式转义Escapes元语法匹配限制和兼容性基本正则表达式正则表达式字符名称wxWidgets:常用表达式一个正则表达式描述字符的字符串。这是一种匹配某些字符串但不匹配其他字符串的模式。不同风味的正则表达式POSIX 定义的正则表达式 (RE) 有两种形式:扩展正则表达式(ERE) 和基本正则表达式(BRE)。ERE 大致是传统egrep 的那些,而 BRE 大致是传统ed 的那些。这个实现增加了第三种风格:高级正则表达式_wxwidget 正则表达式 非数字字符
文章浏览阅读3.4k次,点赞5次,收藏11次。Java中普通for循环和增强for循环的对比_for循环10万数据需要时间
文章浏览阅读2.7k次,点赞13次,收藏97次。0.工厂制作PCB线路板流程1.PCB的结构铜层阻焊丝印本质(PCB画电路板到底在画什么)基础工艺指标2.PCB图中的元素元素布局布线叠层设计3.PCB的设计依据原理图原理图元件库4.PCB的设计流程——总结_pcb端子设计基础知识
文章浏览阅读4.5k次,点赞5次,收藏19次。Python读取Excel内容;将读取的数据转换为list类型便于切片处理;列表的操作方法;pandas处理DataFrame类型数据_pandas excel list
文章浏览阅读4.6k次。在分析服务器运行情况和业务数据时,nginx日志是非常可靠的数据来源,而掌握常用的nginx日志分析命令的应用技巧则有着事半功倍的作用,可以快速进行定位和统计。下面是自己在分析nginx日志时常用命令的一些总结。1.利用grep ,wc命令统计某个请求或字符串出现的次数比如我要统计GET /task/showContent接口在某天的调用次数,则可以使用如下命令: cat _nginx的日志分析
文章浏览阅读5.4w次,点赞64次,收藏262次。使用Echarts绘制中国地图,其中地图点信息由JSON文件编写,前端html直接从JSON文件中读取地区数据,渲染到前端即可。详细介绍用到的各个功能!代码直接复制运行即可!_echarts中国地图
文章浏览阅读435次,点赞3次,收藏7次。转载来源为https://blog.csdn.net/ReCclay/article/details/79439686 1、嵌入式系统的CPU主要使用的有DSP、ARM以及FPGA。2、DSP适用于数字信号处理的微处理器支持单指令多数据(DIMD)并行处理的指令显著提高音频、视频等数字信号的数据处理效率3、片上系统SOC已成为嵌入式处理器芯片的主流发展趋势它是..._八个gpio引脚最多构成几个按键
文章浏览阅读70次。magnum 是用于 OpenStack 的容器服务。它有以下特点:抽象的容器、节点、服务等集成了用于容器技术的Kubernetes和Docker集成了多租户安全的 Keystone继承了k8s多租户网络安全的 Neutron环境准备在VMware Workstations建台虚拟机,Ubuntu 14.04 LTS,..._openstack 安装好没有容器服务
文章浏览阅读420次。 HDU - 2209 翻纸牌游戏 当前的这张牌是否翻转取决于它的前一张牌是否朝上,如果朝上,不翻转,朝下,则翻转,这是贪心的思想,但是,对于第一张牌来说,它的前面没有牌了,所以可以翻转,也可以不翻转,分两种情况来判断,参考的别人的代码 #include<stdio.h>#include<algorithm>#include<string.h>u..._hdu 2209
文章浏览阅读2k次。很多小伙伴都遇到过win7系统因0xc0000005错误导致应用程序无法正常启动的困惑吧,一些朋友看过网上零散的win7系统因0xc0000005错误导致应用程序无法正常启动的处理方法,并没有完完全全明白win7系统因0xc0000005错误导致应用程序无法正常启动是如何解决的,今天小编准备了简单的解决办法,只需要按照1、右键点击要运行的软件或游戏,在右键菜单中选择“兼容性疑难解答”; 2、让系..._mysql 0xc0000005
文章浏览阅读492次。unix环境高级编程笔记_标准io创建空头文件
文章浏览阅读1.3k次。环境:ubuntu 16.04在执行apt-get update时直接报错了,错误信息如下:从返回的错误信息可以看出,问题出在“appstreamcli”上。通过以下命令可以解决:sudo apt install appstream/xenial-backportssudo appstreamcli refresh –force亲测可行。..._sudo apt-get update error in appstreamcli