Hibernate (ORM)

AI训练师团队管理运营思路 工具运营AI训练师主要是支撑运营,协助算法和运营提高托管机器人的解决能力,以协助降低业务场景熔断与优化场景识别为核心运营目标,通过算法聚类、标注分析等方式,结合业务知识,提供精准、清晰的标注数据和解决方案,确保训练效果满足需求。过程中需要与算法、运营一块参与模型搭建和数据验收,并且负责核心指标和数据日常的跟踪维护。④针对知识库已有意图进行梳理和分析,反馈运营评估缺失或合并意图优化方向。③对语料数据进行挖掘、清洗,解除缠绕、冗余等问题导致的未识别。①线上case分析,及时发现识别问题导致的托管熔断问题。 阅读详情
1 框架体系结构

 

2 hibernate入门

2.1 ORM框架

 

 

Hibernate是一个数据持久化层的ORM框架.

Object:对象,java对象,此处特指JavaBean

Relational:关系,二维表,数据库中的表。

映射|映射元数据:对象中属性,与表的字段,存在对应关系。

 

 

 

2.2 什么是hibernate

 

 

l Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架

  • ORM 就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作

l Hibernate提供了对关系型数据库增删改成操作

 

2.3 主流的ORM框架

n JPA Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系(只有接口规范)

n Hibernate 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL

n MyBatis  本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架

n Apache DBUtils 、Spring JDBCTemplate

 

2.4 优点

l Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

l Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作  session.save(User);

l Hibernate使用java的反射机制

l Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系

 

 

 

 

3 入门案例【掌握】

3.1 编写流程

l 1. 导入jar包

l 2. 创建数据库和表

l 3. 编写核心配置文件(hibernate.cfg.xml)--> 配置获得链接等参数

l 4. 编写映射文件 hibernate mapping(*.hbm.xml)

l 5 使用api测试

 

3.2 数据库和表

create database h_day01_db;

use h_day01_db;

create table t_user(

  id int auto_increment primary key,

  username varchar(50),

  password varchar(30)

);

 

 

3.3 导入jar包

l 版本:3.6.10   --> hibernate 4 建议注解开发,hibernate 4 对 3 不兼容。

l 目录结构

 

 

l jar介绍

核心:

 

必须:\lib\required

jpa规范:lib\jpa

mysql驱动:

 

 

 

 

3.4 编写JavaBean + 映射文件

l 文件位置:javabean同包

l 文件名称:javabean同名

l 扩展名:*.hbm.xml

l 内容:

 

添加约束

 

 

 

 

 

public class User {

 

/*

 * create table t_user(

  id int auto_increment primary key,

  username varchar(50),

  password varchar(30)

);

 */

private Integer uid;

private String username;

private String password;

 

<!DOCTYPE hibernate-mapping PUBLIC 

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="com.itheima.a_hello.User" table="t_user">

<!-- 主键 -->

<id name="uid">

<!-- 固定值:主键生成策略 -->

<generator class="native"></generator>

</id>

 

<!-- 普通属性 -->

<property name="username"></property>

<property name="password"></property>

 

</class>

</hibernate-mapping>

 

 

 

3.5 编写核心配置文件

l 位置:类路径(classpath、src)-->WEB-INF/classes

l 名称:hibernate.cfg.xml

l 内容:

添加约束

 

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<!-- SessionFactory,相当于之前学习连接池配置 -->

<session-factory>

<!-- 1 基本4项 -->

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>

<property name="hibernate.connection.username">root</property>

<property name="hibernate.connection.password">1234</property>

 

<!-- 添加映射文件 -->

<mapping resource="com/itheima/a_hello/User.hbm.xml"/>

</session-factory>

 

</hibernate-configuration>

 

 

3.6 测试

@Test

public void demo01(){

User user = new User();

user.setUsername("伟哥哥");

user.setPassword("1234");

 

 

//1 加载配置文件获得核心配置对象

Configuration config = new Configuration().configure();

//2 获得工厂 SessionFactory,相当于连接池

SessionFactory factory = config.buildSessionFactory();

//3获得会话session,相当于链接Connection

Session session = factory.openSession();

//4 开启事务

Transaction transaction = session.beginTransaction();

 

//操作

session.save(user);

 

//5 提交事务 | 回滚事务

transaction.commit();

//6 释放资源--关闭session

session.close();

//7 释放资源--关闭工厂factory

factory.close();

}

 

3.7 常见异常

 

解决方案:

将映射文件添加到核心配置文件中  hbm.xml  --> hibernate.cfg.xml

 

 

4 api详解【多练】

4.1 体系结构

 

 

PO:persistent object ,用于与数据库交互数据。--dao层  (JavaBean + hbm )

BO:Business object 业务数据对象。--service层

VO:Value Object 值对象。--web层

开发中:直接使用JavaBean 描述三个对象。

 

 

 

4.2 Configuration 配置对象

l hibernate 核心配置文件种类

hibernate.cfg.xml 通常使用xml配置文件,可以配置内容更丰富。

hibernate.properties 用于配置key/value 形式的内容,key不能重复的。配置有很多的局限性。一般不用。

参考文件:hibernate-distribution-3.6.10.Final\project\etc\ hibernate.properties

提供了核心配置文件常用的配置项,及选择参数。

1.提供构造  new Configuration() hibernate将自动加载 hibernate.properties文件

hibernate.properties文件必须存放在类路径(src)下

2.提供方法 configure() 将加载src下的hibernate.cfg.xml

 

 

3.扩展api

configure(String) 加载指定目录下的 xml文件

4.手动加载配置文件

// 手动加载指定的配置文件

config.addResource("com/itheima/a_hello/User.hbm.xml");

 

// 手动加载指定类,对应的映射文件 User--> User.hbm.xml

config.addClass(User.class);

 

 

 

l 常见异常:

 

 

开发中:将hbm.xml映射 配置 hibernate.cfg.xml

学习中:可以使用 addClass  或 addResource

 

4.3 SessionFactory工厂

l SessionFactory 相当于java web连接池,用于管理所有session

l 获得方式:config.buildSessionFactory();

l sessionFactory hibernate缓存配置信息 (数据库配置信息、映射文件,预定义HQL语句 等)

l SessionFactory线程安全,可以是成员变量,多个线程同时访问时,不会出现线程并发访问问题。

l 提供api:

//打开一个新的会话 session

factory.openSession();

//获得当前线程中绑定的会话session

factory.getCurrentSession();

hibernate支持,将创建的session绑定到本地线程中,底层使用ThreadLocal,在程序之间共享session。

1.必须在hibernate.cfg.xml 配置

<!-- 2 与本地线程绑定 -->

<property name="hibernate.current_session_context_class">thread</property>

 

2.如果提交或回滚事务,底层将自动关闭session

 

 

 

 

4.4 Session 会话

l Session 相当于 JDBC的 Connection -- 会话

 

l 通过session操作PO对象 --增删改查

l session单线程,线程不安全,不能编写成成员变量。

l session api

save 保存

update 更新

delete 删除

get 通过id查询,如果没有 null

load 通过id查询,如果没有抛异常

createQuery("hql")  获得Query对象

createCriteria(Class) 获得Criteria对象

 

 

 

4.5 Transaction 事务

开启事务 beginTransaction()

获得事务 getTransaction()

 

提交事务:commit()

回滚事务:rollback()

 

try{

   //开启

   //session操作

   //提交

} catch(e){

   //回滚

}

扩展:不需要手动的管理事务,之后所有的事务管理都交予spring。

 

4.6 Query对象

l hibernate执行hql语句

l hql语句:hibernate提供面向对象查询语句,使用对象(类)和属性进行查询。区分大小写。

l 获得 session.createQuery("hql")

l 方法:

list()  查询所有

uniqueResult() 获得一个结果。如果没有查询到返回null,如果查询多条抛异常。

 

setFirstResult(int) 分页,开始索引数startIndex

setMaxResults(int) 分页,每页显示个数 pageSize

 

4.7 Criteria对象(了解)

l QBC(query by criteria),hibernate提供纯面向对象查询语言,提供直接使用PO对象进行操作。

l 获得方式:Criteria criteria = session.createCriteria(User.class);

l 条件

criteria.add(Restrictions.eq("username", "tom"));

// Restrictions.gt(propertyName, value) 大于

// Restrictions.ge(propertyName, value) 大于等于

// Restrictions.lt(propertyName, value) 小于

// Restrictions.le(propertyName, value) 小于等于

// Restrictions.like(propertyName, value) 模糊查询,注意:模糊查询值需要使用 % _

 

4.8 工具类

public class H3Utils {

 

// 会话工厂,整个程序只有一份。

private static SessionFactory factory;

 

static{

//1 加载配置

Configuration config = new Configuration().configure();

 

//2 获得工厂

factory = config.buildSessionFactory();

//3 关闭虚拟机时,释放SessionFactory

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

 

@Override

public void run() {

System.out.println("虚拟机关闭!释放资源");

sf.close();

}

}));

}

 

 

/**

 * 获得一个新的session

 * @return

 */

public static Session openSession(){

return factory.openSession();

}

 

/**

 * 获得当前线程中绑定session

 * * 注意:必须配置

 * @return

 */

public static Session getCurrentSession(){

return factory.getCurrentSession();

}

 

 

}

 

 

 

 

5 核心配置文件详解

 

5.1 详细配置【多读】

<!-- SessionFactory,相当于之前学习连接池配置 -->

<session-factory>

<!-- 1 基本4项 -->

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>

<property name="hibernate.connection.username">root</property>

<property name="hibernate.connection.password">1234</property>

 

<!-- 2 与本地线程绑定 -->

<property name="hibernate.current_session_context_class">thread</property>

 

  <!-- 3 方言:为不同的数据库,不同的版本,生成sql语句(DQL查询语句)提供依据

  * mysql 字符串 varchar

  * orcale 字符串 varchar2

  -->

  <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

 

