JPA1

1.JPA入门

1.1.JPA概述

jpa:(1)Java持久层API,jpa就是做持久层,操作数据库
(2)它是对象映射框架(ORM)的==规范==
ORM: 对象关系映射(Object Relational Mapping,简称ORM)

1.2.为什么需要JPA

(1)以前使用jdbc,在对象和数据库数据之间转换特别麻烦
(2)他以面向对象的思维来操作数据,比如我操作一个java里面对象,就相当于操作数据库表数据

1.3.Hibernate和JPA的关系

JPA:是ORM的规范
Hibernate:是ORM这个JPA规范实现的框架

1.4.JDBC和JPA的优缺点

(1)JDBC的优缺点

本质:处理Java对象和关系型数据库表之间的转换
优点:操作数据库最底层,性能最高(前提是你要有相应的经验,并且是一个数据库高手)
缺点:
1.使用复杂(重复代码太多)
2.移植数据库很麻烦,改动比较多
		主键的生成方式不同(mysql使用自增,oracle使用序列sequence)
		分页的sql语句也是不同(mysql使用limit,oracle使用ROWNUM)
3.性能优化得自己处理,没有提供数据的缓存,需要自己实现
4.面向sql语句操作,不是面向对象的

(2)JPA的优缺点

本质:处理Java对象和关系型数据库表之间的转换,只是对JDBC再次做了一层封装
优点:
5.程序员操作很简单,代码简单 entityManager.persist(employee);	
6.直接面向持久对象操作
7.提供世界级数据缓存(现在几乎所有的ORM框架的缓存都是学的Hibernate)
		  一级缓存,二级缓存,查询缓存(空间换速度)
8.数据库移植性很强,很少的修改(通过配置方言搞定)
		把各种数据库抽取了一个方言接口
		不同数据库实现一个方言接口,如果换了数据库,必须修改方言实现,驱动jar文件,连接数据库信息。
缺点:
​ (1)不能干预sql的生成 ,查询一个数据 find 默认查询所有字段 (select * from )
​ (2)有些优化 jpa做不了,比如特别大数据量的时候,jpa也不适合,mybatis也解决不了 (架构策略 分库 分表 (分布式))
​ (3)一个项目里面 对sql要求比较高,就不适合jpa
(4)JPA适用项目规模:中小型的项目

2.第一个JPA程序

2.1.导入jar包:pom.xml

<?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>jpa-demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>jpaday01</module>
</modules>

<dependencies>
<!-- hibernate的包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- hibernate对于jpa的支持包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- mysql的驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- junit的测试包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<finalName>pss</finalName>
<plugins>
<plugin>
<!-- Maven的编译插件-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

</project>

注意:如果数据库引入不了,把仓库中的mysql版本5.1.6删除,联网重新下载
在这里插入图片描述

2.2.核心配置文件persistence.xml

而JPA中我们也需要先找到这些常用配置:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
persistence.xml放在classpath目录的META-INF下
将META-INF移到resources下面(JPA规范要求)
在这里插入图片描述

persistence.xml配置文件代码

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
	version="2.0">
	<persistence-unit name="cn.itsource.jpa" transaction-type="RESOURCE_LOCAL">
		<properties>
			<!-- 必须配置4个连接数据库属性 -->
			<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="admin" />

			<!-- 必须配置1个方言属性 -->
			<!-- 实现跨数据库关键类 :查询MySQLDialect的getLimitString方法 -->
			<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.3. 类里面的代码

public class HelloTest {
  @Test
  public void save() throws Exception {
    Employee employee = new Employee();
    employee.setName("xxxxx");
    employee.setPassword("yyyyy");

    // 对应配置文件里面的persistence-unit name="cn.itsource.jpa"
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("cn.itsource.jpa");
    // 获取Session对象
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    // 开启事务
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    // 持久操作CUD
    entityManager.persist(employee);
    // 提交事务
    transaction.commit();
    // 关闭资源
    entityManager.close();
    entityManagerFactory.close();
  }
}

3.JPA CRUD

3.1.抽取JPAUtils工具类

用于生成EntityManager类

public class JpaUtil {
    //得到EntityManagerFactory
    private static EntityManagerFactory entityManagerFactory;

    static{
        try {
            entityManagerFactory = Persistence.createEntityManagerFactory("cn.itsource.jpa");
        }catch (RuntimeException e){
            throw new RuntimeException("解析配置文件出问题了");
        }
    }

    //得到EntityManager
    public static EntityManager getEntityManager(){
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        return  entityManager;
    }
}

3.2.CRUD代码

(1)添加:entityManager.persist(obj);
(2)修改:entityManager.merge(obj);
(3)删除:/删除前,必须与entityManager有关联,所以先查找出来,再删除

 	User user = entityManager.find(User.class, 2L);
    System.out.println(user);
    transaction.begin();
    if (user != null){
        entityManager.remove(user);//持久操作
    }

(4)查找单行:User user = entityManager.find(User.class,4L);
(5)查找全部:需现用jpql语句,查找出来,再获得结果集

