当前位置: 首页 > news >正文

JPA 之 Hibernate EntityManager 使用指南

Hibernate EntityManager 专题

参考:

  • JPA – EntityManager常用API详解
  • EntityManager基本概念

基本概念及获得 EntityManager 对象

基本概念

在使用持久化工具的时候,一般都有一个对象来操作数据库,在原生的Hibernate中叫做Session,在 JPA 中叫做EntityManager,在MyBatis中叫做SqlSession,通过这个对象来操作数据库。

EntityManager是 JPA 中用于增删改查的接口,连接内存中的 java 对象和数据库的数据存储。Hibernate EntityManager是围绕提供JPA编程接口实现的Hibernate Core的一个包装,支持JPA实体实例的生命周期,并允许用标准的Java Persistence查询语言编写查询。

EntityManager称为实体管理器,它由EntityManagerFactory所创建。EntityManagerFactory,作为EntityManager的工厂,包含有当前O-R映射的元数据信息,每个EntityManagerFactory,可称为一个持久化单元(PersistenceUnit),每个持久化单元可认为是一个数据源的映射(所谓数据源,可理解为一个数据库,可以在应用服务器中配置多个数据源,同时使用不同的PersistenceUnit来映射这些数据源,从而能够很方便的实现跨越多个数据库之间的事务操作!)

PersistenceContext,称为持久化上下文,它一般包含有当前事务范围内的,被管理的实体对象(Entity)的数据。每个EntityManager,都会跟一个PersistenceContext相关联。PersistenceContext中存储的是实体对象的数据,而关系数据库中存储的是记录,EntityManager正是维护这种OR映射的中间者,它可以把数据从数据库中加载到PersistenceContext中,也可以把数据从PersistenceContext中持久化到数据库,EntityManager通过Persist、merge、remove、refresh、flush等操作来操纵PersistenceContext与数据库数据之间的同步!

EntityManager是应用程序操纵持久化数据的接口。它的作用与hibernate session类似。为了能够在一个请求周期中使用同一个session对象,在hibernate的解决方案中,提出了currentSession的概念,hibernate中的current session,可以跟JTA事务绑定,也可以跟当前线程绑定。在hibernate中,session管理着所有的持久化对象的数据。而在EJB3中,EntityManager管理着PersistenceContext,PersistenceContext正是被管理的持久化对象的集合。

在 Java EE 环境下,一个 JTA 事务通常会横跨多个组件的调用(比如多个 EJB 组件的方法调用)。这些组件需要能够在单个事务范围内访问到同样的PersistenceContext。为了满足这种情况的需要,当EntityManager被注入或通过 JNDI 被查询的时候,它的 PersistenceContext 将会在当前事务范围内自动传播,引用到同一个 Persistence unit 的EntityManager将使用同样的 PersistenceContext。这可以避免在不同的组件之间传递EntityManager引用。

通过容器来传递PersistenceContext,而不是应用程序自己来传递EntityManager。这种方式(由容器管理着PersistenceContext,并负责传递到不同的EntityManager)称为容器管理的实体管理器(Container-Managed EntityManager),它的生命周期由容器负责管理,编程人员不需要考虑EntityManger的连接,释放以及复杂的事务问题等。

有一种不常见的情况是,应用程序自身需要独立访问PersistenceContext。即每次创建一个EntityManager都会迫使创建一个新的PersistenceContext。这些PersistenceContext即使在同一个事务范围内也不会跟其它EntityManager共享!这个创建过程可以由EntityManagerFactory的createEntityManager方法来创建。这被称为应用管理的实体管理器(application-managed entity manager)。

获得EntityManager对象

常用方式:SpringBoot容器托管对象方式:

依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

对象注入:

@Autowired
private EntityManager entityManager;

实体状态和转换

在这里插入图片描述


实体状态详解:

  • 临时状态

    实际上就是new了一个普通的 JavaBean 对象。

  • 托管状态

    临时状态在调用 persist() 后,即可将一般的 JavaBean 做为了托管状态的Bean,该Bean的任何属性改动都会牵涉到数据库记录的改动。

    一旦该记录flush到数据库之后,并且事务提交了,那么此对象不在持久化上下文中,即:变为了游离(没人管的孩子)状态了。

    在游离状态的时候调用更新、刷新方法后,游离状态对象就变为了在持久化上下文的托管状态了。

    通过管理器的find方法,将实体从数据库查询出来后,该实体也就变为了托管形态。

  • 持久化状态

    当处在托管状态的实体Bean被管理器flush了,那么就在极短暂的时间进入了持久化状态,事务提交之后,立刻变为了游离状态。可以把持久化状态当做实实在在的数据库记录。

  • 游离状态

    游离状态就是提交到数据库后,事务commit后实体的状态,因为事务已经提交了,此时实体的属性任你如何改变,也不会同步到数据库,因为游离是没人管的孩子,不在持久化上下文中。

  • 销毁对象

    一般要删除一个持久化对象的时候都是先find出来,之后调用remove方法删之,此时这个对象就是销毁对象,实际上就是瞬时对象的另一种形态罢了。


