jpa的使用01

什么是jpa

1.jpa是对象关系映射(ORM)的规范
2.ORM 就是通过将Java对象映射到数据库表,通过操作Java象,就可以完成对数据表的操作
3.Hibernate是jpa规范的一个实现,不过Hibernate的出现比jpa早

jpa 的使用

1.环境搭建
1.1在maven中导入jpa依赖包

<!-- 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>

1.2核心配置persistence.xml,这个文件要配置在classpath目录的META-INF下(JPA规范要求),classpath指向的是编译后文件的所在地,例如:src/main/java和src/main/reosurce,这两个文件夹下的内容都会被编译到WEB-INF中的class文件夹中

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--持久化单元名-->
    <persistence-unit name="com.wal" transaction-type="RESOURCE_LOCAL">
        <!--持久化单元属性-->
        <properties>
            <!--数据库链接属性-->
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql:///db2020" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="123456" />
            <!-- 必须配置1个方言属性 -->
            <!-- 实现跨数据库关键类 :查询MySQLDialect的getLimitString方法 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

            <!-- 可选配置 -->
            <!-- 是否自动生成表 -->
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <!-- 是否显示sql -->
            <property name="hibernate.show_sql" value="true" />
            <!-- 格式化sql -->
            <!-- <property name="hibernate.format_sql" value="true" /> -->

        </properties>
    </persistence-unit>
</persistence>

2.创建实体对象Employee

//@Entity表示一个由jpa管理的持久对象,对应数据库的一个表
@Entity
// table数据库的表名
@Table(name = "t_employee")
public class Employee {
  // @Id是必须的,是对应表的主键
  @Id
  // @GeneratedValue表示主键的生成方式
  // AUTO自动选择数据库本地的策略:
  // mysql:AUTO_INCREMENT自增
  // oracle:序列
  @GeneratedValue(strategy = GenerationType.AUTO)
  //@Column设置该字段在数据库中的名字
  @Column(name = "e_id")
  private Long id;
  private String name;
  @Column(name = "pwd")
  private String password;

2.1执行流程
创建实体管理工厂获得实体管理者
括号中对应配置文件里面的persistence-unit name=“com.wal”
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(“com.wal”);
EntityManager entityManager = entityManagerFactory.createEntityManager();
开启事务
执行操作CURD
提交事务
关闭资源

		  EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("com.wal");
    // 获取Session对象
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    // 开启事务
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    // 持久操作CUD
    entityManager.persist(employee);
    // 提交事务
    transaction.commit();
    // 关闭资源
    entityManager.close();
    entityManagerFactory.close();
  }	

2.2通过jpql查询数据

		//查询所有数据
		String jpql = "select o from Employee o";
    // 简写
    jpql = "from Employee";
    Query query = entityManager.createQuery(jpql);
    List<Employee> list = query.getResultList();
    System.out.println(list.size());
    for (Employee employee : list) {
      System.out.println(employee);
    }
    entityManager.close();
  }
  
  //通过id查询一条数据
	  EntityManager entityManager = JPAUtils.getEntityManager();
    Employee employee = entityManager.find(Employee.class, 1L);
    System.out.println(employee);
    entityManager.close();
    
    //persist持久化方法,保存方法
	 //merge方法,修改,必须要有id值
	 //remove方法,删除,必须要有id值

2.3建表策略
creat-drop:先删除表,再创建表,再删除表
cerat:先删除表,再创建表,不会再删除表,如果更改了domain类的映射,会马上生效(一般用于测试)
update:如果没表就根据最新的映射信息来创建表
如果表里面已经有这个属性,如修改属性的长度,不会更新到表里面
需要更新这个列先删除表或者删除这个属性对应的列名
如果表里面没有属性,映射信息存在,会增加这个列
validate:表不存在,会抛出异常
Domain类映射信息少属性,表比映射定义的列要多,不会报错

3entitymanagerfactory是一个重量级线程安全的对象,不适合平凡的创建和销毁
entitymanagerfactory中包含
3.1.数据库配置信息它里面有一个连接池(本身就重,创建与销毁太费时间)
3.2.二级缓存(查询缓存,…)
3.3.预定义的JPQL语句(JPQL,SQL)
3.4.所有实体及关系

二级缓存:同一个entitymanagerfactory创建出来的entitymanager共享二级缓存,当一个entitymanager查询一条数据后,如果二级缓存中没有该数据就会保存到二级缓存中,当其他entitymanager来查询同一条数据时不用从数据库中查询,直接从二级缓存中取

二级缓存配置

/依赖导入
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>4.3.8.Final</version>
</dependency>

添加persistence.xml配置信息

<!-- 启用二级缓存 -->
<property name="hibernate.cache.use_second_level_cache" value="true" />
<!-- 二级缓存的实现类 -->
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
<!-- 启用查询缓存 -->
<property name="hibernate.cache.use_query_cache" value="true" />

在上面添加配置二级缓存扫描的策略

<!-- ALL:所有的实体类都被缓存 -->
<!-- NONE:所有的实体类都不被缓存. -->
<!-- ENABLE_SELECTIVE:标识 @Cacheable(true) 注解的实体类将被缓存 -->
<!-- DISABLE_SELECTIVE:缓存除标识 @Cacheable(false) 以外的所有实体类 -->
<!-- UNSPECIFIED:默认值,JPA 产品默认值将被使用 -->
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

domain类的二级缓存

@Entity
@Cacheable(true)
public class Department

命中条件

@Test
public void test2() throws Exception {
	EntityManager entityManager = JPAUtils.getEntityManager();
	//先从一级缓存,二级缓存取数据?取不到,发出sql去获取,填充一级缓存,二级缓存
	Department department1 = entityManager.find(Department.class, 1L);
	//先从一级缓存,二级缓存取数据?一级缓存取到了,返回
	Department department2 = entityManager.find(Department.class, 1L);// 一级缓存命中
	entityManager.close();

	EntityManager entityManager2 = JPAUtils.getEntityManager();
	//先从一级缓存,二级缓存取数据?一级缓存没有取到,但是二级缓存取到了,返回
	Department department3 = entityManager2.find(Department.class, 1L);// 二级缓存命中
	//先从一级缓存,二级缓存取数据?一级缓存取到了,返回
	Department department4 = entityManager2.find(Department.class, 1L);// 一级缓存命中
	entityManager2.close();
}

二级缓存的使用场景
读取大于修改;
对数据要有独享控制,数据不会被第三方修改;
可以容忍出现无效数据,非关键数据(不是财务数据等)
数据量不能超过内存容量,数据量特别巨大,此时不适合于二级缓存(钝化

一级缓存
同一个EntityManagerFactory,同一个EntityManager,查询同一条数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值