<!-- 4 sql语句 -->

<!-- 显示sql语句 -->

<property name="hibernate.show_sql">true</property>

<property name="hibernate.format_sql">true</property>

 

<!-- 5 自动创建表(了解) ,学习中使用,开发不使用的。

* 开发中DBA 先创建表,之后根据表生产 PO类

* 取值:

update:【】

如果表不存在,将创建表。

如果表已经存在,通过hbm映射文件更新表(添加)。(映射文件必须是数据库对应)

表中的列可以多,不负责删除。

create :如果表存在,先删除,再创建。程序结束时,之前创建的表不删除。【】

create-drop:与create几乎一样。如果factory.close()执行,将在JVM关闭同时,将创建的表删除了。(测试)

validate:校验 hbm映射文件 和 表的列是否对应,如果对应正常执行,如果不对应抛出异常。(测试)

-->

<property name="hibernate.hbm2ddl.auto">create</property>

 

<!-- 6 java web 6.0 存放一个问题

* BeanFactory 空指针异常

异常提示:org.hibernate.HibernateException: Unable to get the default Bean Validation factory

* 解决方案:取消bean校验

-->

<property name="javax.persistence.validation.mode">none</property>

 

<!-- 添加映射文件

<mapping >添加映射文件

resource 设置 xml配置文件 (addResource(xml))

class 配置类 (addClass(User.class)) 配置的是全限定类名

-->

<mapping  resource="com/itheima/a_hello/User.hbm.xml"/>

</session-factory>

 

6 Hibernate中持久化类

6.1 编写规则

  • 提供一个无参数 public访问控制符的构造器
  • 提供一个标识属性,映射数据表主键字段
  • 所有属性提供public访问控制符的 set  get 方法(javaBean)
  • 标识属性应尽量使用基本数据类型的包装类型
  • 不要用final修饰实体 (将无法生成代理对象进行优化)

6.2 持久化对象的唯一标识 OID

l Java按地址区分同一个类的不同对象.

l 关系数据库用主键区分同一条记录

l Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系

结论: 对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID付值

6.3 区分自然主键和代理主键

l 主键需要具备: 不为空/不能重复/不能改变

自然主键: 在业务中,某个属性符合主键的三个要求.那么该属性可以作为主键列.

代理主键: 在业务中,不存符合以上3个条件的属性,那么就增加一个没有意义的列.作为主键.

6.4 基本数据与包装类型

l 基本数据类型和包装类型对应hibernate的映射类型相同

l 基本类型无法表达null、数字类型的默认值为0。

l 包装类默认值是null。当对于默认值有业务意义的时候需要使用包装类。

 

6.5 类型对应

Java数据类型

Hibernate数据类型

标准SQL数据类型
(PS:对于不同的DB可能有所差异)

byte、java.lang.Byte

byte

TINYINT

short、java.lang.Short

short

SMALLINT

int、java.lang.Integer

integer

INGEGER

long、java.lang.Long

long

BIGINT

float、java.lang.Float

float

FLOAT

double、java.lang.Double

double

DOUBLE

java.math.BigDecimal

big_decimal

NUMERIC

char、java.lang.Character

character

CHAR(1)

boolean、java.lang.Boolean

boolean

BIT

java.lang.String

string

VARCHAR

boolean、java.lang.Boolean

yes_no

CHAR(1)('Y'或'N')

boolean、java.lang.Boolean

true_false

CHAR(1)('Y'或'N')

java.util.Date、java.sql.Date

date

DATE

java.util.Date、java.sql.Time

time

TIME

java.util.Date、java.sql.Timestamp

timestamp

TIMESTAMP

java.util.Calendar

calendar

TIMESTAMP

java.util.Calendar

calendar_date

DATE

byte[]

binary

VARBINARY、BLOB

java.lang.String

text

CLOB

java.io.Serializable

serializable

VARBINARY、BLOB

java.sql.Clob

clob

CLOB

java.sql.Blob

blob

BLOB

java.lang.Class

class

VARCHAR

java.util.Locale

locale

VARCHAR

java.util.TimeZone

timezone

VARCHAR

java.util.Currency

currency

VARCHAR

6.6 普通属性

<hibernate-mapping>

package 用于配置PO类所在包

例如: package="com.itheima.d_hbm"

<class> 配置 PO类 和 表 之间对应关系

name:PO类全限定类名

例如:name="com.itheima.d_hbm.Person"

如果配置 package,name的取值可以是简单类名 name="Person"

table : 数据库对应的表名

dynamic-insert="false" 是否支持动态生成insert语句

dynamic-update="false" 是否支持动态生成update语句

如果设置true,hibernate底层将判断提供数据是否为null,如果为null,insert或update语句将没有此项。

普通字段

<property>

name : PO类的属性

column : 表中的列名,默认name的值相同

type:表中列的类型。默认hibernate自己通过getter获得类型,一般情况不用设置

取值1: hibernate类型

string 字符串

integer 整形

取值2: java类型 (全限定类名)

java.lang.String 字符串

取值3:数据库类型

varchar(长度) 字符串

int 整形

<property name="birthday">

  <column name="birthday" sql-type="datetime"></column>

  </property>

  javabean 一般使用类型 java.util.Date

  jdbc规范提供3中

  java类型 mysql类型

  java.sql.Date date

  java.sql.time time

  java.sql.timestamp timestamp

  null datetime

 

  以上三个类型都是java.util.Date子类

 

length : 列的长度。默认值:255

not-null : 是否为null

unique : 是否唯一

access:设置映射使用PO类属性或字段

property : 使用PO类属性,必须提供setter、getter方法

field : 使用PO类字段,一般很少使用。

insert 生成insert语句时,是否使用当前字段。

update 生成update语句时,是否使用当前字段。

默认情况:hibernate生成insert或update语句,使用配置文件所有项

注意:配置文件如果使用关键字,列名必须使用重音符

 

 

 

6.7 主键

主键

<id>配置主键

name:属性名称

access="" 设置使用属性还是字段

column=""  表的列名

length=""  长度

type="" 类型

<generator> class属性用于设置主键生成策略

1.increment 由hibernate自己维护自动增长

底层通过先查询max值,再+1策略

不建议使用,存在线程并发问题

2.identity hibernate底层采用数据库本身自动增长列

例如:mysql auto_increment

3.sequence hibernate底层采用数据库序列

例如:oracle 提供序列

4.hilo 

 

         </generator>

5.native 根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个。【】

##以上策略使用整形,long, short 或者 int 类型

6.uuid 采用字符串唯一值【】

##以上策略 代理主键,有hibernate维护。

7.assigned 自然主键,由程序自己维护。【】

 

 

 

 

 

1 对象状态与一级缓存

1.1 状态介绍

l hibernate 规定三种状态:瞬时态、持久态、脱管态

l 状态

瞬时态:transient,session没有缓存对象,数据库也没有对应记录。

OID特点:没有值

持久态:persistent,session缓存对象,数据库最终会有记录。(事务没有提交)

OID特点:有值

脱管态:detached,session没有缓存对象,数据库有记录。

OID特点:有值

 

1.2 转换

 

 

1.2.1 瞬时态/临时态

l 获得:一般都只直接创建(new)

l 瞬时态 转换 持久态

一般操作:save方法、saveOrUpdate

l 瞬时态 转换 脱管态

一般操作:通过setId方法设置数据

 

例如:

User user = new User(); //瞬时态

user.setUid(1); //脱管态

 

1.2.2 持久态

l 获得:

查询操作:get、loat、createQuery、createCriteria 等 获得都是持久态【】

执行save之后持久态

执行update之后持久态

l 持久态 转换 瞬时态

官方规定执行delete()  --民间:删除态

l 持久态 转换 脱管态

session没有记录

session.close () 关闭

session.clear() 清除所有

session.evict(obj) 清除指定的PO对象

 

1.2.3 脱管态/游离态

l 获得:

创建、并设置OID的

通过api获得

l 脱管态 转换 瞬时态

手动去除OID,设置成默认值

l 脱管态 转换 持久态

一般操作:update()、saveOrUpdate

 

 

 

 

@Test

public void demo01(){

User user = new User(); //瞬时态

user.setUsername("jack");

user.setPassword("1234"); //瞬时态(与oid没有关系)

 

Session session = factory.openSession();

session.beginTransaction();

 

session.save(user); //持久态

//---- 持久态就应该有持久态的行为(特性)

 

// user.setUsername("rose");  //持久态对象 被修改后,hibernate将自动生成update语句

// session.flush();

 

 

session.getTransaction().commit();

session.close();

 

System.out.println(user);  //脱管态

}

 

 

 

2 一级缓存

2.1 介绍

l 一级缓存:又称为session级别的缓存。当获得一次会话(session),hibernate在session中创建多个集合(map),用于存放操作数据(PO对象),为程序优化服务,如果之后需要相应的数据,hibernate优先从session缓存中获取,如果有就使用;如果没有再查询数据库。当session关闭时,一级缓存销毁。

 

2.2 一级缓存操作

2.2.1 证明一级缓存

@Test

public void demo02(){

//证明一级缓存

Session session = factory.openSession();

session.beginTransaction();

 

//1 查询 id = 1

User user = (User) session.get(User.class, 1);

System.out.println(user);

//2 再查询 -- 不执行select语句,将从一级缓存获得

User user2 = (User) session.get(User.class, 1);

System.out.println(user2);

 

session.getTransaction().commit();

session.close();

}

 

2.2.2 移除

@Test

public void demo03(){

//清除缓存

Session session = factory.openSession();

session.beginTransaction();

 

User user = (User) session.get(User.class, 1);  //--select

System.out.println(user);

 

//清除

//session.clear();

session.evict(user);

 

// 一级缓存没有缓存对象,从数据库直接查询

User user2 = (User) session.get(User.class, 1);  //--select

System.out.println(user2);

 

session.getTransaction().commit();

session.close();

}

 