常用的 API

SELECT、DELETE

SELECT

Ø find() :返回指定的 OID 对应的实体类对象,如果这个实体存在于当前的持久化环境,则返回一个被缓存的对象;否则会创建一个新的 Entity, 并加载数据库中相关信息;若 OID 不存在于数据库中,则返回一个 null。

Ø getReference()

<T> T find(Class<T> entityClass, Object primaryKey);
<T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> var3);
<T> T find(Class<T> entityClass, Object primaryKey, LockModeType var3);
<T> T find(Class<T> entityClass, Object primaryKey, LockModeType var3, Map<String, Object> var4);<T> T getReference(Class<T> entityClass, Object primaryKey);// 参数说明:entityClass	// 被查询的实体类类型primaryKey	// 待查找实体的主键值

异同:

  1. 当在数据库中没有找到记录时,find()方法会返回null,

    而getReference() 方法会抛出javax.persistence.EntityNotFoundException异常,

  2. 调用getReference()方法,返回的其实并不是实例对象,而是一个代理。当你要使用实体时,才会真正的调用查询语句来查询实例对象

  3. 另外getReference()方法不保证 entity Bean已被初始化。

  4. 如果传递进getReference()或find()方法的参数不是实体Bean,都会引发 IllegalArgumentException


DELETE

Ø Remove()

void remove(Object entity);
  1. 如果级联关系cascade=CascadeType.ALL,在删除person 时候,也会把级联对象删除。把cascade属性设为cascade=CascadeType.REMOVE 有同样的效果。

    Person person = em.find(Person.class, 2);
    em.remove (person);
    
  2. 如果传递进remove ()方法的参数不是实体Bean,会引发一个IllegalArgumentException

    remove()方法不能移除游离对象,只能移除持久化对象

    Order order = new Order();
    order.setId(140);
    entityManager.remove(order);
    

    上面这段代码会抛出异常,因为order是自己创建的对象,也就是游离对象。必须这样写:

    Order order = new Order();
    order = entityManager.find(Order.class140);
    entityManager.remove(order);
    

    这段代码中的order是从数据库中获取的,也就是持久化对象

    hibernate的delete()方法,只要对象有Id,就可以删除


INSERT、UPDATE

INSERT

Ø persist(): 将临时状态的实体持久化到数据库

void persist(Object entity);

persist方法:使对象由临时状态变为托管状态。进而变为持久化状态,就是执行INSERT操作。

  1. 如果传递进persist()方法的参数不是实体Bean,会引发IllegalArgumentException
  2. 和hibernate的save()方法有些不同:当Entity实体类中设置了主键自动生成时,如果传入对象有id值,则会抛出异常

特殊场景及处理方案:

  • 特殊场景:Entity上使用自动生成ID值,但有些又需要插入的主键值是指定的ID值,而非自动生成的ID值

  • 处理方案1:Bean主键为Null,persist()后自动生成ID值,然后再使用QueryDsl-Jpa的update()方法,根据自动生成的ID值为条件,更新新增的实体的ID值为指定值

    @Test
    @Transactional
    @Rollback(false)
    public void addByEntityManager(){User bean = User.builder().addressee("孙六").build();entityManager.persist(u1);QUser entity = QUser.user;long execute = queryFactory.update(entity).set(entity.id, "11111").where(entity.id.eq(bean.getId())).execute();entityManager.flush();entityManager.clear();
    }
    
  • 处理方案2:使用Querydsl-SQL中,SqlQueryFactory.insert()方法。


UPDATE

Ø 当实体正在被容器管理,即托管状态,你可以调用实体的set方法对数据进行修改,在容器决定flush时(这个由Container自行判断),更新的数据才会同步到数据库,而不是在调用了set方法对数据进行修改后马上同步到数据库。如果希望修改后的数据马上同步到数据库,可以调用 EntityManager.flush() 方法。

// 使用示例
@tranational
publicvoid updatePerson() {Person person = entityManager.find(Person.class, 1);person.setName("lihuoming");	//方法执行完后即可更新数据entityManager.merge(person);
}

Ø Merge

