欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JPA的理论及实践第一节

程序员文章站 2022-05-31 20:30:36
...

@JPA的理论及实践第一节

一.理论

1.1 什么是JPA

  • JPA:(Java Persistence API) ORM的规范
  • JPA是规范,Hibernate是它的实现(不唯一,但最好)
  • 最底层的操作还是JDBC(引入驱动包)

1.2 什么是ORM

o(对象,java面向对象) r(关系,关系型数据库) m(映射)

1.3 JPA与JDBC的区别

JPA(hibernate)的底层还是JDBC

  • JPA开发效率高(JPA代码简单)
  • JPA运行效率低(jdbc高:更接近低层)
  • JPA兼容各种数据库(方便移植)
  • JPA有内置缓存(性能在一定程度上还是有优化)
  • 具体的东西请大家查看文档(百度)

二.hello

2.1 新建项目支持

具体的配置都是属于idea的内
JPA的理论及实践第一节

2.2 导包

在外层的pom.xml中进行导包

  • 导包类型(hibernate核心包,JPA支持包,驱动包,测试包)
  • JDK1.8插件配置支持
<?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.itsource</groupId>
    <artifactId>jpademo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>jpaday01</module>
    </modules>

    <!--导包:hibernate的包 ,hibernate对于JPA的支持包,数据库驱动包,junit测试包-->
    <dependencies>
        <!--hibernate的核心包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
        <!--hiberante对于jpa的支持包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
        <!--数据库驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
        <!--junit测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--设置咱们项目的JDK版本-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.3 引入persistence.xml

2.3.1 使用工具生成 META-INF\persistence.xml

大家也可以手动创建

  • 快捷键 ctrl+alt+shift+s
  • 进行配置
  • JPA的理论及实践第一节
  • 调整结构(如下)
  • JPA的理论及实践第一节
  • persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--
        咱们这个配置是要连接数据库的(jpa支持咱们连接多个数据库)
        persistence-unit:持久化单元(可能有多个,每一个对应一个数据库)
            name:取个名称(随便取)
            transaction(事务,同生共死)-type(类型)
                RESOURCE_LOCAL:本地的事务
                JTA: 分布式系统要使用的事务
        基本的数据库连接配置(四大金刚)
         properties:属性(所有属性都可以在下面的文件中找到)
            resources\源码包\hibernate-release-4.3.8.Final\project\etc\hibernate.properties
       -->
    <persistence-unit name="cn.itsource.jpa" transaction-type="RESOURCE_LOCAL">
        <properties>
            <!--连接数据库的四个基本属性-->
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql:///jpa" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="root" />
            <!-- 配置方言(数据库兼容):你要操作的是什么数据库,根据不同的方言拼接不同的SQL
                    InnoDB:支持事务,支持外键   MyISAM:不支持事务,不支持外键(属性高)
            -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <!--配置建表策略(自动化帮我们创建相应的表)-->
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <!--可以看到SQL的展示-->
            <property name="hibernate.show_sql" value="true" />
            <!--可以看到SQL的展示(漂亮一点)-->
            <!--<property name="hibernate.format_sql" value="true" />-->
        </properties>
    </persistence-unit>
</persistence>

2.4 准备domain对象

//告诉JPA:这个类是要做实体化的
/**
 * @Entity:我是一个实体类,JPA快来管我
 * @Table(name = "t_employee"):我和哪些张是有关系的
 *   如果不写,他就认为你有一个表叫:Employee
 */
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "t_employee")
public class Employee {
    /**
     * @Id:代表我是一个主键
     * @GeneratedValue:我们认为主键是自增的
     */
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private String password;

    //getter,setter省略
}

2.5 基本功能测试

  • Persistence -> EntityManagerFactory -> EntityManager -> crud
  • 注意点:增删改需要事务 EntityManager可以拿到一个事务
/**
 * 在JPA中,所以增删改都需要我们去提交事务
 */
//拿到EntityManagerFactory(传入持久化单元的名称)
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("cn.itsource.jpa");
//拿出到实体管理对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//拿出一个事务 EntityManager里面有一个事务(只能拿到一个事务)
//开始事务
entityManager.getTransaction().begin();
//persist:持久化(保存一条数据)
entityManager.persist(employee);
//提交事务
entityManager.getTransaction().commit();
//关闭资源
entityManager.close();
entityManagerFactory.close();

三.CRUD

先完成了工具类

//帮咱们拿到一个EntityManager对象
public class JpaUtil {
    private static EntityManagerFactory factory;
    //加载时运行,且只运行一次
    static {
        try {
            factory = Persistence.createEntityManagerFactory("cn.itsource.jpa");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //直接拿到EntityManager对象
    public static EntityManager getEntityManager(){
        return factory.createEntityManager();
    }
}

增删改需要添加事务

3.1 添加

entityManager.persist(employee);

3.2 修改

entityManager.merge(employee);

3.3 删除

先查询,再判断,最后删除

 Employee employee = entityManager.find(Employee.class, id);
if(employee!=null) {
    //这里要求咱们传一个对象进去
    entityManager.remove(employee);
}

3.4 查询一条数据

传类型与id

   entityManager.find(Employee.class,id);

3.1 查询所有

query对象(entityManager创建)
jpql:面向对象的查询语言

entityManager = JpaUtil.getEntityManager();
//使用查询对象,写JPQL:像SQL,但是更加简单(面向对象)
//1.准备JPQL 不要写* ,from后面是一个类
//String jpql = "select o from cn.itsource.jpa.domain.Employee o";
// String jpql = "select o from Employee o";
String jpql = "from Employee";
//2.根据JPQL拿到查询对象
Query query = entityManager.createQuery(jpql);
//3.返回所有数据
return query.getResultList();

四.建表策略

4.1 create-drop

先删除-> 再创建 -> 用完(EntityManagerFactory关闭)再删(测试)

4.2 create

先删除-> 再创建(测试)

4.3 update

  • 没有表就创建,有就修改
  • 修改只增不减(不改类型)

4.4 validate

验证功能(只验证domain中写好的属性)

五.重要API认识

5.1 Persistence

  • 解析相应的核心配置文件
  • 创建EntityManagerFactory对象

5.2 EntityManagerFactory

  • 重(连接池,二级缓存,所有实体关系,预编译的SQL/JPQL)
  • 线程安全 (1:1:1)
  • 创建 EntityManager对象

5.3 EntityManager

  • 轻(连接,一级缓存)
  • 线程不安全
  • 完成CRUD
  • 什么是一级缓存命中?
    同一个EntityManagerFactory,同一个EntityManager,同一个OID
  • OID是什么样子的?
    类的全限定名#idcn.itsource.jpa.domain.Employee#1

5.4 EntityTransaction

  • EntityManager只有这一个事务
  • 如果多个系统/多个数据库 -> JTA

六.映射细节

@Column

     name = "username":对应的列名
     length=2 :长度
     nullable = false:该字符不能为空
     unique = true:唯一
@Column(name = "username",length = 20,nullable = false,unique = true)

@Lob

大文本(装很多数据)

@Transient

临时属性(JPA不会管理这个属性)

@Temporal

时间设置

TemporalType.TIMESTAMP:年月日,时分秒
TemporalType.DATE:年月日
TemporalType.TIME:时分秒