2.2.3 一级缓存快照【掌握】

l 快照:与一级缓存一样的存放位置,对一级缓存数据备份。保证数据库的数据与 一级缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库。

 

 

 

2.2.4 refresh 刷新

l refresh 保证 一级缓存的数据 与 数据库的数据 保持一致。将执行select语句查询数据库,将一级缓存中的数据覆盖掉。只要执行refresh都将执行select语句。

@Test

public void demo04(){

//刷新

Session session = factory.openSession();

session.beginTransaction();

 

User user = (User) session.get(User.class, 1);  //--select

System.out.println(user);

 

session.refresh(user);

 

session.getTransaction().commit();

session.close();

}

 

2.2.5 快照演示(一级缓存刷新)

@Test

public void demo05(){

//快照

Session session = factory.openSession();

session.beginTransaction();

 

User user = (User) session.get(User.class, 1);  //--select

System.out.println(user);

 

//修改持久态对象内容(一级缓存内容)--默认在commit时,将触发update语句。

user.setUsername("rose2");

 

 

session.getTransaction().commit();

session.close();

}

 

l 问题:一级缓存什么时候刷新?(了解)

默认情况提交(commit())刷新。

 

 

@Test

public void demo06(){

//设置刷新时机

Session session = factory.openSession();

session.beginTransaction();

 

//1 设置

session.setFlushMode(FlushMode.MANUAL);

 

User user = (User) session.get(User.class, 1);

user.setUsername("rose4");

 

//1 查询所有 -- AUTO , 查询之前先更新,保存一级缓存和数据库一样的

//List<User> allUser = session.createQuery("from User").list();

 

//2手动刷新 --MANUAL 将执行update,注意:一级缓存必须修改后的

session.flush();

 

// 如果MANUAL 在执行commit 不进行update

session.getTransaction().commit();

session.close();

}

 

2.3 PO对象操作

2.3.1 save & persist

l save方法:瞬时态 转换 持久态 ,会初始化OID

1.执行save方法,立即触发insert语句,从数据库获得主键的值(OID值)

2.执行save方法前,设置OID将忽略。

3.如果执行查询,session缓存移除了,在执行save方法,将执行insert

 

@Test

public void demo01(){

User user = new User();

user.setUid(100);

user.setUsername("jack");

user.setPassword("1234");

 

Session session = factory.openSession();

session.beginTransaction();

 

 

session.save(user);

 

 

session.getTransaction().commit();

session.close();

}

 

@Test

public void demo03(){

//代理  assigned

User user = new User();

//user.setUid(100);

user.setUsername("jack");

user.setPassword("1234");

 

Session session = factory.openSession();

session.beginTransaction();

 

 

session.save(user);

 

 

session.getTransaction().commit();

session.close();

}

 

 

l 注意:持久态对象不能修改OID的值

 

 

 

@Test

public void demo04(){

 

Session session = factory.openSession();

session.beginTransaction();

 

 

User user = (User) session.get(User.class, 100);

user.setUid(101);

 

session.save(user);

 

session.getTransaction().commit();

session.close();

}

l persist方法:瞬时态 转换 持久态 ,不会立即初始化OID

 

注意: persist方法不会立即得到ID,所以执行sql语句的时机要靠后.

 

2.3.2 update

l update:脱管态 转换 持久态

如果OID在数据存放的,将执行update语句

如果OID不存在将抛异常

@Test

public void demo01(){

//自然 assigned

User user = new User();

user.setUid(101);

user.setUsername("jack1");

user.setPassword("12345");

 

Session session = factory.openSession();

session.beginTransaction();

 

 

session.update(user);

 

 

session.getTransaction().commit();

session.close();

}

 

l 注意1:如果数据没有修改,执行save方法,将触发update语句。

查询速度 比 更新速度快

通过<class select-before-update> 来设置更新前先查询,如果没有改变就不更新。

 

 

 

总结:

update 之后对象 持久态

 

@Test

public void demo03(){

// merge 合并

User user = new User();

user.setUid(1);

user.setUsername("jack3");

user.setPassword("12345");

 

Session session = factory.openSession();

session.beginTransaction();

 

 

// 1 oid =1 持久态对象

User user2 = (User) session.get(User.class, 1);

 

// session.update(user);

session.merge(user);

 

 

session.getTransaction().commit();

session.close();

}

 

2.3.3 saveOrUpdate

l 代理主键:

判断是否有OID

如果没有OID,将执行insert语句

如果有OID,将执行update语句。

@Test

public void demo02(){

// 代理 native

User user = new User();

// user.setUid(2);

user.setUsername("jack2");

user.setPassword("12345");

 

Session session = factory.openSession();

session.beginTransaction();

 

 

session.saveOrUpdate(user);

 

 

session.getTransaction().commit();

session.close();

}

 

l 自然主键:

先执行select语句,查询是否存放

如果不存在,将执行insert

如果存在,将执行update

@Test

public void demo02(){

// 自然 assigned

User user = new User();

user.setUid(2);

user.setUsername("jack2333");

user.setPassword("12345333");

 

Session session = factory.openSession();

session.beginTransaction();

 

 

session.saveOrUpdate(user);

 

 

session.getTransaction().commit();

session.close();

}

 

 

l 注意1:native下,默认OID是否存在,使用默认值。例如:Integer 默认null

通过<id  unsaved-value="1"> 修改使用默认值,如果设置1进行insert语句。此内容提供hibernate使用的,录入到数据库后,采用自动增长。

 

 

 

 

2.3.4 delete

 

总结:

PO对象状态:瞬时态、持久态、脱管态

 

 

 

3 多表设计

l 在开发中,前期进行需求分析,需求分析提供E--R图,根据ER图编写表结构。

l 表之间关系存在3种:一对多、多对多、一对一。(回顾)

 

 

一对多:1表(主表)必须主键 和 多表(从表)必须外键,主表的主键 与 从表外键 形成主外键关系

多对多:提供中间表(从表),提供2个字段(外键)分别对应两个主表。

一对一:???

 

 

 

l 面单对象描述 对象与对象 之间关系?【掌握】

一对多:客户和订单

private class Customer{

//一对多:一个客户 拥有 多个订单

private Set<Order> orderSet;

}

private class Order{

//多对一:多个订单 属于 一个客户

private Customer customer;

}

多对多:Student学生 和 Course课程

private class Student{

//多对多:多个学生(当前)学习 【不同课程】

private Set<Course> courseSet ...;

}

private class Course{

//多对多:多个课程 可以被 【不同学生】学习

private Set<Student> student = ...;

}

一对一:公司company 和 地址address

private class Company{

private Address address;

}

private class Address{

private Company company;

}

 

4 关联关系映射

4.1 一对多实现【掌握】

4.1.1 实现类

public class Customer {

 

private Integer cid;

private String cname;

 

//一对多:一个客户(当前客户) 拥有 【多个订单】

// * 需要容器存放多个值,一般建议Set (不重复、无序)

// * 参考集合:List、Map、Array等

// ** 建议实例化--使用方便

private Set<Order> orderSet = new HashSet<Order>();

 

public class Order {

private Integer xid;

private String price;

 

//多对一:多个订单属于【一个客户】

private Customer customer;

 

 

4.1.2 配置文件

l Customer.hbm.xml

<class name="com.itheima.b_onetomany.Customer" table="t_customer">

<id name="cid">

<generator class="native"></generator>

</id>

<property name="cname"></property>

 

<!-- 一对多:一个客户(当前客户) 拥有 【多个订单】

1 确定容器  set <set>

2 name确定对象属性名

3 确定从表外键的名称

4 确定关系,及另一个对象的类型

注意:

在hibernate中可以只进行单向配置

每一个配置项都可以完整的描述彼此关系。

一般情况采用双向配置,双方都可以完成描述表与表之间关系。

