hiberbate

笔记

1.什么是hibernate
   Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。       Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JaveEE架构中取代CMP,完成数据持久化的重任。
 
特点:
  • 将对数据库的操作转换为对Java对象的操作,从而简化开发。通过修改一个"持久化"对象的属性从而修改数据库表中对应的记录数据。
  • 提供线程和进程两个级别的缓存提升应用程序性能。
  • 有丰富的映射方式将Java对象之间的关系转换为数据库表之间的关系。
  • 屏蔽不同数据库实现之间的差异。在Hibernate中只需要通过"方言"的形式指定当前使用的数据库,就可以根据底层数据库的实际情况生成适合的SQL语句。
  • 非侵入式:Hibernate不要求持久化类实现任何接口或继承任何类,POJO即可。
 
hibernate的基本使用
1.创建maven项目导入依赖
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.4.21.Final</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.4.21.Final</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.12</version>
    </dependency>
</dependencies>

 

2.配置核心文件
    类路径下META-INF下创建persistence.xml文件

 

 

 

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--
    需要配置persistence-unit节点
    持久化单元:
        name:持久化单元名称
        transaction-type:事务管理的方式
            JTA:分布式事务管理
            RESOURCE_LOCAL:本地事务管理


    -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!--jpa的实现方式-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>




        <properties>
            <!--
                数据库信息
                用户名:javax.persistence.jdbc.user
                密码:javax.persistence.jdbc.password
                驱动:javax.persistence.jdbc.driver
                数据库地址:javax.persistence.jdbc.url
            -->
            <property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="645464"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8"/>


            <!--
                可选的配置,配置jpa实现方的配置信息
                显示sql:hibernate.show_sql       true/false
                自动创建数据库表:hibernate.hbm2ddl.auto
                create/update/none
                create:程序运行时创建数据库表(如果有表,先删除再创建)
                update:程序运行时创建表(如果有表,不创建表)
                none:不会创建表
            -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            
        </properties>
    </persistence-unit>


</persistence>

 

3.编写客户的实体类

/**
* 客户的实体类
*      配置映射关系
*          1.实体类和表的映射关系
*          2.实体类属性和表中字段的映射关系
*/


/*
* @Entity:声明实体类
* @Table:配置实体类和表的映射关系
*   name:配置数据库表的名称
*
*
* */


@Entity
@Table(name = "cst_customer")
public class Customer {


    /**
     * @Id:声明主键的配置
     * @GeneratedValue:配置主键的生成策略
     *      strategy:
     *          GenerationType.IDENTITY表示自增
     *
     * @Column:配置属性和字段的映射关系
     *      name:数据库表中字段的名称
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cust_id")
    private Long custId;


    @Column(name = "cust_name")
    private String custName;


    @Column(name = "cust_source")
    private String custSource;


    @Column(name = "cust_industry")
    private String custIndustry;


    @Column(name = "cust_level")
    private String custLevel;


    @Column(name = "cust_address")
    private String custAddress;


    @Column(name = "cust_phone")
    private String custPhone;

 

 4.测试

/**
* 测试jpa的保存
*      案例:保存一个客户到数据库中
* Jpa的操作步骤:
*      1.加载配置文件创建工厂对象(实体管理类工厂)对象
*      2.通过实体管理类工厂获取实体管理器
*      3.获取事务对象,开启事务
*      4.完成增删改查操作
*      5.提交事务(回滚事务)
*      6.释放资源
*/


@Test
public void testSave(){
    //  1.加载配置文件创建工厂对象(实体管理类工厂)对象
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
    //  2.通过实体管理类工厂获取实体管理器
    EntityManager entityManager = factory.createEntityManager();
    //  3.获取事务对象,开启事务
    EntityTransaction tx = entityManager.getTransaction(); //获取事务对象
    tx.begin(); //开启事务


    //  4.完成增删改查操作
    Customer customer = new Customer();
    customer.setCustName("gg");
    customer.setCustAddress("11");
    customer.setCustSource("213");


    //保存
    entityManager.persist(customer);


    //  5.提交事务(回滚事务)
    tx.commit();
    //  6.释放资源(与开启顺序相反)
    entityManager.close();
    factory.close();


}

 

输出

log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Hibernate: drop table if exists cst_customer
Hibernate: create table cst_customer (cust_id bigint not null auto_increment, cust_address varchar(255), cust_industry varchar(255), cust_level varchar(255), cust_name varchar(255), cust_phone varchar(255), cust_source varchar(255), primary key (cust_id)) engine=InnoDB
Hibernate: insert into cst_customer (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source) values (?, ?, ?, ?, ?, ?)

 

 

hibernate主键生成策略

public enum GenerationType {
    TABLE,    //jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
    SEQUENCE,    //序列,oracle,底层数据库必须支持序列
    IDENTITY,    //自增,mysql
    AUTO;        //由程序自动的帮助我们选择主键生成策略

