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(); }
时间花在哪里,成就就在哪里

浙公网安备 33010602011771号