 -->

<!-- 一对多:一个客户(当前客户) 拥有 【多个订单】 -->

<set name="orderSet" cascade="delete-orphan">

<key column="customer_id"></key>

<one-to-many class="com.itheima.b_onetomany.Order"/>

</set>

</class>

 

l Order.hbm.xml

<class name="com.itheima.b_onetomany.Order" table="t_order">

<id name="xid">

<generator class="native"></generator>

</id>

<property name="price"></property>

 

<!-- 多对一:多个订单属于【一个客户】

* name 确定属性名称

* class 确定自定义类型

* column 确定从表的外键名称

-->

<many-to-one name="customer" class="com.itheima.b_onetomany.Customer" column="customer_id"></many-to-one>

 

</class>

 

 

 

 

 

4.2 一对多操作

4.2.1 保存客户

@Test

public void demo01(){

// 1 创建客户,并保存客户--成功

Session session = factory.openSession();

session.beginTransaction();

 

Customer customer = new Customer();

customer.setCname("田志成");

 

session.save(customer);

 

session.getTransaction().commit();

session.close();

}

 

4.2.2 保存订单

@Test

public void demo02(){

// 2 创建订单,保存订单--成功,外键为null

Session session = factory.openSession();

session.beginTransaction();

 

Order order = new Order();

order.setPrice("998");

 

session.save(order);

 

session.getTransaction().commit();

session.close();

}

 

4.2.3 客户关联订单,只保存客户

@Test

public void demo03(){

// 3 创建客户和订单,客户关联订单,保存客户?

Session session = factory.openSession();

session.beginTransaction();

 

//1 客户和订单

Customer customer = new Customer();

customer.setCname("成成");

 

Order order = new Order();

order.setPrice("998");

 

//2 客户关联订单

customer.getOrderSet().add(order);

 

//3 保存客户

session.save(customer);

 

session.getTransaction().commit();

session.close();

}

 

 

 

 

4.2.4 双向关联,使用inverse

 

 

 

@Test

public void demo04(){

// 4  创建客户和订单,客户关联订单,订单也关联客户,保存客户和订单?

// * 开发中优化程序 , n + 1 问题?

// ** 解决方案1:客户不关联订单 ,不建议

// ** 解决方案2:客户放弃对订单表外键值的维护。

// **** Customer.hbm.xml <set name="orderSet" inverse="true">

// ** inverse 将维护外键值的权利交予对象。相当于自己放弃。(反转)

Session session = factory.openSession();

session.beginTransaction();

 

//1 客户和订单

Customer customer = new Customer();

customer.setCname("成成");

 

Order order = new Order();

order.setPrice("998");

 

//2 客户关联订单

customer.getOrderSet().add(order);

//3 订单也关联客户

order.setCustomer(customer);

 

//4 保存客户

// * 1 save(order) -- insert  --> 1,998 null

// * 2 订单管理客户,此时null --预留update --> 更新所有(正常设置)

// * 3 save(customer) -- insert --> 1,成成

// * 4 客户关联订单  --> 预留update --> 更新订单外键 (维护外键)

// * 5 提交commit --> 执行2 和 4

session.save(order);

session.save(customer);

 

session.getTransaction().commit();

session.close();

}

 

l 在一对多开发中,一方一般都放弃对外键值的维护。及<set inverse="true

 

 

 

4.3 级联操作(读、理解)

4.3.1 save-update  级联保存或更新

 

 

 

@Test

public void demo032(){

// 32 创建客户和订单,客户关联订单,保存客户? --抛异常

// ** 解决方案2:级联操作--级联保存或更新

// ** Customer.hbm.xml <set cascade="save-update">

// ** 在保存客户的同时,一并保存订单

Session session = factory.openSession();

session.beginTransaction();

 

//1 客户和订单

Customer customer = new Customer(); //瞬时态

customer.setCname("成成");

 

Order order = new Order(); //瞬时态

order.setPrice("998");

 

//2 客户关联订单

customer.getOrderSet().add(order);

 

//3 保存客户

session.save(customer); //持久态

// 关联操作都是持久态的,此时 持久态Customer 引用 一个 瞬时态的Order 抛异常

 

session.getTransaction().commit();

session.close();

}

 

4.3.2 delete 级联删除

 

 

@Test

public void demo05(){

// 5 查询客户,并删除(持久态)

// 默认:当删除客户,默认将订单外键设置成null。

// 级联删除:删除客户时,并将客户的订单删除。

// ** Customer.hbm.xml <set name="orderSet" cascade="delete">

Session session = factory.openSession();

session.beginTransaction();

 

Customer customer = (Customer) session.get(Customer.class, 10);

 

session.delete(customer);

 

 

session.getTransaction().commit();

session.close();

}

 

4.3.3 孤儿删除

l 一对多关系,存在父子关系。1表(主表)可以成为父表,多表(从表)也可以子表。

 

 

 

总结:

主表不能删除,从表已经引用(关联)的数据

从表不能添加,主表不存在的数据。

 

 

 

@Test

public void demo06(){

// 6 查询客户,并查询订单,解除客户和订单订单的关系

// * 默认:客户和订单解除关系后,外键被设置成null,此时订单就是孤儿。客户和订单都存在。

// * 孤儿删除(孤子删除),当订单称为孤儿,一并删除。客户仍存在。

Session session = factory.openSession();

session.beginTransaction();

 

//1 查询客户

Customer customer = (Customer) session.get(Customer.class, 9);

 

//2查询订单

Order order = (Order) session.get(Order.class, 8);

 

//3 解除关系

customer.getOrderSet().remove(order);

 

session.getTransaction().commit();

session.close();

}

 

4.3.4 总结

save-update:A保存,同时保存B

delete:删除A,同时删除B,AB都不存在

delete-orphan:孤儿删除,解除关系,同时将B删除,A存在的。

如果需要配置多项,使用逗号分隔。<set cascade="save-update,delete">

 

all : save-update 和 delete 整合

all-delete-orphan : 三个整合

 

 

 

 

1.1.1 Hibernate的关联关系映射:(多对多)

1.1.1.1 多对多的配置:

步骤一创建实体和映射:

Student:

public class Student {

private Integer sid;

private String sname;

// 学生选择多门课程.

private Set<Course> courses = new HashSet<Course>();

...

}

 

Course:

public class Course {

private Integer cid;

private String cname;

// 课程可以被多个学生选择:

private Set<Student> students = new HashSet<Student>();

...

}

 

Student.hbm.xml

<hibernate-mapping>

<class name="cn.itcast.demo3.Student" table="student">

<id name="sid" column="sid">

<generator class="native"/>

</id>

<property name="sname" column="sname"/>

<!-- 配置多对多关联关系 -->

<set name="courses" table="stu_cour">

<key column="sno"/>

<many-to-many class="cn.itcast. demo3.Course" column="cno"/>

</set>

</class>

</hibernate-mapping>

 

Course.hbm.xml

<hibernate-mapping>

<class name="cn.itcast. demo3.Course" table="course">

<id name="cid" column="cid">

<generator class="native"/>

</id>

 

<property name="cname" column="cname"/>

 

<!-- 配置多对多关联关系映射 -->

<set name="students" table="stu_cour">

<key column="cno"/>

<many-to-many class="cn.itcast. demo3.Student" column="sno"/>

</set>

</class>

</hibernate-mapping>

2 抓取策略(优化)

2.1 检索方式

l 立即检索:立即查询,在执行查询语句时,立即查询所有的数据。

l 延迟检索:延迟查询,在执行查询语句之后,在需要时在查询。(懒加载)

 

2.2 检查策略

l 类级别检索:当前的类的属性获取是否需要延迟。

l 关联级别的检索:当前类 关联 另一个类是否需要延迟。

 

 

2.3 类级别检索

l get:立即检索。get方法一执行,立即查询所有字段的数据。

l load:延迟检索。默认情况,load方法执行后,如果只使用OID的值不进行查询,如果要使用其他属性值将查询 。 Customer.hbm.xml  <class  lazy="true | false">

lazy 默认值true,表示延迟检索,如果设置false表示立即检索。

 

 

 

@Test

public void demo02() {

//类级别

Session session = factory.openSession();

session.beginTransaction();

 

//1立即

// Customer customer = (Customer) session.get(Customer.class, 1);

//2延迟

Customer customer = (Customer) session.load(Customer.class, 1);

 

 

 

//打印

System.out.println(customer.getCid());

System.out.println(customer.getCname());

 

session.getTransaction().commit();

session.close();

}

 

 

 

2.4 关联级别检索

2.4.1 一对多或多对多

2.4.1.1 介绍

l 容器<set> 提供两个属性:fetch、lazy

fetch:确定使用sql格式

lazy:关联对象是否延迟。

l fetch:join、select、subselect

join:底层使用迫切左外连接

select:使用多个select语句(默认值)

subselect:使用子查询

l lazy:false、true、extra

false:立即

true:延迟(默认值)

extra:极其懒惰

 

 

 

2.4.1.2 fetch="join"

l fetch="join" ,lazy无效。底层使用迫切左外连接,使用一条select将所有内容全部查询。

 

 

@Test

public void demo03() {

//关联级别:一对多,

// * Customer.hbm.xml  <set fetch="join">

// *** select语句使用左外连接,一次性查询所有

Session session = factory.openSession();

session.beginTransaction();

 

//1 查询客户

Customer customer = (Customer) session.get(Customer.class, 1);

System.out.println(customer.getCname());

 

//2 查询客户订单数

Set<Order> orderSet = customer.getOrderSet();

System.out.println(orderSet.size());

 

//3 查询客户订单详情

for (Order order : orderSet) {

System.out.println(order);

}

 

 

session.getTransaction().commit();

session.close();

}

 

2.4.1.3 fetch="select"

l 当前对象 和 关联对象 使用多条select语句查询。

l lazy="false" , 立即,先查询客户select,立即查询订单select

l lazy="true",延迟,先查询客户select,需要订单时,再查询订单select

l lazy="extra",极其懒惰(延迟),先查询客户select, 如果只需要订单数,使用聚合函数(不查询详情)

 

 

 

 

 

 

 

 

2.4.1.4 fetch="subselect"

l 将使用子查询。注意:必须使用Query否则看不到效果。

l lazy= 同上

@Test

public void demo04() {

//关联级别:一对多,

// 演示3:* Customer.hbm.xml  <set fetch="subselect">

Session session = factory.openSession();

session.beginTransaction();

 

//1 查询客户

List<Customer> allCustomer = session.createQuery("from Customer").list();

Customer customer = allCustomer.get(0);

System.out.println(customer.getCname());

 

//2 查询客户订单数

Set<Order> orderSet = customer.getOrderSet();

System.out.println(orderSet.size());

 

//3 查询客户订单详情

for (Order order : orderSet) {

System.out.println(order);

}

 

 

session.getTransaction().commit();

session.close();

}

 

 

 

 

 

 

 

 

 

2.4.2 多对一

2.4.2.1 介绍

l <many-to-one fetch="" lazy="">  (<one-to-one>)

l fetch取值:join、select

join:底层使用迫切左外连接

select:多条select语句

l lazy取值:false、proxy、no-proxy

false:立即

proxy:采用关联对象 类级别检索的策略。

订单 关联 客户 (多对一)

订单 立即获得 客户,需要在客户Customer.hbm.xml <class lazy="false">

订单 延迟获得 客户,需要在客户Customer.hbm.xml <class lazy="true">

 

no-proxy 不研究

 

 

 

 

2.4.2.2 fetch="join"

l fecth="join" select语句使用左外连接,此时lazy无效。

 

 

 

 

@Test

public void demo05() {

//关联级别:多对一,

// 演示1:* Order.hbm.xml  <set fetch="join">  lazy无效

// * 注意:检查Customer.hbm.xml 和 Order.hbm.xml 没有额外的配置

Session session = factory.openSession();

session.beginTransaction();

 

//1 查询订单

Order order = (Order) session.get(Order.class, 1);

System.out.println(order.getPrice());

 

//2 查询订单客户信息

Customer customer = order.getCustomer();

System.out.println(customer.getCname());

 

 

session.getTransaction().commit();

session.close();

}

2.4.2.3 fetch="select"

l 将采用多条select语句,lazy="proxy"是否延迟,取决关联对象 类级别检索策略。

 

l lazy="false"

 

 

l lazy="proxy"

 

 

 

 

2.5 批量查询

l 当客户 关联查询 订单,给每一个客户生产一个select语句查询订单。批量查询使用in语句减少查询订单语句个数。

默认:select * from t_order where customer_id = ?

批量:select * from t_order where customer_id in (?,?,?,?)

l <set batch-size="5"> 5表示括号中?个数。

 

 

 

@Test

public void demo06() {

//批量查询

Session session = factory.openSession();

session.beginTransaction();

 

//1 查询所有客户

List<Customer> allCustomer = session.createQuery("from Customer").list();

 

//2遍历

for (Customer customer : allCustomer) {

System.out.println(customer.getCname());

System.out.println(customer.getOrderSet().size());

}

 

 

session.getTransaction().commit();

session.close();

}

2.6 检索总结

 

检索策略

优点

缺点

优先考虑使用的场合

立即检索

对应用程序完全透明,不管对象处于持久化状态还是游离状态,应用程序都可以从一个对象导航到关联的对象

(1)select语句多

(2)可能会加载应用程序不需要访问的对象,浪费许多内存空间。

(1)类级别

(2)应用程序需要立即访问的对象

(3)使用了二级缓存

延迟检索

由应用程序决定需要加载哪些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并节省内存空间。

应用程序如果希望访问游离状态的代理类实例,必须保证她在持久化状态时已经被初始化。

(1)一对多或者多对多关联

(2)应用程序不需要立即访问或者根本不会访问的对象

 

表连接检索

(1)对应用程序完全透明,不管对象处于持久化状态还是游离状态,都可从一个对象导航到另一个对象。

(2)使用了外连接,select语句少

(1)可能会加载应用程序不需要访问的对象,浪费内存。

(2)复杂的数据库表连接也会影响检索性能。

(1)多对一或一对一关联

(2)需要立即访问的对象

(3)数据库有良好的表连接性能。

 

Customer  Get(int id)

Return Session.load(Customer.class,id);