<T> T merge(T entity);
  1. 传入的对象没有id

    在这种情况下,调用merge方法,将返回一个新的对象(有id),并对这个新的对象执行insert操作。

  2. 传入的对象有id,entityManager的缓存中没有该对象,数据库中没有该记录:

    在这种情况下,调用merge方法,将返回一个新的对象,并对该对象执行insert操作。

    注意:如果Entity的主键设置的是自动生成,则新对象的id并不是原传入对象的id,而是自动生成的(比如自增长的id)。(其实和情况1的结果是一样的)

  3. 传入的对象有id,entityManager的缓存没有该对象,数据库中有该记录

    在这种情况下,调用merge方法,将会从数据库中查询对应的记录,生成新的对象,然后将传入的对象复制到新的对象,最后执行update操作。

    简单来说,就是更新操作。

  4. 传入的对象有id,entityManager的缓存有该对象

    在这种情况下,调用merge方法,JPA会把传入的对象赋值到entityManager的缓存中的对象,然后对entityManager缓存中的对象执行update操作。(和情况3的结果一样)

总结:执行merge时,如果实体ID为空,则进行insert操作。 如果有ID则进行update操作。


flush()、clear()

flush()

将实体的改变立刻刷新到数据库中

当EntityManager对象在一个session bean 中使用时,它是和服务器的事务上下文绑定的。EntityManager 在服务器的事务提交时提交并且同步它的内容。

在一个session bean 中,服务器的事务默认地会在调用堆栈的最后提交(如:方法的返回)。