String jpql = "select o from User o";//jpql语句
TypedQuery<User> query = entityManager.createQuery(jpql, User.class);
List<User> resultList = query.getResultList();

注:查找的时候,不需要事务
(1)添加

public void testadd() throws Exception{
    User user = new User();
    user.setName("老刘星");
    EntityManager entityManager = JpaUtil.getEntityManager(); // 获取entityManager对象
    // 开启事务
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    entityManager.persist(user);//持久操作
    transaction.commit();// 提交事务
    entityManager.close();// 关闭资源
}

(2)删除

public void testdel() throws Exception{
    EntityManager entityManager = JpaUtil.getEntityManager(); // 获取entityManager对象
    EntityTransaction transaction = entityManager.getTransaction(); // 开启事务
    //删除前,必须与entityManager有关联,所以先查找一次
    User user = entityManager.find(User.class, 2L);
    System.out.println(user);
    transaction.begin();
    if (user != null){
        entityManager.remove(user);//持久操作
    }
    transaction.commit();// 提交事务
    entityManager.close();// 关闭资源
}

(3)修改

public void testupdate() throws Exception{
    User user = new User();
    user.setName("老刘星");
    user.setId(1L);
    EntityManager entityManager = JpaUtil.getEntityManager();// 获取entityManager对象
    // 开启事务
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    entityManager.merge(user);//持久操作
    transaction.commit(); // 提交事务
    entityManager.close();  // 关闭资源
}

(4)查找单行

public void testfindOne() throws Exception{
    EntityManager entityManager = JpaUtil.getEntityManager(); // 获取entityManager对象
    User user = entityManager.find(User.class, 1L);//持久操作
    System.out.println(user);
    entityManager.close(); // 关闭资源
}

(5)查找全部

public void testfindAll() throws Exception{
    EntityManager entityManager = JpaUtil.getEntityManager();   // 获取entityManager对象
    //持久操作
    String jpql = "select o from User o";//jpql语句
    TypedQuery<User> query = entityManager.createQuery(jpql, User.class);
    List<User> resultList = query.getResultList();
    for (User user : resultList) { //循环
        System.out.println(user);
    }
    entityManager.close(); // 关闭资源
}

4.配置自动生成表(建表策略)

(1)create 创建策略,先删除 在创建
(2) update (测试)更新策略 不会删除 如果发现没有表,也会创建
(3)create-drop 先删除 在创建 在删除
(4) validate 验证策略 当前实体配置和数据库的配置进行对比验证

5.核心API简介

(1)EntityManagerFactory

EntityManagerFactory中应保存了对应的persistence unit中的数据库配置信息和所有实体及关系以及预定义的JPQL语句。同时,EntityManagerFactory还负责维护二级缓存。 
EntityManagerFactory这个类他是重量级的,不要频繁创建和销毁,很销毁性能
这个类也应该设计成共享的。在设计成共享的时候,尽量线程安全(利用同步)

(2)EntityManager

EntityManager 它是实体管理的类,可以管理实体(crud),它是轻量级的类,可以频繁创建和销毁不会销毁太多的性能,他是线程不安全的,但是在设计,多个线程来访问的时候,尽量的保证线程是安全,如果没有线程安全,出现事务并发带来的问题;
用途:A管理实体(crud)
B.EntityManager里面有一个一级缓存(掌握)
​		缓存:Cache  在内存里面开辟一块空间来临时存储数据 
缓存什么时候才能用上:(一级缓存命中之后就可以用来)  
 		同一个EntityManagerFactory  同一个EntityManager 同一个OID(实体对象的ID --主键ID)

(3)EntityManager

只能控制相同一个数据库不同表的事务管理,大多数情况都使用这种
处理不同数据库不同表的事务管理
Tomcat默认不支持JTA事务(不过可以通过添加插件来解决),或者需要用JavaEE服务器:如jboss,weblogic服务器
JTA事务适用场景:比如跨行转账,就需要用到JTA事务

6.单表映射配置细节

@Entity
@Table(name = "t_employee")
public class Employee {
    @Id
    @GeneratedValue
    private Long id; //要求:主键,使用数据库的自动生成策略

    @Column(length=20,name = "username",unique =true,nullable = false)
    private String name;  //要求:varchar(20),数据库名称为username,不能为空,唯一
    private String password;

    @Column(columnDefinition = "int(20) default 25",insertable = false)
    private Integer age = 25; //要求:默认值是25,在插入数据时不允许覆盖(添加数据时不操作该字段)

    private Boolean sex;// 数据库没有布尔类型,bit对象

    @Column(columnDefinition = "decimal(19,2)")
    private BigDecimal salary;// 19,2   长度19,小声点2位

    @Column(updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;//包含年月日时分秒,不允许修改

    @Temporal(TemporalType.DATE)
    private Date birthday;//包含年月日

    @Temporal(TemporalType.TIME)
    private Date time;//包含时分秒

    @Lob
    private String text;//这是一个大文本

    @Transient
    private String temp;//这一个字段不要同步到数据库

发布了31 篇原创文章 · 获赞 3 · 访问量 908

猜你喜欢

转载自blog.csdn.net/S_L__/article/details/97040733
JPA