  1. layz=false
  2. 在Service层获得在页面要上要用到的属性=> 在Service层中确保数据已经

3 查询方式总结

1.通过OID检索(查询)

get()立即、如果没有数据返回null

load()延迟,如果没有数据抛异常。

2.导航对象图检索方式:关联查询

customer.getOrderSet()

user.getPost().getDepartment().getDepName();

3.原始sql语句

SQLQuery sqlQuery = session.createSQLQuery("sql 语句")   --->表,表字段(列)

sqlQuery.list() 查询所有

sqlQuery.uniqueResult() 查询一个

4.HQL,hibernate query language hibernate 查询语言【1】

Query query = session.createQuery("hql语句")  --> 对象,对象属性

5.QBC,query by criteria 纯面对对象查询语言【2】

 

4 HQL【掌握】

4.1 介绍

 

 

4.2 查询所有客户

@Test

public void demo01(){

//1 查询所有

Session session = factory.openSession();

session.beginTransaction();

 

//1  使用简单类名 , 存在自动导包

// * Customer.hbm.xml <hibernate-mapping auto-import="true">

// Query query = session.createQuery("from Customer");

//2 使用全限定类名

Query query = session.createQuery("from com.itheima.a_init.Customer");

 

List<Customer> allCustomer = query.list();

for (Customer customer : allCustomer) {

System.out.println(customer);

}

 

session.getTransaction().commit();

session.close();

}

 

4.3 选择查询

@Test

public void demo02(){

//2 简单条件查询

Session session = factory.openSession();

session.beginTransaction();

 

 

//1 指定数据,cid OID名称

// Query query = session.createQuery("from Customer where cid = 1");

//2 如果使用id,也可以(了解)

// Query query = session.createQuery("from Customer where id = 1");

//3 对象别名 ,格式: 类 [as] 别名

// Query query = session.createQuery("from Customer as c where c.cid = 1");

//4 查询所有项,mysql--> select * from...

Query query = session.createQuery("select c from Customer as c where c.cid = 1");

 

Customer customer = (Customer) query.uniqueResult();

System.out.println(customer);

 

session.getTransaction().commit();

session.close();

}

4.4 投影查询(部分)

@Test

public void demo04(){

//4 投影

Session session = factory.openSession();

session.beginTransaction();

 

//1 默认

//如果单列 ,select c.cname from,需要List<Object>

//如果多列,select c.cid,c.cname from ,需要List<Object[]>  ,list存放每行,Object[]多列

// Query query = session.createQuery("select c.cid,c.cname from Customer c");

//2 将查询部分数据,设置Customer对象中

// * 格式:new Customer(c.cid,c.cname)

// * 注意:Customer必须提供相应的构造方法。

// * 如果投影使用oid,结果脱管态对象。

Query query = session.createQuery("select new Customer(c.cid,c.cname) from Customer c");

 

List<Customer> allCustomer = query.list();

for (Customer customer : allCustomer) {

System.out.println(customer.getCid() + " : " + customer.getOrderSet().size());

}

 

session.getTransaction().commit();

session.close();

}

 

4.5 排序

@Test

public void demo03(){

//3排序 ,mysql--> select... order by 字段  [asc]|desc ,....

Session session = factory.openSession();

session.beginTransaction();

 

Query query = session.createQuery("from Customer order by cid desc");

 

List<Customer> allCustomer = query.list();

for (Customer customer : allCustomer) {

System.out.println(customer.getCid());

}

 

session.getTransaction().commit();

session.close();

}

 

 

4.6 分页

@Test

public void demo05(){

//分页

Session session = factory.openSession();

session.beginTransaction();

 

Query query = session.createQuery("from Customer");

// * 开始索引 , startIndex 算法: startIndex = (pageNum - 1) * pageSize;

// *** pageNum 当前页(之前的 pageCode)

query.setFirstResult(0);

// * 每页显示个数 , pageSize

query.setMaxResults(2);

 

List<Customer> allCustomer = query.list();

for (Customer customer : allCustomer) {

System.out.println(customer.getCid());

}

 

session.getTransaction().commit();

session.close();

}

 

4.7 绑定参数

@Test

public void demo06(){

/* 6 绑定参数

 * 方式1:占位符,使用? 在hql语句替换具体参数

 * 设置参数 query.setXxx(int , object)

 * 参数1:?位置,从0开始。

 * 参数2:实际参数

 * 例如:String --> query.setString(int,String)

 * 方式2:别名 , 格式 “属性= :别名 ”

 * 设置参数 query.setXxx(String,object)

 * 参数1:别名

 * 参数2:实际参数

 * 例如:Integer --> query.setInteger(String,Integer)

 * 提供公共设置方法

 * setParameter(int|string , Object)

 */

Session session = factory.openSession();

session.beginTransaction();

 

Integer cid = 1;

 

//方式1

// Query query = session.createQuery("from Customer where cid = ?");

// query.setInteger(0, cid);

//方式2

Query query = session.createQuery("from Customer where cid = :xxx");

// query.setInteger("xxx", cid);

query.setParameter("xxx", cid);

 

Customer customer = (Customer) query.uniqueResult();

System.out.println(customer);

 

session.getTransaction().commit();

session.close();

}

 

4.8 聚合函数和分组

@Test

public void demo07(){

/* 7  聚合函数

 */

Session session = factory.openSession();

session.beginTransaction();

 

//1

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

//2 别名

// Query query = session.createQuery("select count(c) from Customer c");

//3 oid

Query query = session.createQuery("select count(cid) from Customer");

 

Long numLong = (Long) query.uniqueResult();

int num = numLong.intValue();

 

System.out.println(num);

 

 

session.getTransaction().commit();

session.close();

}

 

4.9 连接查询

 

 

1.交叉连接 ,等效 sql 笛卡尔积

2.隐式内连接,等效 sql 隐式内连接

3.内连接,等效sql内连接

4.迫切内连接,hibernate底层使用 内连接。

5.左外连接,等效sql左外连接

6.迫切左外连接,hibernate底层使用 左外连接

7.右外连接,等效sql右外连接

 

内连接和迫切内连接?

左外连接和迫切左外连接?

@Test

public void demo08(){

/* 8 链接查询 : 左外连接和迫切左外连接?

 * * 左外连接 , left outer join

 * 底层使用sql的左外连接,hibernate进行数据自动封装,将一条记录,封装给两个对象(Customer,Order)

 * 将两个对象添加到一个对象数组中Object[Customer,Order]

 * * 迫切左外链接 left outer join fetch

 * 底层使用sql的左外连接,hibernate将一条记录封装给Customer,讲order数据封装Order,并将order关联到Customer

 * customer.getOrderSet().add(order)

 * 默认查询的数据重复

 */

Session session = factory.openSession();

session.beginTransaction();

 

//左外连接

// List list = session.createQuery("from Customer c left outer join c.orderSet ").list();

//迫切左外链接 (默认数据重复)

// List list = session.createQuery("from Customer c left outer join fetch c.orderSet ").list();

//迫切左外链接 (去重复)

List list = session.createQuery("select distinct c from Customer c left outer join fetch c.orderSet ").list();

 

 

session.getTransaction().commit();

session.close();

}

 

4.10 命名查询

l 思想:将HQL从java源码中,提取到配置文件中。

l 分类:全局、布局

l 配置

全局:*.hbm.xml   <class></class><query name="名称">HQL语句

 

 

局部: <class name="" table=""><id><property> <query name="">HQL</class>

 

 

l 获得

全局:

session.getNamedQuery("queryName")

局部:

session.getNamedQuery("className.queryName")  需要使用类的全限定名称

 

 

 

@Test

public void demo09(){

/* 9 命名查询

 */

Session session = factory.openSession();

session.beginTransaction();

 

//全局

//List list = session.getNamedQuery("findAll").list();

//局部

List list = session.getNamedQuery("com.itheima.a_init.Customer.findAll").list();

 

System.out.println(list.size());

 

session.getTransaction().commit();

session.close();

}

 

 

5 QBC【了解】

 

5.0.0.1 QBC查询:

QBC:Query By Criteria条件查询.面向对象的查询的方式.

5.0.0.2 QBC简单的查询:

// 简单查询:

List<Customer> list = session.createCriteria(Customer.class).list();

for (Customer customer : list) {

System.out.println(customer);

}

5.0.0.3 QBC分页的查询:

Criteria criteria = session.createCriteria(Order.class);

criteria.setFirstResult(10);

criteria.setMaxResults(10);

List<Order> list = criteria.list();

5.0.0.4 QBC排序查询:

Criteria criteria = session.createCriteria(Customer.class);

// criteria.addOrder(org.hibernate.criterion.Order.asc("age"));

criteria.addOrder(org.hibernate.criterion.Order.desc("age"));

List<Customer> list = criteria.list();

5.0.0.5 QBC条件查询:

// 按名称查询:

/*Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.eq("cname", "tom"));

List<Customer> list = criteria.list();*/

 

// 模糊查询;

/*Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.like("cname", "t%"));

List<Customer> list = criteria.list();*/

 

// 条件并列查询

Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.like("cname", "t%"));

criteria.add(Restrictions.ge("age", 35));

List<Customer> list = criteria.list();

 

 

5.0.0.6 离线查询(了解)

l DetachedCriteria 离线查询对象,不需要使用Session就可以拼凑查询条件。一般使用在web层或service层拼凑。将此对象传递给dao层,此时将与session进行绑定执行查询。

l 离线查询条件与QBC一样的。

 

 

 

@Test

public void demo10(){

/* 10 离线查询

 */

 

//web & service

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);

detachedCriteria.add(Restrictions.eq("cid", 1));

 

//---------------dao

 

Session session = factory.openSession();

session.beginTransaction();

 

// 离线Criteria 与session绑定

Criteria criteria = detachedCriteria.getExecutableCriteria(session);

List<Customer> allCustomer = criteria.list();

System.out.println(allCustomer.size());

 

session.getTransaction().commit();

session.close();

}

 

 

 

 