// 例子1:在方法返回时才提交事务
public void updatePerson(Person person) {try {Person person = em.find(Person.class, 2);person.setName("lihuoming");em.merge(person);//后面还有众多修改操作} catch (Exception e) {e.printStackTrace();}//更新将会在这个方法的末尾被提交和刷新到数据库中
}

默认只在当事务提交时才将改变更新到数据库中,容器将所有数据库操作集中到一个批处理中,这样就减少了代价昂贵的与数据库的交互。

当调用 persist( ),merge( )或 remove( ) 这些方法时,更新并不会立刻同步到数据库中,直到容器决定刷新到数据库中时才会执行,默认情况下,容器决定刷新是在 “相关查询” 执行前或事务提交时发生。

当然 “相关查询” 除 find() 和 getreference() 之外,这两个方法是不会引起容器触发刷新动作的,默认的刷新模式是可以改变的。


如果你需要在事务提交之前将更新刷新到数据库中,你可以直接地调用EntityManager.flush()方法。

ORM框架执行的一些更新数据库的方法,其实质是在更新缓存,只有调用了 flush() 后才会将缓存同步到数据库,即真正执行SQL语句,但是这时并没有真正将数据保存进数据库,需要事务commit后才能全部保存。一般 flush 后立刻就会进行事务的提交。

public void updatePerson(Person person) {try {Person person = em.find(Person.class, 2);person.setName("lihuoming");em.merge(person);em.flush();//手动将更新立刻刷新进数据库//后面还有众多修改操作} catch (Exception e) {e.printStackTrace();}
}

clear()

分离所有当前正在被管理的实体

1.清除持久上下文环境,断开所有关联的实体。如果这时还有未提交的更新则会被撤消。

2.在处理大量实体的时候,如果你不把已经处理过的实体从EntityManager中分离出来,将会消耗你大量的内存。

3.调用EntityManager 的clear()方法后,所有正在被管理的实体将会从持久化内容中分离出来。

4.有一点需要说明下,在事务没有提交前(事务默认在调用堆栈的最后提交,如:方法的返回),如果调用clear()方法,之前对实体所作的任何改变将会丢失,所以建议在调用clear()方法之前先调用flush()方法保存更改。


JcreateQuery() – PQL

创建查询对象

除了使用 find() 或 getReference() 方法来获得Entity Bean之外,你还可以通过 JPQL 得到实体Bean。要执行 JPQL 语句,你必须通过 EntityManager 的 createQuery() 或 createNamedQuery() 方法创建一个Query 对象。

注:JPQL 没有插入语句。即不能执行insert语句。


Ø getResultList()

Query query = em.createQuery("select p from Person p where p.name=’黎明’");
List result = query.getResultList();Iterator iterator = result.iterator();
while( iterator.hasNext() ){
//处理Person
}

Ø getSingleResult()

返回查询的第一条数据,可以进行强转,如:

// 查询数目:
Query query = em.createQuery("select count(1) from Person p");
Long num = (Long)query. getSingleResult ();// 强转为实体:
Query query = em.createQuery("select p from Person p");
User user = (User)query. getSingleResult ();

Ø executeUpdate()

// 执行更新和删除操作,返回受影响的记录数。
Query query = em.createQuery("delete from Person");
int result =query.executeUpdate();	 //影响的记录数

Ø 关于 **JPQL 和SQL **中参数的问题:

  1.  使用标识符
    
Query query =em.createQuery("delete from Person p where p.name := name");
query.setParameter("name","张三");
int result =query.executeUpdate(); //影响的记录数
  1.  使用索引下标
    
Query query =em.createQuery("delete from Person p where p.id = ?1 ");
query.setParameter(1, "张三");
int result =query.executeUpdate(); //影响的记录数  

createNaiveQuery() – SQL

用法基本同createQuery(),只不过这里使用的不是 JPQL 而是SQL

Ø 将查询到的数据映射成实体:

Query query = em.createNativeQuery("select * from person", Person.class);
List result = query.getResultList();if (result != null){Iterator iterator = result.iterator();while( iterator.hasNext() ){Person person= (Person)iterator.next();}
}

refresh()

如果怀疑当前被管理的实体已经不是数据库中最新的数据,则可以通过 refresh() 方法刷新实体,容器会把数据库中的新值重写进实体。这种情况一般发生在获取了实体之后,有人更新了数据库中的记录,这时需要得到最新的数据。当然再次调用 find() 或 getReference() 方法也可以得到最新数据,但这种做法并不优雅。

User user = em.find(User.class, 1);//第二次同样的查询不会访问数据库
user = em.find(User.class, 1);// 运行以上代码,发现调用了两次find,但是只执行了一次select语句,这是缓存导致的。// 执行refresh()方法刷新缓存,容器会把数据库中的新值重写进实体。
User user = em.find(User.class, 1);
em.refresh(user);

其他方法

contains()

判断实体是否还在EntityManage的管理下,或者说是否属于当前持久上下文环境。

contains() 方法使用一个实体作为参数,如果这个实体对象当前正被持久化内容管理,返回值为true,否则为false。

如果传递的参数不是实体 Bean,将会引发一个IllegalArgumentException.

User user = em.find(User.class, 1);if (em.contains(user)){//正在被持久化内容管理
}else{//已经不受持久化内容管理
}

getFlushMode ():

获取持久上下文环境的Flush模式。返回FlushModeType类的枚举值。


setFlushMode()

改变实体管理器的Flush模式

setFlushMode()的Flush模式有2种类型:AUTO 和 COMMIT。AUTO为默认模式。

// 改变实体管理器的Flush模式
em.setFlushMode(FlushModeType.COMMIT);
  • FlushModeType.AUTO

    默认情况下除了在事务提交时 flush,在进行查询时(除了 find() 和 getreference() 查询)也会进行一次 flush ,比如使用JPQL查询前会进行一次flush。

    使用场合:在大量更新数据的过程中没有任何查询语句(除了 find() 和 getreference() 查询)的执行。

  • FlushModeType.COMMIT

    刷新只有在事务提交时才发生,查询不触发。

    使用场合:在大量更新数据的过程中存在查询语句(除了find() 和 getreference() 查询)的执行。

其实上面两种模式最终反映的结果是:JDBC 驱动跟数据库交互的次数。

JDBC 性能最大的增进是减少JDBC 驱动与数据库之间的网络通讯。

FlushModeType.COMMIT 模式使更新只在一次的网络交互中完成,而 FlushModeType.AUTO 模式可能需要多次交互(触发了多少次Flush 就产生了多少次网络交互)


isOpen()

判断当前的实体管理器是否是打开状态


close()

关闭实体管理器。

之后若调用实体管理器实例的方法或其派生的查询对象的方法都将抛出 IllegalstateException 异常,除了 getTransaction 和 isOpen方法(返回 false)。

不过,当与实体管理器关联的事务处于活动状态时,调用 close() 方法后持久上下文将仍处于被管理状态,直到事务完成。


getTransaction()

返回资源层的事务对象。EntityTransaction实例可以用于开始和提交多个事务


EntityTransaction 接口用来管理资源层实体管理器的事务操作

通过调用实体管理器的getTransaction方法 获得其实例。

① begin ()

用于启动一个事务,此后的多个数据库操作将作为整体被提交或撤消。若这时事务已启动则会抛出 IllegalStateException 异常。

② commit ()

用于提交当前事务。即将事务启动以后的所有数据库更新操作持久化至数据库中。

③ rollback ()

撤消(回滚)当前事务。即撤消事务启动后的所有数据库更新操作,从而不对数据库产生影响。

④ setRollbackOnly ()

使当前事务只能被撤消。

⑤ getRollbackOnly ()

查看当前事务是否设置了只能撤消标志。

⑥ isActive ()

查看当前事务是否是活动的。如果返回true则不能调用begin方法,否则将抛出 IllegalStateException 异常;如果返回 false 则不能调用 commit、rollback、setRollbackOnly 及 getRollbackOnly 方法,否则将抛出 IllegalStateException 异常。

需要注意的是:

// 在JPA里面,先需要 getTransaction,再 begin 
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();// 在 hibernate 里面呢,直接 begin,然后进行 commit 
EntityTransaction transaction = session.beginTransaction();
transaction.commit();

JPA 调用存储过程

参考:https://www.cnblogs.com/zhuang229/p/12227938.html

定义存储过程及调用方式

定义一个简单的存储过程

传入一个int参数,返回这个参数+1

CREATE DEFINER=`root`@`localhost` PROCEDURE `plus1inout`(IN ARG INT, OUT res INT)
BEGIN SET res = ARG + 1;
END

注意:

  1. IN参数个数没有限制。

  2. 如果out参数类型为sys_refcursor,那么最好只定义这 一个out参数(JPA API限制);

    sys_refcursor 类型的 out 参数,在 JPA 中统一注册为 Void.class 类型,参数模式定义为 ParameterMode.REF_CURSOR;

    使用getResultList()方法获取游标fetch到的多行数据,返回结果为List<Object[]>,一个Object[]对应一行数据。

  3. 如果使用Oracle 存储包,只需在定义存储过程名字时加个对应的package名前缀即可(例如:包名.存储过程名)。


JPA调用存储过程的两种方式

  • 基于Entity实体类,在实体类上使用@NamedStoredProcedureQuery注解(需要数据库中有对应的表,可自动映射结果集)
    • EntityManager创建createNamedStoredProcedureQuery,传参调用
    • SpringDataJpa中Repository自定义方法,传参调用
  • 直接使用EntityManager进行自定义(不需要数据库中有对应的表,需要自己处理结果集)
    • EntityManager创建StoredProcedureQuery对象,注册 IN/OUT 参数模式

实体类(使用注解声明存储过程)

@NamedStoredProcedureQuery注解(解析详见注解目录)

  • name为唯一名称,调用时使用;procedureName 为存储过程名;

  • @Entity注解必须有

  • @Entity要求必须有主键id属性(存储过程可返回id任意值即可)

  • @Entity要求必须对应数据库表必须存在(JPA表检查用)(若用EntityManager调用存储过程,此条存疑)

import lombok.Data;
import javax.persistence.*;@Data
@Entity
// 存储过程使用了注解@NamedStoredProcedureQuery,并绑定到一个随意一个JPA表
@NamedStoredProcedureQueries({@NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = {@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) }),@NamedStoredProcedureQuery(name = "User.mytest", procedureName = "mytest") })
class user{@Idprivate Integer id;private String name;private String age;
}