    private GenerationType() {
    }
}

 

hibernate的基本操作

* hibernate的操作步骤:
 
* 1.加载配置文件创建工厂对象(实体管理类工厂)对象
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
Persistence的静态方法createEntityManagerFactory(持久化单元名称)

持久化单元名称:<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">

 

* 2.通过实体管理类工厂获取实体管理器

EntityManager entityManager = factory.createEntityManager();
createEntityManager:
    内部维护了数据库信息
    维护了缓存信息
    维护了所有的实体管理器对象
    在创建EntityManagerFactory的过程中会根据配置创建数据库表
EntityManagerFactory的创建过程比较浪费资源
特点:线程安全的对象
    多个线程访问同一个EntityManagerFactory不会有线程安全问题
如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题
思路:创建一个公共的EntityManagerFactory对象
    静态代码块的形式创建EntityManagerFactory

 

* 3.获取事务对象,开启事务

EntityTransaction tx = entityManager.getTransaction(); //获取事务对象
tx.begin(); //开启事务

EntityManager对象:实体类管理器
    beginTransaction:创建事务对象
    persist:保存 
    merge:更新
    remove:删除
    find/getReference:根据id查询

EntityTransaction对象:事务
    begin:开启事务
    commit:提交事务
    rollback:回滚

 

* 4.完成增删改查操作

1.添加案例persist

public class JpaTest {
    /**
     * 测试jpa的保存
     *      案例:保存一个客户到数据库中
     * Jpa的操作步骤:
     *      1.加载配置文件创建工厂对象(实体管理类工厂)对象
     *      2.通过实体管理类工厂获取实体管理器
     *      3.获取事务对象,开启事务
     *      4.完成增删改查操作
     *      5.提交事务(回滚事务)
     *      6.释放资源
     */


    @Test
    public void testSave(){
        //  1.加载配置文件创建工厂对象(实体管理类工厂)对象
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
        //  2.通过实体管理类工厂获取实体管理器
        EntityManager entityManager = factory.createEntityManager();
        //  3.获取事务对象,开启事务
        EntityTransaction tx = entityManager.getTransaction(); //获取事务对象
        tx.begin(); //开启事务

        //  4.完成增删改查操作
        Customer customer = new Customer();
        customer.setCustName("gg");
        customer.setCustAddress("11");
        customer.setCustSource("213");

        //保存
        entityManager.persist(customer);

        //  5.提交事务(回滚事务)
        tx.commit();


        //  6.释放资源(与开启顺序相反)
        entityManager.close();
        factory.close();


    }

    @Test
    public void test1(){
        EntityManager entityManager = JpaUtils.getEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Customer customer = new Customer();
        customer.setCustName("gg3");
        customer.setCustAddress("11");
        customer.setCustSource("8989");
        entityManager.merge(customer);
        transaction.commit();
    }


    @Test
    public void test2(){
        EntityManager entityManager = JpaUtils.getEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();

        /**
         * find:根据id查询数据
         *      class:查询数据的结果需要包装的实体类类型和字节码
         *      id:查询的主键的取值
         */
        Customer customer = entityManager.find(Customer.class, 2L);
        System.out.println(customer);


        transaction.commit();
        entityManager.close();
    }


    @Test
    public void test3(){
        EntityManager entityManager = JpaUtils.getEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        
        Customer customer = entityManager.getReference(Customer.class, 2L);
        System.out.println(customer);


        transaction.commit();
        entityManager.close();
    }

}

 

 2.查询案例
find与的getReference区别
/**
* 根据id查询客户
*     使用find方法查询:
*          1.查询的对象就是当前客户对象本身
*          2.在调用find方法的时候,就会发送sql语句查询数据库
*     * 立即加载
*/

============================================================

/**
* 根据id查询客户
*      getReference方法
*          1.获取的对象是一个动态代理对象
*          2.调用getReference方法不会立即发送sql语句查询数据库
*              * 当调用查询结果对象的时候,才会发送查询的sql语句,
*              * 什么时候用,什么时候发送sql语句查询数据库
*  延迟加载(懒加载)
*      * 得到的是一个动态代理对象
*      * 什么时候使用才会查询
*/

 

3.删除案例remove

@Test
public void testDelete(){
    EntityManager entityManager = JpaUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();

    Customer customer = entityManager.find(Customer.class, 4L);
    entityManager.remove(customer);

    transaction.commit();
}

 

 4.修改merge

//更新merge
@Test
public void testUpdate(){
    EntityManager entityManager = JpaUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();


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


    customer.setCustAddress("001");
    customer.setCustName("可可");
    customer.setCustIndustry("乱码");


    entityManager.merge(customer);


    transaction.commit();
}

 