6 常见配置

6.1 整合c3p0(连接池) (了解)

l 整合c3p0

 

 

步骤一:导入c3p0 jar包

 

 

步骤二:hibernate.cfg.xml 配置

hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider

 

 

l c3p0具体配置参数

###########################

### C3P0 Connection Pool###

###########################

 

#hibernate.c3p0.max_size 2

#hibernate.c3p0.min_size 2

#hibernate.c3p0.timeout 5000

#hibernate.c3p0.max_statements 100

#hibernate.c3p0.idle_test_period 3000

#hibernate.c3p0.acquire_increment 2

#hibernate.c3p0.validate false

 

6.2 事务

6.2.1 回顾

l 事务:一组业务操作,要么全部成功,要么全部不成功。

l 特性:ACID

原子性:整体

一致性:数据

隔离性:并发

持久性:结果

l 隔离问题:

脏读:一个事务读到另一个事务未提交的内容

不可重复读:一个事务读到另一个事务已提交的内容(insert)

虚读(幻读):一个事务读到另一个事务已提交的内容(update)

l 隔离级别--解决问题

read uncommittd,读未提交。存在3个问题。

read committed,读已提交。解决:脏读。存在2个问题。

repeatable read ,可重复读。解决:脏读、不可重复读。存在1个问题。

serializable,串行化。单事务。没有问题。

 

 

 

6.2.2 hibernate设置隔离级别

l 在hibernate.cfg.xml 配置

hibernate.connection.isolation 4

 

 

 

6.2.3 lost update 丢失更新

 

 

l 悲观锁:丢失更新肯定会发生。

采用数据库锁机制。

读锁:共享锁。

select .... from  ... lock in share mode;

写锁:排他锁。(独占)

select ... from  ....  for update

 

 

 

l 乐观锁:丢失更新肯定不会发生

在表中提供一个字段(版本字段),用于标识记录。如果版本不一致,不允许操作。

 

 

 

6.2.4 hibernate处理丢失更新

l 悲观锁:写锁

 

 

@Test

public void demo01(){

//1 查询所有

Session session = factory.openSession();

session.beginTransaction();

 

Customer customer = (Customer) session.get(Customer.class, 1 ,LockMode.UPGRADE);

System.out.println(customer);

 

session.getTransaction().commit();

session.close();

}

 

 

 

 

l 乐观锁:

在PO对象(javabean)提供字段,表示版本字段。一般Integer

在*.hbm.xml 文件配置 <version name="...">

 

步骤一:

 

 

步骤二:

 

 

 

步骤三:测试

@Test

public void demo02(){

//1 查询所有

Session session = factory.openSession();

session.beginTransaction();

 

// Order order = new Order();

// order.setPrice(998d);

// session.save(order);

 

Order order = (Order) session.get(Order.class, 32);

order.setPrice(889d);

 

 

session.getTransaction().commit();

session.close();

}

 

 

1 整合log4j(了解)

l slf4j 核心jar  : slf4j-api-1.6.1.jar 。slf4j是日志框架,将其他优秀的日志第三方进行整合。

 

 

l 整合导入jar包

log4j 核心包:log4j-1.2.17.jar

过渡jar(整合jar):slf4j-log4j12-1.7.5.jar

l 导入配置文件

log4j.properties  ,此配置文件通知log4j 如何输出日志

 

l 配置文件内容:

1.记录器

2.输出源

3.布局

l 记录器

例如: log4j.rootLogger=info, stdout,file

格式:log4j.rootLogger=日志级别, 输出源1,输出源2,。。。。

log4j 日志级别 : fatal 致命错误 error 错误 warn 警告 info 信息 debug 调试信息 trace 堆栈信息 (由高到底顺序)

l 输出源:

例如:log4j.appender.file=org.apache.log4j.FileAppender

格式:log4j.appender.输出源的名称=输出源的实现类

名称:自定义

实现类:log4j提供

 

输出源属性例如:log4j.appender.file.File=d\:mylog.log

输出源属性格式:log4j.appender.名称.属性=值

每一个输出源对应一个实现类,实现类都属性(setter),底层执行setter方法进行赋值

 

l 常见的输出源实现类

org.apache.log4j.FileAppender  输出文件中

file ,表示文件输出位置

org.apache.log4j.ConsoleAppender 输出到控制台

Target ,表示使用哪种输出方式,在控制台打印内容,取值:System.out / System.err

l 布局  -- 确定输出格式

例如:log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

格式:log4j.appender.数据源.layout=org.apache.log4j.PatternLayout

布局属性:log4j.appender. 数据源.layout.ConversionPattern=值

12:56:30,123  info

 

l 扩展:对指定的目录设置日志级别

例如:log4j.logger.org.hibernate.transaction=debug

格式:log4j.logger.包结构=级别

2 一对一(了解)

l 情况1:主表的主键,与从表的外键(唯一),形成主外键关系

l 情况2:主表的主键,与从表的主键,形成主外键关系 (从表的主键又是外键)

 

2.1.1 情况1

 

 

 

 

 

2.1.2 情况2

 

 

 

 

 

 

3 二级缓存【掌握】

3.1 介绍

3.1.1 缓存

缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写硬盘(永久性数据存储源)的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存

缓存:程序<--(内存)-->硬盘

 

3.1.2 什么是二级缓存

 

l hibernate 提供缓存机制:一级缓存、二级缓存

一级缓存:session级别缓存,在一次请求中共享数据。

二级缓存:sessionFactory级别缓存,整个应用程序共享一个会话工厂,共享一个二级缓存。

l SessionFactory的缓存两部分: 内置缓存:使用一个Map,用于存放配置信息,预定义HQL语句等,提供给Hibernate框架自己使用,对外只读的。不能操作。

外置缓存:使用另一个Map,用于存放用户自定义数据。默认不开启。外置缓存hibernate只提供规范(接口),需要第三方实现类。外置缓存有成为二级缓存。

 

 

3.1.3 二级缓存内部结构

 

 

l 二级就是由4部分构成

n 类级别缓存

n 集合级别缓存

n 时间戳缓存

n 查询缓存(二级缓存的第2大部分,三级缓存)

3.1.4 并发访问策略

 

 

l 访问策略:读写型(read-write)、只读型(read-only)

 

3.1.5 应用场景

l 适合放入二级缓存中的数据:

很少被修改

不是很重要的数据, 允许出现偶尔的并发问题

l 不适合放入二级缓存中的数据:

经常被修改

财务数据, 绝对不允许出现并发问题

与其他应用数据共享的数据

3.1.6 二级缓存提供商

l EHCache: 可作为进程(单机)范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 对 Hibernate 的查询缓存提供了支持。--支持集群。