EntityManager直接调用存储过程

@Autowired
private EntityManager em;@Test
public void test01(){StoredProcedureQuery query = em.createStoredProcedureQuery("plus1inout")	// 创建StoredProcedureQuery对象,传入被调用的存储过程名称.registerStoredProcedureParameter("ARG", Integer.class, ParameterMode.IN)	// 注册参数.registerStoredProcedureParameter("res", Integer.class, ParameterMode.OUT).setParameter("ARG", 20);	// 传参query.execute();	// 执行存储过程调用String result = query.getOutputParameterValue("res").toString();	// 获取存储过程中的返回值System.out.println(result);
}

调用基于实体类注解的存储过程

使用EntityManager调用基于Entity实体类注解的存储过程。实体类详见 JPA调用存储过程

@Autowired
private EntityManager em;@Test
public void test02(){StoredProcedureQuery query = em// 创建NamedStoredProcedureQuery对象,传入实体类上@NamedStoredProcedureQuery注解中name的值.createNamedStoredProcedureQuery("proKQAttendanceRecord")// IN模式的参数可以在实体类上注解,此处相应注释掉// .registerStoredProcedureParameter("PRM_ID", Integer.class, ParameterMode.IN)// 使用EntityManager调用基于Entity实体类注解的存储过程时,OUT或INOUT模式的参数,必须要在此处注册,并删掉原实体类上相应的参数注解。不然运行报错。.registerStoredProcedureParameter("PRM_APPCODE", Integer.class, ParameterMode.OUT).registerStoredProcedureParameter("PRM_ERRMSGE", Integer.class, ParameterMode.OUT).setParameter("PRM_ID", attId);		// 传参query.execute();List resultList = query.getResultList();Object code = query.getOutputParameterValue("PRM_APPCODE");Object msg = query.getOutputParameterValue("PRM_ERRMSGE");
}

相关文章:

JPA 之 Hibernate EntityManager 使用指南

Hibernate EntityManager 专题 参考&#xff1a; JPA – EntityManager常用API详解EntityManager基本概念 基本概念及获得 EntityManager 对象 基本概念 在使用持久化工具的时候&#xff0c;一般都有一个对象来操作数据库&#xff0c;在原生的Hibernate中叫做Session&…...

英语作文提示(持续更新)

星期&#xff08;介词on&#xff09;Monday星期一Tuesday星期二Wednesday星期三Thursday星期四Friday星期五Saturday星期六Sunday星期日月份&#xff08;介词in&#xff09;lunar calendar农历on the second day of the second lunar农历初二January1月February2月March3月Apri…...

【计算机组成原理】计算机的性能指标、数据的表示和运算、BCD码和余3码

计算机组成原理(二) 计算机的性能指标: 存储器的性能指标&#xff1a; 存储器中&#xff0c;MAR为存储单元的个数 MDR为机械字长也就是存储单元的长度 存储器的大小MAR*MDR n为二进制位能表示出几种不同的状态呢&#xff1f; 2的n次方种不同的状态 CPU的性能指标&#xf…...

三天吃透MySQL八股文(2023最新整理)

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…...

队列_23约瑟夫问题+_24猫狗收容所

约瑟夫问题 n 个小孩围坐成一圈&#xff0c;并按顺时针编号为1,2,…,n&#xff0c;从编号为 p 的小孩顺时针依次报数&#xff0c;由1报到m &#xff0c;当报到 m 时&#xff0c;该小孩从圈中出去&#xff0c;然后下一个再从1报数&#xff0c;当报到 m 时再出去。如此反复&#…...

gradle

Gradle环境介绍OpenJDK 17.0.5Gradle 7.6示例代码 fly-gradleGradle 项目下文件介绍如果你的电脑安装了 gradle&#xff0c;可以使用 gradle init 去初始化一个新的 gradle 工程&#xff0c;然后使用电脑安装的 gradle 去执行构建命令。但是每个开发电脑上的 gradle 版本不一样…...

[牛客]链表中倒数第k个结点

使用快慢指针法:两种思路:1.fast先向后走k-1次,slow再向后走1次,然后fast和slow同时向后走,当fast走到最后一个结点时,slow刚好在倒数第k个位置上;2.fast先向后走k次,slow再向后走1次,然后fast和slow同时向后走,当fast走到最后一个结点的后面时(此时为NULL),slow刚好在倒数第k个…...

English Learning - L2 语音作业打卡 双元音 [eɪ] [aɪ] Day14 2023.3.6 周一

English Learning - L2 语音作业打卡 双元音 [eɪ] [aɪ] Day14 2023.3.6 周一&#x1f48c;发音小贴士&#xff1a;&#x1f48c;当日目标音发音规则/技巧:&#x1f36d; Part 1【热身练习】&#x1f36d; Part2【练习内容】&#x1f36d;【练习感受】&#x1f353;元音 /eɪ/…...

C++ this 指针与静态成员

文章目录参考描述实例成员与静态成员实例成员静态成员静态成员属性隐式形参 this 指针冲突this 指针静态成员函数this 指针与静态成员函数参考 项目精通C &#xff08;第九版&#xff09;托尼加迪斯、朱迪沃尔特斯、戈德弗雷穆甘达 &#xff08;著&#xff09; / 黄刚 等 &…...

REDIS16_LRU算法概述、查看默认内存、默认是如何删除数据、缓存淘汰策略

文章目录①. LRU算法概述②. 查看默认内存③. 如何删除数据④. 缓存淘汰策略①. LRU算法概述 ①. LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的数据给予淘汰 (leetcode-cn.com/problems/lru-cache) ②. LRU算法题来源 ③.…...

ClassMix: Segmentation-Based Data Augmentation for Semi-Supervised Learning学习笔记

ClassMix相关介绍主要思想方法Mean-Teacher损失函数交叉熵损失标签污染实验实验反思参考资料相关介绍 从DAFormer溯源到这篇文章&#xff0c;ClassMix主要是集合了伪标签和一致性正则化&#xff0c;思想来源于CutMix那条研究路线&#xff0c;但是优化了CutMix中的标签污染的情…...

CSDN竞赛第35期题解

CSDN竞赛第35期题解 1、题目名称&#xff1a;交换后的or 给定两组长度为n的二进制串&#xff0c;请问有多少种方法在第一个串中交换两个不同位置上的数字&#xff0c;使得这两个二进制串“或”的 结果发生改变&#xff1f; int n;cin>>n; string a,b;cin>>a>…...

Java应用服务系统安全性,签名和验签浅析

