JPA第一天

Em的find方法会使用缓存

em.getReference   使用延迟加载策略 返回的是代理对象;

先查再set就能改了,事务提交会自动更新.提交时会比较对象与表数据,不同就更新

 

Mysql用limit    oracle用rownum

Jpa基于框架进行开发,可以随意切换数据库,跨数据库开发

 

需求

  保存一个客户到客户表

步骤

  1.建表

  2.创建工程

  3.引入依赖

  4.建立实体类

    建立类和表的对应关系(加注解)

    @Entity  表示这个类是JPA的一个类,默认表明和类名对应

    @Table(name="cst_customer")  //如果表明和类名一致,可以省略

    建立属性与列的对应关系

    1.主键属性上的注解  

      @Id  //主键属性

      @Column(name="cust_id")  //如果列名和属性名一致,可以省略

      @GeneratedValue(strategy=GenerationType.IDENTITY)    //指定主键生成策略

    2.非主键属性上的注解

      默认情况下不用加注解(要求列名和属性名一样)

    @Column(name="cust_name")  //不一样就要写出来

  5.编写jpa的核心配置文件  persistence.xml

    在src下创建一个META-INF文件夹(固定写法)

    引入约束

      file-new-edit file template-jpa-deployment-persistence_2_0.xml拿过来即可

      persistence-unit//持久化单元     transaction-type//指定事务类型 

<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--指定JPA规范的提供商-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/springdatajpa"/> name  固定写法
<property name="javax.persistence.jdbc.user" value="root"/>  
<property name="javax.persistence.jdbc.password" value="123456"/>
<property name="hibernate.show_sql" value="true"/>  是否展示sql语句  value="true"展示
<property name="hibernate.format_sql" value="true"/>
<!--
create:每次加载hibernate框架,如果有表,先删除表,再创建表
create-drop:每次加载hibernate框架,如果有表,先删除表,再创建表,当程序结束时,再删除表
update:如果没有表,会创建表,不会打印建表语句;如果有表,会比较实体类和表结构是否一致,如果不一致,就更新表结构
validate:如果没有表,会报错;如果有表,会比较实体类和表结构是否一致,如果不一致,就报错
-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>

      RESOURCE_LOCAL:本地事务

         一个项目只有一个数据库

      JTA:分布式事务

        业务中有好多操作,跨数据库存在的,要保证操作在同一个事务中

        要结合第三方技术(如容器)才能使用

       

  6.代码测试

@Test
public void test1() {
Customer customer = new Customer();
customer.setCustName("九阳");

//创建实体管理器工厂EntityManagerFactory=======SqlSessionFactory
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//获取实体管理器EntityManager======SqlSession
EntityManager em = factory.createEntityManager();
//获取事务
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();

//保存
em.persist(customer);
//提交事务
tx.commit();
//释放资源
em.close();
factory.close();
}

  //jpa所有操作包括查询都要放到事务里面去  ★★★

  7.hbm2ddl.auto取值的说明

    ddl:SQL语句的一种data define language,数据定义语言create drop alter

    dml:数据的操纵语言,insert update delete

    dql:数据查询语言,select

    tcl:事务控制语言  commit  rollback

    dcl:数据控制语言  grant  revoke

    hibernate.hbm2ddl.auto  

      create:每次加载hibernate时,如果有表,先删除表,再建表

        好处:不用手动建表

      create-drop:每次加载hibernate框架,如果有表,先删表再建表,程序结束时,再删除表

        作用:用于做测试,测试数据不保存

      update:如果没有表,会创建表但是不会打印建表语句,如果有表,会比较实体类和表结构是否一致,一致啥也不干。如果不一致,更新表结构

      validate:如果没有表,会报错;如果有表,会比较类和表结构是否一致,如果不一致,就报错(持久化异常)

      生产环境中用update  ★★★

 

8.主键生成策略  @GeneratedValue(strategy=GenerationType.IDENTITY)

IDENTITY

  自增,mysql和sql server能自增,oracle不能自增

SEQUENCE

  序列,oracle中的一个对象,通过序列模拟一个自增的效果

TABLE

  通过表来实现自增的效果,通过表来维护主键,一个通用的

AUTO

  自适应,根据底层数据库的不同选择一种策略

    mysql  选表策略(hibernate4,5,用table  3是选的identity)

    oracle  选序列

生产环境中,底层是mysql用IDENTITY,底层是oracle用SEQUENCE  ★★★

   9.JPAUtils类

  由于EntityManagerFactory 是一个线程安全的对象(即多个线程访问同一个EntityManagerFactory 对象不会有线程安全问题),并且EntityManagerFactory 的创建极其浪费资源,所以在使用JPA编程时,我们可以对EntityManagerFactory 的创建进行优化,只需要做到一个工程只存在一个EntityManagerFactory 即可 。