l OpenSymphony `:可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持

l SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存

l JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存

 

 

X表示支持

 

 

 

 

3.2 配置(操作)

1.导入jar包:ehcache-1.5.0.jar/ commons-logging.jar/ backport-util-concurrent.jar

2.开启二级缓存(我要使用二级缓存)

3.确定二级缓存提供商(我要使用哪个二级缓存)

4.确定需要缓存内容

1>配置需要缓存的类

2>配置需要缓存的集合

5.配置ehcache自定义配置文件

 

 

3.2.1 导入jar包

 

 

 

3.2.2 开启二级缓存

 

 

l 在hibernate.cfg.xml 配置二级缓存

<!-- 9.1 开启二级缓存 -->

<property name="hibernate.cache.use_second_level_cache">true</property>

 

3.2.3 确定提供商

 

 

l hibernate.cfg.xml 配置

<!-- 9.2 提供商 -->

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

 

 

3.2.4 确定缓存内容

l 在hibernate.cfg.xml 确定 类缓存 和集合缓存配置项

 

 

l 配置

<!-- 9.3 确定缓存内容 -->

<!-- 类缓存 -->

<class-cache usage="read-write" class="com.itheima.a_init.Customer"/>

<class-cache usage="read-write" class="com.itheima.a_init.Order"/>

<!-- 集合缓存 -->

<collection-cache usage="read-write" collection="com.itheima.a_init.Customer.orderSet"/>

 

3.2.5 ehcache配置文件

步骤1:从jar包复制xml文件

 

 

步骤2:将xml重命名“ehcache.xml”

 

 

步骤3:将修改后的xml,拷贝到src下

 

 

 

3.3 演示

3.3.1 证明

@Test

public void demo01(){

//1 证明二级缓存存在

// * 修改toString()

// * 如果二级缓存开启,查询3 没有select语句,表示从二级缓存获得的。

// * 将二级缓存关闭,查询3将触发select语句。

Session s1 = factory.openSession();

s1.beginTransaction();

 

//1 查询id=1 -- 执行select (查询后,将数据存放在一级缓存,之后由一级缓存同步到二级缓存)

Customer c1 = (Customer) s1.get(Customer.class, 1);

System.out.println(c1);

//2 查询id=1 --从一级缓存获取

Customer c2 = (Customer) s1.get(Customer.class, 1);

System.out.println(c2);

 

s1.getTransaction().commit();

s1.close();

 

System.out.println("----------");

 

Session s2 = factory.openSession();

s2.beginTransaction();

 

//3 查询id=1 -- 从二级缓存获取

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

 

s2.getTransaction().commit();

s2.close();

}

 

3.3.2 类缓存

l 类缓存:只存放数据

l 一级缓存:存放对象本身

 

 

@Test

public void demo02(){

//2 类缓存:只存放数据,散装数据。

// * 使用默认的toString();

Session s1 = factory.openSession();

s1.beginTransaction();

 

//1 查询id=1 -- 执行select

Customer c1 = (Customer) s1.get(Customer.class, 1);

System.out.println(c1);

//2 查询id=1 -- 从一级缓存获取,一级缓存存放对象本身

Customer c2 = (Customer) s1.get(Customer.class, 1);

System.out.println(c2);

 

s1.getTransaction().commit();

s1.close();

 

System.out.println("----------");

 

Session s2 = factory.openSession();

s2.beginTransaction();

 

//3 查询id=1 -- 对象不一样,数据一样

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

 

s2.getTransaction().commit();

s2.close();

}

 

3.3.3 集合缓存

 

 

 

 

@Test

public void demo03(){

//3 集合缓存:只存放关联对象OID的值,如果需要数据,从类缓存中获取。

// * 3.1 默认:第一条select 查询客户,第二天 select 查询客户所有订单

// * 3.2 操作:在hibernate.cfg.xml 将 Order 类缓存删除

// *** <!--  <class-cache usage="read-write" class="com.itheima.a_init.Order"/>-->

// *** 多了10条select,通过订单的id查询订单

Session s1 = factory.openSession();

s1.beginTransaction();

 

//1 查询id=1

Customer c1 = (Customer) s1.get(Customer.class, 1);

System.out.println(c1);

//2 获得订单

for (Order o1 : c1.getOrderSet()) {

System.out.println(o1);

}

 

 

s1.getTransaction().commit();

s1.close();

 

System.out.println("----------");

 

Session s2 = factory.openSession();

s2.beginTransaction();

 

//3 查询id=1

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

//4 获得订单

for (Order o2 : c3.getOrderSet()) {

System.out.println(o2);

}

 

s2.getTransaction().commit();

s2.close();

}

 

3.3.4 时间戳

l 时间戳:任何操作都在时间戳中记录操作时间。

 

 

 

@Test

public void demo04(){

//4 时间戳: 所有的操作都会在时间戳中进行记录,如果数据不一致,将触发select语句进行查询

// * 修改toString()

Session s1 = factory.openSession();

s1.beginTransaction();

 

//1 查询id=1

Integer cid = 1;

Customer c1 = (Customer) s1.get(Customer.class, cid);

System.out.println(c1);

//2 绕过一级和二级缓存,修改数据库,修改客户cname=大东哥

s1.createQuery("update Customer set cname = ? where cid = ?")

.setString(0, "大东哥")

.setInteger(1, cid)

.executeUpdate();

//3打印

System.out.println(c1);

 

s1.getTransaction().commit();

s1.close();

 

System.out.println("----------");

 

Session s2 = factory.openSession();

s2.beginTransaction();

 

//4 查询id=1  -- ?

Customer c3 = (Customer) s2.get(Customer.class, 1);

System.out.println(c3);

 

s2.getTransaction().commit();

s2.close();

}

3.3.5 查询缓存

l 查询缓存又称为三级缓存(民间)

l 查询缓存默认不使用。需要手动开启

l 查询缓存:将HQL语句与 查询结果进行绑定。通过HQL相同语句可以缓存内容。

默认情况Query对象只将查询结果存放在一级和二级缓存,不从一级或二级缓存获取。

查询缓存就是让Query可以从二级缓存获得内容。

 

步骤一:开启查询缓存

 

 

<!-- 9.4 开启查询缓存 -->

<property name="hibernate.cache.use_query_cache">true</property>

 

步骤二:在查询query对象,设置缓存内容(注意:存放和查询 都需要设置)

 

 

 

 

 

 

@Test

public void demo05(){

//5 查询缓存

Session s1 = factory.openSession();

s1.beginTransaction();

 

//1 query查询

Query q1 = s1.createQuery("from Customer");

q1.setCacheable(true);

List<Customer> a1 = q1.list();

for (Customer c1 : a1) {

System.out.println(c1);

}

 

//2 cid =1  -- 一级缓存获得

Customer customer = (Customer) s1.get(Customer.class, 1);

System.out.println(customer);

 

s1.getTransaction().commit();

s1.close();

 

System.out.println("----------");

 

Session s2 = factory.openSession();

s2.beginTransaction();

 

//2 cid =1  -- 二级缓存获得

Customer customer2 = (Customer) s2.get(Customer.class, 1);

System.out.println(customer2);

 

//3 query查询

Query q2 = s2.createQuery("from Customer");

q2.setCacheable(true);

List<Customer> a2 = q2.list();

for (Customer c2 : a2) {

System.out.println(c2);

}

 

s2.getTransaction().commit();

s2.close();

}

 

 

3.4 ehcache配置文件

l <diskStore path="java.io.tmpdir"/>  设置临时文件存放位置。(缓存一般内存,一定程度时,写入硬盘。)

 

l 缓存详细设置

<defaultCache> 所有的缓存对象默认的配置

<cache name="类"> 指定对象单独配置

l 参数设置

maxElementsInMemory="10000"  内存最大数

eternal="false"  是否永久(内存常驻留)

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"  内存满了,是否写入到硬盘

maxElementsOnDisk="10000000"  硬盘最大数

diskPersistent="false"  关闭JVM,是否将内存保存硬盘中

diskExpiryThreadIntervalSeconds="120"  轮询

memoryStoreEvictionPolicy="LRU"

Least Recently Used (specified as LRU).

First In First Out (specified as FIFO)

Less Frequently Used (specified as LFU)

  • maxElementsInMemory :设置基于内存的缓存中可存放的对象最大数目
  • eternal:设置对象是否为永久的,true表示永不过期,此时将忽略timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false
  • timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态。
  • timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。
    如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值
  • overflowToDisk:设置基于内在的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中
  • diskPersistent 当jvm结束时是否持久化对象 true false 默认是false
  • diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间
  •  memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出) 

 

高通 Wi-Fi 驱动实录:MHI 协议中 Host 私有的数据结构 它那 16 字节的身体里,不仅装下了硬件返回的完成码(code)、传输长度(len),还装下了通道号(chid)和回指指针(ptr)。硬中断响应(mhi_irq_handler):需要特别注意的是,er_ctxt.msivec 和 mhi_event.irq 存储的是 MSI 向量索引(如 0, 1, 2...),而不是真正的 Linux IRQ 号!在它的内部,整段内嵌了两个 struct mhi_ring 实例:一个是处理硬件交互的 tre_ring,另一个则是默默在幕后记账的 buf_ring。 阅读详情

相关推荐

【STM32CubeIDE入门】(一)工程创建&工程配置

​写在前面:如果是刚接触stm32cubeide的同学推荐与这一篇文章共同阅读,能够更加快速认识上手stm32cubeide。 1、打开stm32cubeide,选择好工作目录进入主界面后,点击创建工程。

涛涛子的博客 1万+

ORM框架Hibernate框架的使用以及搭建方式

持久层ORM框架Hibernate框架的使用以及搭建方式 前言 hibernate的概念: hibernate是一个ormapping框架(ORM框架,全自动ORM框架) hibernate是一个数据库的操作框架即持久层框架 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库(SQL语句由Hibernate根据对象自动生成)。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户

zhx__的博客 6085

手把手复现金蝶云星空V8.1文件上传漏洞(附完整POC与修复方案)

本文深度解析金蝶云星空V8.1文件上传漏洞,提供详细的漏洞复现步骤与完整POC,涵盖技术原理、测试环境搭建及验证流程。同时给出多维防护方案,包括官方补丁部署、临时缓解措施和长期安全加固建议,帮助企业有效防范任意文件上传风险。

weixin_30505225的博客 184

hibernate之ORM介绍

Hibernate框架的概述 Hibernate是一个开源diamante的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级的对象封装,使得java程序员可以随心所欲的使用对象编程思维来操纵数据库 Hibernate可以应用在任何使用JDBC的场合,既可以在java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。 Hibernate是轻量级Java...

u011301372的博客 1630

BIDS数据存储格式介绍与dcm2bids安装与使用

BIDS格式&dcm2bids安装与使用

machinelearning_er的博客 7320

基于EKF的UWB-IMU融合定位系统在农业机器人中的抗干扰优化与Matlab仿真

本文探讨了基于扩展卡尔曼滤波(EKF)的UWB-IMU传感器融合定位系统在农业机器人中的应用。通过Matlab仿真验证,该系统有效解决了农业环境中UWB信号遮挡和IMU累积误差问题,实现了厘米级高精度定位,显著提升了机器人在复杂场景下的抗干扰能力和导航可靠性。

numpy6sculptor的博客 625

Java必知必会系列:ORM框架与Hibernate

1.背景介绍 在现代软件开发中,数据库操作是非常重要的一部分。随着数据库技术的不断发展,各种数据库操作的框架也不断出现。这篇文章将介绍一种非常重要的数据库操作框架——ORM框架(Object-Relational Mapping,对象关系映射),以及其中的一种实现——Hibernate。 ORM框架是一种将对象与关系数据库进行映射的技术,

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 353

Day470&471.Netty概述&Netty高性能架构设计 -netty

Netty概述 一、原生 NIO 存在的问题 NIO 的类库和 API 繁杂,使用麻烦:需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。 需要具备其他的额外技能:要熟悉 Java 多线程编程,因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网络编程非常熟悉,才能编写出高质量的 NIO 程序。 开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常流的处理等等。 JDK NIO

阿昌爱Java 1574

Hibernate,大部分开发者的第一个ORM框架?

本文介绍了ORM(对象关系映射)技术及其在Java中的实现框架Hibernate。ORM通过将数据库表映射为类、行映射为对象、字段映射为属性,简化了数据库操作。Hibernate作为Java中常见的ORM框架,封装了JDBC,使开发者无需直接编写SQL语句,而是通过操作Java对象间接操作数据库。文章详细讲解了如何在IDEA中使用Hibernate进行数据库的增删改查(CRUD)操作,并比较了Hibernate与JDBC的关系,指出Hibernate在JDBC上层封装,提供了更高级的数据库操作方式。最后,文

733

游戏大厂射击游戏无缝大世界游戏DS服务器架构设计方案详解

摘要: 本文深入解析游戏大厂无缝大世界射击游戏的分布式服务器(DS)架构设计方案。以《和平精英》《量子特攻》为例,阐述如何通过动态分区、兴趣管理、弹性扩缩等核心技术应对高并发、低延迟、无缝切换等挑战。架构分为世界协调层、分区计算层、物理判定层等模块,结合微服务化、快照同步和Kubernetes调度,实现玩家跨区无感知迁移与一致判定。重点优化动态负载均衡、状态同步算法及容灾备份,依托分布式数据库与多云部署保障高可用性,为同类游戏提供可扩展的技术范本。(149字) 关键词: 无缝大世界、分布式服务器、动态分区、

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 564

电磁兼容(EMC):一文读懂过电应力(EOS)

过电应力(EOS)是指元器件承受的电流或电压应力超过其允许的最大范围。产品的电磁兼容(EMC)失效的一种常见模型为过电应力(EOS),也是电子产品失效的最常见的情况之一。过电应力基本与半导体器件相关,EOS事件包括有:静电放电(ESD)、雷击、系统瞬态、电磁脉冲、充电等。本文将详细讨论一下产品设计中如何关注EOS设计。

linkking27的博客 6486

Hibernate第一篇【介绍Hibernate,简述ORM,快速入门】

前言 前面已经学过了Struts2框架了,紧接着就是学习Hibernate框架了…本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门 什么是Hibernate框架? Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取Java对象! 为什...

3y 435

被搜狗输入法背刺了!偷偷装的 “AI 汪仔” 狂占 CPU!手把手教你如何彻底关闭删除搜狗AI功能AI汪仔

手把手教你如何彻底关闭删除搜狗输入法的AI汪仔🚀

XiaoqiangClub的博客 2万+

hibernate进阶(一)—ORM、JPA、Hibernate

一、ORM  起源     如今面向对象编程已经称为企业级开发中主流开发方法,而关系型数据库也也成为企业应用环境中永久存数据的主流存储系统。面向对象是从软件工程基本原则(如耦合、聚合、封装)基础上发展而来,而关系型数据库是从数学理论发展而来。那怎样将编程中的对象存储在关系型数据库呢?

遇见更好的自己 1360

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ORM框架——Hibernate

ORM(Object-Relationship Mapping):对象-关系映射 ORM框架技术:Hibernate、MyBatis 使用JBoss突出的Eclipse综合开发工具插件Hibernate Tools简化开发工作 ============================使用Hibernate创建一个工厂========================== 创建

Paige's Blog 383

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ORM 思想及Hibernate实现

ORM 思想目前,通过 Java 语言连接并操作数据库的技术或方式已经有很多了,例如:JDBC, Hibernate,MyBatis,TopLink 等等。其中 JDBC 是 Java 原生的 API,支持连接并操作各种关系 型数据库。相信每个程序员都是从 JDBC 开始学起的,然后才接触到各种持久层框架。 JDBC 作为...

qq_35485206的博客 961

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

初学Hibernate 写orm demo

一、Hibernate简介Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servl...

Lemon__的博客 301

结合Hibernate,理解ORM

1. 绪言 关系型数据库(RDB)通过实体之间的关系连接数据,而面向对象编程(OOP)把现实生活中的实体抽象成对象。 其实,RDB中的实体也可以使用对象进行表达,这样就能使用OOP来操作RDB。 比如,对象的save()方法,对应RDB的insert语句;对象的update()方法对应RDB的update语句。 以上思想或技术被叫做ORM(Object/Relational Mapping,对象/关系映射): 通过实例对象的语法,完成关系型数据库的操作的技术 在ORM中,对象与数据库的关系如下:

lucyLee的博客 471

hibernate_和ORM的关系

Hibernate是轻量级的JavaEE应用的持久层框架,Hibernate不仅管理Java类到数据表的映射,还提供数据查询和获取数据的方法,可大幅度缩短处理数据持久化的时间。1. ORM和Hibernate的关系 ORM的全称是:Object/Relation Mapping,即对象/关系数据库映射。ORM可理解成一种规范,它概述了这类框架的基本特征,完成面向对象的变成语言到数据库的映射。ORM...

子龙修仙的博客 2603

Hibernate之ORM

Hibernate之ORM简介: hibernate是一个采用ORM(Object/Relation Mapping对象关系映射)机制持久层的开源框架,其主要核心思想是面向对象,而非面向过程,而这个面向对象则主要通过ORM实现。 实现方式 注解和xml配置 常用注解 @Entity //第一步:变成实体 表示标识映射到数据库中的类 @Id //第二步:主键 @Gen

a3060858469的博客 546

ORM 和 Hibernate

一. Hibernate的简要介绍          Hibernate是轻量级Java EE应用的持久层解决方案,Hibernate不仅管理者Java类到数据库表的映射(包括Java 数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度的缩短使用JDBC处理数据持久化的时间。         目前的主流的数据库依然是关系型数据库,而Java语言是面向对象的编程语言,当

菜鸟JAVA 592

Hibernate ORM 概览

Hibernate ORM(对象关系映射)是一个用于 Java 应用程序的持久层框架。它提供了一种将 Java 对象映射到关系型数据库中的方式,从而简化了数据库访问和管理。

qq_33240556的博客 1065

JPA与ORM以及Hibernate

有没有办法让程序员彻底抛弃书写SQL思想,完全的使用面向对象思想开发软件呢? 需要一种可行的ORM框架。 什么是ORM? 不同的数据库使用的SQL语法不同,比如PL/SQL(Oracle)和T/SQL(SQL SERVER); 同样的功能不同的数据库有不同的实现方式; 程序过分依赖SQL对程序的移植性及扩展维护等带来很大的麻烦。 ORM框架包括Entity EJB、Hibernate、

csdn_main的博客 2161

Hibernate框架ORM的实现原理

Hibernate框架ORM的实现原理2007-08-24 来自:梁建全  [收藏到我的网摘]梁建全: 东方标准国际软件专业讲师,曾经负责过的重大的大型项目包括:全军武器装备质量管理系统、全军办公自动化系统、日本NTT电信管理系统等。主要著作包括《ASP.NET开发答疑200问》《ASP.NET开发实例导航》等。毕业于北京大学计算机专业。1. 什么是ORM ORM的全称是Obj

dongliheng的专栏 5131

MyBatis 与 Hibernate 等 ORM 框架的区别?

MyBatis 更像是一个“SQL Mapper”,它提供了对 SQL 的精细控制,适合复杂的、性能敏感的场景;Hibernate 更像是一个“全自动 ORM”,它强调对象与数据库的自动映射,适合简单的、快速开发的场景。选择哪种框架取决于项目的具体需求、团队的技术栈以及开发者的偏好。MyBatis 和 Hibernate 都是流行的 Java ORM(Object-Relational Mapping,对象关系映射)框架,但它们在设计理念、使用方式和适用场景上存在显著的区别。

专注于技术分享 1171
上一篇: Java Struts2 (三)
下一篇: Spring 框架(一)
github_39294367
博客等级 码龄9年 33粉丝 156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值