 5.查询全部

/**
     * 查询全部
     *      jpql:
     *      sql:select * from com.gg.domain.Customer
     */
    @Test
    public void TestFindAll(){
        // 1.获取entityManager
        EntityManager entityManager = JpaUtils.getEntityManager();
        // 2.开启事务
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();


        // 3.查询全部
//        String jpql = "from com.gg.domain.Customer";
        String jpql = "from Customer";
        // 创建Query查询对象,query对象才是执行jpql对象
        Query query = entityManager.createQuery(jpql);
        //发送查询,并封装结果集
        List list = query.getResultList();


        for (Object obj : list) {
            System.out.println(obj);
        }


        // 4.提交事务
        tx.commit();
        // 5.释放资源
        entityManager.close();
    }

 

 6.倒序查询

/**
*  排序查询:倒序查询全部客户(根据id倒序)
*      sql:select * from cst_customer order by cust_id desc
*      jpql: from Customer order by custId desc
*/
@Test
public void TestFindAllOrder(){
    // 1.获取entityManager
    EntityManager entityManager = JpaUtils.getEntityManager();
    // 2.开启事务
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();


    // 3.查询全部
    String jpql = "from Customer order by custId desc";
    // 创建Query查询对象,query对象才是执行jpql对象
    Query query = entityManager.createQuery(jpql);
    //发送查询,并封装结果集
    List list = query.getResultList();


    for (Object obj : list) {
        System.out.println(obj);
    }


    // 4.提交事务
    tx.commit();
    // 5.释放资源
    entityManager.close();
}

 

 7.查询记录数

/**
*  sql: select COUNT(cust_id) From cst_customer
*  jpql: select COUNT(cust_id) From cst_customer
*/
@Test
public void TestCount(){
    // 1.获取entityManager
    EntityManager entityManager = JpaUtils.getEntityManager();
    // 2.开启事务
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();

    // 3.查询全部
    String jpql = "select COUNT(custId) From Customer";
    // 创建Query查询对象,query对象才是执行jpql对象
    Query query = entityManager.createQuery(jpql);
    //发送查询,并封装结果集
    Object singleResult = query.getSingleResult();
    System.out.println(singleResult);

    // 4.提交事务
    tx.commit();
    // 5.释放资源
    entityManager.close();


}

 

 8.分页查询

/**
* 分页查询
*  sql: select * From cst_customer limit ?,?
*  jpql: From Customer
*/
@Test
public void TestLimit(){
    // 1.获取entityManager
    EntityManager entityManager = JpaUtils.getEntityManager();
    // 2.开启事务
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();


    // 3.查询全部
    String jpql = "From Customer";
    // 1-创建Query查询对象,query对象才是执行jpql对象
    Query query = entityManager.createQuery(jpql);
    // 2-对参数赋值


    // 起始索引
    query.setFirstResult(1);
    // 页大小
    query.setMaxResults(2);


    // 3-发送查询,并封装结果集
    List resultList = query.getResultList();

    for (Object o : resultList) {
        System.out.println(o);
    }
    // 4.提交事务
    tx.commit();
    // 5.释放资源
    entityManager.close();


}

 

9.条件查询方式1

/**
* 条件查询
* 查询以xxx开头的客户
*      sql: select * From cst_customer where cust_name like '%gg%'
*      jpql: From Customer where custName like '%gg%'
*/
@Test
public void TestLike(){
    // 1.获取entityManager
    EntityManager entityManager = JpaUtils.getEntityManager();
    // 2.开启事务
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();


    // 3.查询全部
    String jpql = "From Customer where custName like :cust_name ";    //jpql也支持占位符
    // 1-创建Query查询对象,query对象才是执行jpql对象
    Query query = entityManager.createQuery(jpql);
    // 2-对参数赋值


    // 第一个参数:占位符的索引位置(从0开始),第二个参数:取值
    query.setParameter("cust_name","可%");


    // 3-发送查询,并封装结果集
    List resultList = query.getResultList();


    for (Object o : resultList) {
        System.out.println(o);
    }
    // 4.提交事务
    tx.commit();
    // 5.释放资源
    entityManager.close();


}

 

 10.条件查询方式2

@Test
public void TestLike1(){
    // 1.获取entityManager
    EntityManager entityManager = JpaUtils.getEntityManager();
    // 2.开启事务
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();


    // 3.查询全部
    String jpql = "From Customer where custName like ?1 ";    //jpql也支持占位符
    // 1-创建Query查询对象,query对象才是执行jpql对象
    Query query = entityManager.createQuery(jpql);
    // 2-对参数赋值


    // 第一个参数:占位符的索引位置(从0开始),第二个参数:取值
    query.setParameter(1,"可%");


    // 3-发送查询,并封装结果集
    List resultList = query.getResultList();


    for (Object o : resultList) {
        System.out.println(o);
    }
    // 4.提交事务
    tx.commit();
    // 5.释放资源
    entityManager.close();


}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-04-27 17:45  G-G  阅读(167)  评论(0)    收藏  举报