public class JPAUtils {
private static final EntityManagerFactory factory;

//创建EntityManagerFactory
static {
factory = Persistence.createEntityManagerFactory("myJpa");
}

public static EntityManager getEntityManager(){
return factory.createEntityManager();
}
}
测试工具类
@Test
public void test2() {
Customer customer = new Customer();
customer.setCustName("美的");

EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

em.persist(customer);

tx.commit();
em.close();
}
10.查询
/**
* 根据id查询对象
* 立即加载
*/
@Test
public void test1() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Customer customer = em.find(Customer.class, 1L);
System.out.println(customer);

tx.commit();
em.close();
}


@Test
public void test2() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

//先检测缓存里是否有id为1的客户对象,没有,就发送sql语句查询数据库得到一个对象,再把该对象存放到缓存里
Customer customer1 = em.find(Customer.class, 1L);
//先检测缓存里是否有id为1的客户对象,有,就直接用缓存的对象,不再发送sql语句
Customer customer2 = em.find(Customer.class, 1L);
System.out.println(customer1 == customer2);

tx.commit();
em.close();
}
友情提示:这个缓存比mybatis缓存强,mybatis缓存鸡肋,查一个数据,放缓从,事务没提交,做一些增删改,缓存立马失效


/**
* 延迟加载
* 返回的是代理对象
*/
@Test
public void test3() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Customer customer = em.getReference(Customer.class, 1L);
System.out.println(customer);


tx.commit();
em.close();
}
11.修改

  先查询再修改


  事务提交会自动更新


  过程:先查出来,事务提交的时候,会比较对象数据是否和表的记录一致,如果不一致,就把对象信息更新到表里面去


  对象要和em有关系才会自动更新,否则显示调用更新em.merge(""),这个方法容易丢失数据,不推荐使用

/**
* 先查询,再修改
*/
@Test
public void test4() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Customer customer = em.find(Customer.class, 1L);
customer.setCustLevel("普通客户");

tx.commit();//事务提交,会自动更新
em.close();
}

@Test
public void test5() {
Customer customer = new Customer();
customer.setCustId(3L);
customer.setCustName("美的集团");
// customer.setCustIndustry("家电");


EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

em.merge(customer);


tx.commit();
em.close();

}
  12.删除
  
/**
* 先查询,再删除

  先查询,再删除

  detached:游离态,脱管  不受管理

  persistence: 持久态


*/
@Test
public void test6() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Customer customer = em.find(Customer.class, 3L);
em.remove(customer);


tx.commit();//事务提交,会自动更新
em.close();
}

@Test
public void test7() {
Customer customer = new Customer();
customer.setCustId(1L);

EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

em.remove(customer);


tx.commit();
em.close();
}
 13.JPQL

   java Persistence Query Language


   sql:select * from cst_customer


   jpql:from Customer  去掉select * ,将表名换成类名,列名换成属性名,查出的一行数据形成一个对象,放到集合中去返回


   //查询所有


 em.createQuery("from Customer")


 分页查询


 //设置分页信息  mysql分页用limit,oracle分页用rownum  

 查count(*)规定写long

@Test
public void test8() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Query query = em.createQuery("from Customer");
//执行查询
List<Customer> list = query.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}


tx.commit();//事务提交,会自动更新
em.close();
}


@Test
public void test9() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Query query = em.createQuery("from Customer where custName like ? or custIndustry = ?");
//给占位符设置值
query.setParameter(1, "%马%");
query.setParameter(2, "家电");
//执行查询
List<Customer> list = query.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}


tx.commit();//事务提交,会自动更新
em.close();
}


@Test
public void test10() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Query query = em.createQuery("from Customer");
//设置分页信息
query.setFirstResult(2);
query.setMaxResults(2);
List<Customer> list = query.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}



tx.commit();//事务提交,会自动更新
em.close();
}

@Test
public void test11() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Query query = em.createQuery("from Customer order by custName,custId desc");



List<Customer> list = query.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}

tx.commit();//事务提交,会自动更新
em.close();
}

/**
* sum avg count max min
*/
@Test
public void test12() {
EntityManager em = JPAUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Query query = em.createQuery("select count(*) from Customer");


// List<Long> list = query.getResultList();
// System.out.println(list.get(0));
Long total= (Long) query.getSingleResult();
System.out.println(total);
tx.commit();//事务提交,会自动更新
em.close();
}

 

 


 

 
 
 
 

转载于:https://www.cnblogs.com/jameshuangbhlx/p/9821575.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值