1 前言 随着互联网的普及&#xff0c;分布式服务部署越来越流行&#xff0c;服务之间通信的安全性也是越来越值得关注。这里&#xff0c;笔者把应用与服务之间通信时&#xff0c;进行的的安全性相关&#xff0c;加签与验签&#xff0c;进行了一个简单的记录。 2 安全性痛点 …...

spring中bean的实例化

构造方法实现实例化 无参构造器实例化 我们之前用的就一直是无参构造器实现实例化&#xff0c;虽然没有在类中写构造器&#xff0c;但是每个类都会有一个默认的无参构造器 有参构造器实例化 相比于无参构造器&#xff0c;我们只需要传入参数就可以了 我们可以通过construc…...

磨皮插件portraiture2023最新中文版

Portraiture滤镜是一款 Photoshop&#xff0c;Lightroom 和 Aperture 插件&#xff0c;DobeLighttroom 的 Portraiture 消除了选择性掩蔽和逐像素处理的繁琐的手工劳动&#xff0c;以帮助您在肖像修整方面取得卓越的效果。它是一个强大的&#xff0c;但用户友好的插件照明.这是…...

记录每日LeetCode 2269.找到一个数组的K美丽值 Java实现

题目描述&#xff1a; 一个整数 num 的 k 美丽值定义为 num 中符合以下条件的 子字符串 数目&#xff1a; 子字符串长度为 k 。 子字符串能整除 num 。 给你整数 num 和 k &#xff0c;请你返回 num 的 k 美丽值。 注意&#xff1a; 允许有 前缀 0 。 0 不能整除任何…...

代码管理--svnadmin工具介绍

1、简介 SVNAdmin2 是一款通过图形界面管理服务端SVN的web程序。正常情况下配置SVN仓库的人员权限需要登录到服务器手动修改 authz 和 passwd 两个文件&#xff0c;当仓库结构和人员权限上了规模后&#xff0c;手动管理就变的非常容易出错&#xff0c;本系统能够识别人员和权限…...

Git的基本使用以及上传到GitHub

GIT的基本使用一、安装并配置GIT二、Git的基本操作三、使用GIT上传至GitHub四、Git分支一、安装并配置GIT 1.安装GIT连接 GIT安装包链接 2.打开GIT 鼠标右键点击Git Bash Here 安装完 Git 之后&#xff0c;第一件事就是设置自己的用户名和邮件地址。因为通过 Git 对项目进行…...

国科大论文latex模板中可能的注意事项

背景 国科大2022年9月发布了毕业论文的LaTeX模板&#xff0c;它是在ucasthesis上修改而来的&#xff0c;但近日使用国科大发布版本时发现有几点不同以及需要注意的地方。本人只会简单使用latex&#xff0c;但并不熟悉latex样式编辑&#xff0c;因此以下介绍与方法仅供参考。仅…...

ABAP 怎样将XML和JSON格式转换为HTML格式显示

ABAP 怎样将XML和JSON格式转换为HTML格式显示 一、将JSON格式转换为HTML格式 BAP接口程序开发中时常会用到JSON格式来传输数据&#xff0c;在监控传输的JSON串内容时&#xff0c;把JSON转换为HTML格式来显示会很便利。下面提供一个简单例子来实现JSON转化为HTML并显示的功能。…...

基础课DP

DP 背包问题01背包问题完全背包问题多重背包问题多重背包问题II分组背包问题线性DP数字三角形最长上升子序列最长上升子序列II最长公共子序列编组距离区间DP石子合并计数类DP整数划分数位统计DP计数问题状态压缩DP蒙德里安的梦想最短Ha路径树形DP没有上司的舞会...

基于支持向量机SVM的风电场NWP数据预测,SVM的详细原理

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 SVM应用实例,基于SVM的风电场NWP预测 结果分析 展望 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定…...

webRtc概念

webRtc概念 以下的文档整理来自此链接 文档整理了一系列实现web通用接口的ECMAScript APIs &#xff0c;这些接口是为了支持浏览器或者一些其他实现了实时交换协议的设备进行媒体信息和程序数据交换。 1、实现点对点通信的规范&#xff1a; NAT穿透实现与远端节点链接比如&a…...

数据结构与算法基础(王卓)(16):KMP算法详解(代码实现)

实现代码的过程中 具体细节、问题&#xff1a; &#xff08;1&#xff09;&#xff1a;关于写Get_next函数的标题&#xff1a; 现象&#xff1a; PPT上写的是&#xff1a; void get_next(SString T, int &next[]) 然而并不能运行&#xff0c;而当我们去掉了引用符号&…...

九龙证券|盘前直接腰斩,银行巨头紧急“拔网线”!美股银行股又崩了?

见证历史了&#xff0c;又有一家银行巨子倒下&#xff1f; 美股银行股团体暴降 上一交易日暴降超60%的硅谷银行持续面对腥风血雨。盘前&#xff0c;硅谷银行跌幅超50%&#xff0c;随后&#xff0c;公司宣布盘前暂停交易&#xff0c;等待刊发消息。 而最新消息显现&#xff0c…...

接口优化常用思路

空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾&#xff0c;那么&#xff0c;从这个角度出发逆向思维来考虑程序的效率问题&#xff0c;我们就有了解决问题的第1招–以空间换时间 合理使用缓存就是一个很好的例子&#xff0c;针对一些频繁使用且不频繁变更的数据&#…...

【SpringCloud】SpringCloud面试题整理

文章目录1、什么是Spring Cloud&#xff1f;2、Spring Cloud和Dubbo的区别3、REST和RPC的区别4、SpringCloud如何实现服务的注册和发现5、什么是服务熔断和服务降级&#xff1f;6、项目中zuul常用的功能7、服务网关的作用8、ribbon和feign区别9、ribbon的负载均衡策略10、简述什…...

一些数据库知识点总结

DB2数据库&#xff1a;从数据库表中第I条记录开始检索J条记录SELECT * FROM (SELECT A.*, ROW_NUMBER() OVER() AS NFROM (SELECT * FROM table_name) AS A)WHERE N > I AND N < J;Oracle数据库&#xff1a;从数据库表中第M条记录开始检索N条记录SELECT * FROM (SELECT R…...

Python unittest 模块

一、Unittest 的几个基本概念 TestCase &#xff1a;要写的具体的测试用例TestSuite&#xff1a; 多个测试用例集合&#xff08;或测试套件/测试集&#xff09;TestLoader&#xff1a;用来加载 TestCase 到 TestSuite中的&#xff08;更通俗一点&#xff0c;就是用来把符合我们…...

Spring - Spring IoC 容器相关面试题总结

文章目录01. Spring IoC 和依赖注入是什么&#xff1f;02. Spring IoC 的优点和缺点分别是什么&#xff1f;03. Spring IoC 有什么作用和功能&#xff1f;04. Spring 依赖注入的方式&#xff1f;05. Spring 构造器注入和 setter 方法注入的区别&#xff1f;06. Spring 依赖注入…...

河北邯郸网站建设公司/湖北百度seo

学习Office自动化之前先阅读一些COM书籍&#xff0c;对于理解Office自动化有很大帮助。以下示例代码使用VS2010进行编译。目前市面上已有的关于Office自动化的书籍&#xff0c;多是快餐式的&#xff0c;看过之后只能知道最基本的使用。要想更多的了解&#xff0c;非得MSDN不可。…...

外贸没有公司 如何做企业网站/德州seo整站优化

大家是不是经常看到如下代码List list Arrays.asList("a","b","c");list.stream().forEach(System.out::println);这个“::”到底是什么语法呢&#xff1f;在JAVA 8 中&#xff0c;可以通过 “::” 关键字来访问类的构造方法&#xff0c;对象方…...

广州做网站seo/seo sem是指什么意思

Solr 是一种可供企业使用的、基于 Lucene 的搜索服务器&#xff0c;它支持层面搜索、命中醒目显示和多种输出格式。在这篇文章中&#xff0c;将介绍 Solr 并展示如何轻松地将其表现优异的全文本搜索功能加入到 Web 应用程序中。 开发环境&#xff1a; System&#xff1a;Window…...

做网站片头的软件/武汉百度推广开户

github地址:https://github.com/cheesezh/python_design_patterns 适配器模式 适配器模式&#xff0c;将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作[DP]。 当系统的数据和行为都正确&#xff0c;但是接口…...

河北网站制作公司地址/seo短期课程

目录 ThreadPoolExecutor 源码阅读Executor 框架ExecutorExecutorServiceAbstractExecutorService构造器状态Worker 与任务调度提交任务线程池关闭ThreadPoolExecutor 源码阅读 读了一下 ThreadPoolExecutor 的源码(JDK 11), 简单的做个笔记. Executor 框架 Executor Executor …...

响应式网站软件/头条广告入口

CSS作为Web标准的一部分&#xff0c;已经成为现代网页设计中必不可少的关键要素。网页学习网CSS教程专题系统地讲解了CSS样式表的基础理论和实际运用技术&#xff0c;通过大量实例对CSS进行深入浅出的分析&#xff1b;透彻地讲解CSS核心技术的基础上&#xff0c;深入到各个CSS实…...