Spring Data JPA方法名命名规则

news2024/9/22 5:38:18

最近巩固一下JPA,网上看到这些资料,这里记录巩固一下。

一、Spring Data Jpa方法定义的规则

简单条件查询

        简单条件查询:查询某一个实体类或者集合。
        按照Spring Data的规范的规定,查询方法以find | read | get开头(比如 find、findBy、read、readBy、get、getBy),涉及查询条件时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。
        直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,即不用写SQL,目前支持的关键字写法如下:

二、只有查询参数

定义一个Entity实体类:

class People{
       private String firstName;
       private String lastName;
}

以上使用and条件查询时,应这样写

findByLastNameAndFirstName(StringlastName,String firstName); 

注意:条件的属性名称与个数要与参数的位置与个数一一对应

三、查询同时排序

        如果方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询比如

Page findByName(String name, Pageable pageable);

List findByName(String name, Sort sort);

排序也可以这么写

List<Cus> findBySexOrderByName(String sex); //名称正序(正序时,推荐此方式,简单)
List<Cus> findBySexOrderByNameAsc(String sex); //名称正序(效果同上)
List<Cus> findBySexOrderByNameDesc(String sex); //名称倒序

四、查询参数是 对象里面的对象的属性

如,查询参数是ERole.EMemberAccount.memberCode 一般我们会这么写

   @Query("select e from ERole e where e.memberAccount.memberCode = ?1")
    List<ERole> findByMerchantCode(String merchantCode);

如果用命名规则可以这么写

List<ERole> findByMemberAccountMemberCode(String merchantCode);

查询方法解析流程

        假如我们创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除findBy,然后对剩下的属性进行解析,假设查询实体为Doc。

  1. 先判断userDepUuid (根据POJO(Plain Ordinary Java Object简单java对象,实际就是普通java bean)规范,首字母变为小写。)是否是查询实体的一个属性,如果根据该属性进行查询;如果没有该属性,继续第二步。

  2. 从右往左截取第一个大写字母开头的字符串(此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user为查询实体的一个属性。

  3. 接着处理剩下部分(DepUuid),先判断user所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2的规则从右往左截取,最终表示根据“Doc.user.dep.uuid” 的值进行查询。

  4. 可能会存在一种特殊情况,比如 Doc包含一个user的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 "_"以显式表达意图,比如"findByUser_DepUuid()" 或者"findByUserDep_uuid()"。

五、命名规则不适合动态查询

当查询条件为null时,如

  • 实体定义:对于一个客户实体Cus,包含有name和sex,均是String类型。
  • 查询方法定义:List<Cus> findByNameAndSex(String name,String sex);
  • 使用时:dao.findByNameAndSex(null, "男");
  • 后台生成sql片断:where (cus0_.name is null) and cus0_.sex=?

        结论:当查询时传值是null时,数据库中只有该字段是null的记录才符合条件,并不是说忽略这个条件。也就是说,这种查询方式,只适合于明确查询条件必须传的业务,对于动态查询(条件多少是动态的,例如一般的查询列表,由最终用户使用时决定输入那些查询条件),这种简单查询是不能满足要求的。

强调:需要强调的是,命名规则也不适合delete insert update. 只适合简单查询

 

六、Spring Data JPA对多表查询的选择

答案是肯定的,直接上结论。

方案说明自定义接收对象SQL分页多表联合问题
方案一@QueryJPQL:DTO或投影原生SQL:Object[],map(2个字段时)JPQL或原生SQLJpaRepository实体上配不配关系都可以1.查询条件要嵌入SQL语句内,一些复杂的情形不好处理,例如某个字段模糊检索,字段是动态的;2.分页查询countQuery把查询语句重复了一遍
方案二Specification不支持,只能返回对应PO无SQL结合JpaRepository需要在实体上配置关系,如@OneToOne,否则无法实现左连接,只能联合查询1.实体需要配置连接关系2.每一个关联对象都是单独的数据库查询
方案三EntityManager不支持投影,其他同@QueryJPQL或原生SQL自己封装实体上配不配关系都可以相比于@Query好处是,JPQL字符串可以动态拼接,可以处理一些复杂的查询情形。但是分页需要自己封装。
方案四CriteriaQueryDTO无SQL自己封装需要在实体上配置关系,如@OneToOne否则无法实现左连接,只能联合查询同Specification,且分页需要自己封装
终极方案QueryDSLDTOTuple无SQL支持实体上配不配关系都可以解决以上所有问题

选择一个好的解决方案,需要考虑如下几个方面:

  • 能够自定义对象接收查询结果集;
  • 能够支持复杂的、动态的查询条件;
  • 既然使用JPA,当然最好能够用类型安全的查询方式,并且使用起来比较自然;
  • 能够原生支持分页查询;
  • 能够支持left join,并且对实体定义没有约束。

上表就是从这几个方面进行分析,最后QueryDSL堪称完美,下面详细介绍几种方案。

示例代码:GitHub - zhongpan/jpa-demo

七、JPA、Hibernate、Spring Data JPA三者的关系

        先了解下JPA、Hibernate、Spring Data JPA三者的关系是什么?

        JPA是一个接口规范,随着Java EE 5发布,也是EJB3.0的一部分。Hibernate是先于JPA出现的一种历史悠久的ORM框架,它实现了JPA,也是目前用的最多的实现。而Sprint Data JPA是Spring中提供的开箱即用的基于JPA的数据库访问框架,其采用的实现正是Hibernate。Spring Data JPA提供的数据库访问能力如下:

img

从上述接口的名字就可以看出:

  • CrudRepository:最基本的增删改查操作
  • PagingAndSortingRepository:分页查询
  • QueryByExampleExecutor:基于样本查询,避免了传一堆参数,还要判断是否null
  • JpaSpecificationExecutor:基于Specification查询,就是对CriteriaQuery的封装,类型安全的查询方式
  • QuerydslPredicateExecutor:基于QueryDSL的查询,也是类型安全的

        上述接口的实现在SimpleJpaRepository和QuerydslJpaPredicateExecutor中,其中就是基于JPA的EntiryManager接口进行封装。如果我们要重写实现,也是通过EntiryManager来完成。

方案一

        首先想到的方法自然是使用@Query注解,直接使用JPQL进行联合查询,自定义接收对象,left join都不在话下。主要的问题是对于一些复杂的、动态的查询条件不好处理,另外分页的countQuery不得不把主查询重写一遍,有点烦人。

 
@Repository
public interface VmhostDao extends JpaRepository<VmhostPO, String> {

  // 方法一:使用@Query注解,可以自定义接收对象
  // 问题:查询条件要嵌入SQL语句内,一些复杂的情形不好处理,例如某个字段模糊检索,字段是动态的;分页查询countQuery把查询语句重复了一遍

  @Query("select new com.example.demo.entity.VmhostDTO(v, u, t) from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id where v.name like %?1%")
  List<VmhostDTO> findVmhost(String name);

  @Query("select new com.example.demo.entity.VmhostInfoDTO(v.id, v.name, u.username, t.name) from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id where v.name like %:name%")
  List<VmhostInfoDTO> findVmhostInfo(String name);

  @Query("select v.id as id, v.name as name, u.username as userName, t.name as tname from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id")
  List<VmhostInfoByProjection> findVmhostInfoByProjection();

  @Query(value = "select new com.example.demo.entity.VmhostInfoDTO(v.id, v.name, u.username, t.name) from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id where v.name like %:name%", 
  countQuery = "select count(*) from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id where v.name like %:name%")
  Page<VmhostInfoDTO> findVmhostInfoByPage(String name, Pageable pageable);

}

方案二

        那么SQL的组织能否动态编程控制呢,自然会想到Specification查询,查询条件可以通过CriteriaQuery动态拼装。这也是Spring Data JPA中用的最广泛的查询方式。

        但是这种方式存在一些限制,首先不能灵活自定义接收对象,只能返回PO,其次要想实现left join,必须在实体上定义关系,最后关联对象不是一次查询回来的,而是单独的查询。

public interface VmhostSpecWithRelationDao
    extends JpaRepository<VmhostWithRelationPO, String>, JpaSpecificationExecutor<VmhostWithRelationPO> {

  // 方案二:使用Specification查询
  // 问题:实体必须配置关系,否则无法左连接;每个关联对象是单独数据库查询
}



package com.example.demo.service;

@Service
public class VmhostService {

  public List<VmhostWithRelationPO> listVmhostSpecWithRelation(String name) {
    Specification<VmhostWithRelationPO> spec = (root, cq, cb) -> {
      root.join("user", JoinType.LEFT);
      root.join("tenant", JoinType.LEFT);
      return cb.like(root.get("name"), "%" + name + "%");
    };
    List<VmhostWithRelationPO> list = vmhostSpecWithRelationDao.findAll(spec);
    return list;
  }

}

可能大家有两点疑问:

  • @Query和Specification能否混用,@Query定义select的结果,Specification定义查询条件

答案:不行,总是@Query有效,你定义的Specification参数压根就不会理会

 
// JpaSpecificationExecutor的参数和JpaRepository不一样,没啥用,SimpleJpaRepository总是用的JpaRepository的参数
public interface VmhostSpecDao extends JpaRepository<VmhostPO, String>, JpaSpecificationExecutor<VmhostInfoDTO> {

  // 方案二:@Query和Specification是不能混用的,也无法改变接收结果集对象

  // 无法混用,总是query有效,spec参数压根就不会理会
  @Query("from VmhostPO")
  List<VmhostPO> findVmhost(Specification<VmhostPO> spec);

  // 覆盖JpaSpecificationExecutor的方法可以吗?一样的,根本不会走到findAll的默认实现 
  @Override
  @Query("select new com.example.demo.entity.VmhostInfoDTO(v.id, v.name, u.username, t.name) from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id")
  List<VmhostInfoDTO> findAll(Specification<VmhostInfoDTO> spec);
}
  • Specification控制接收结果集对象

答案:对不起,Specification的toPredicate中执行select是无效的,里面只能返回查询条件。

 
  // 这样写没有用,生成如下sql
  // select vmhostpo0_.id as id1_2_, vmhostpo0_.addresses as addresse2_2_, vmhostpo0_.availablezone as availabl3_2_, vmhostpo0_.baremetal as baremeta4_2_, vmhostpo0_.cpucore as cpucore5_2_, vmhostpo0_.createtime as createti6_2_, vmhostpo0_.disksize as disksize7_2_, vmhostpo0_.floatip as floatip8_2_, vmhostpo0_.hostname as hostname9_2_, vmhostpo0_.locked as locked10_2_, vmhostpo0_.metadata as metadat11_2_, vmhostpo0_.name as name12_2_, vmhostpo0_.privatenetworkid as private13_2_, vmhostpo0_.ramsize as ramsize14_2_, vmhostpo0_.tenantid as tenanti15_2_, vmhostpo0_.tenantname as tenantn16_2_, vmhostpo0_.type as type17_2_, vmhostpo0_.userid as userid18_2_, vmhostpo0_.username as usernam19_2_, vmhostpo0_.vmstatus as vmstatu20_2_ from vmhost vmhostpo0_ cross join auth_user authuserpo1_ cross join auth_tenant authtenant2_ where vmhostpo0_.userid=authuserpo1_.id and vmhostpo0_.tenantid=authtenant2_.id and (vmhostpo0_.name like ?)
public Optional<VmhostInfoDTO> listVmhostSpec(String name) {
  Specification<VmhostInfoDTO> spec = (root, cq, cb) -> {
    // 只能cross join,要left join需要在实体上建立关系
    Root<AuthUserPO> user = cq.from(AuthUserPO.class);
    Root<AuthTenantPO> tenant = cq.from(AuthTenantPO.class);
    // 这里执行select没有用,这个函数只能返回查询条件,外层会覆盖select
    cq.multiselect(root.get("id"), root.get("name"), user.get("username"), tenant.get("name"));
    return cb.and(cb.equal(root.get("userid"), user.get("id")), cb.equal(root.get("tenantid"), tenant.get("id")),
        cb.like(root.get("name"), "%" + name + "%"));

  };
  return vmhostSpecDao.findOne(spec);
}

因为SimpleJpaRepository的实现已经固定了select,跟JpaRepository的类型参数相关,跟JpaSpecificationExecutor的类型参数无关

 
protected <S extends T> TypedQuery<S> getQuery(@Nullable Specification<S> spec, Class<S> domainClass, Sort sort) {

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<S> query = builder.createQuery(domainClass);

    Root<S> root = applySpecificationToCriteria(spec, domainClass, query);
    query.select(root);

    if (sort.isSorted()) {
        query.orderBy(toOrders(sort, root, builder));
    }

    return applyRepositoryMethodMetadata(em.createQuery(query));
}

方案三

上面两种使用方法是Spring Data JPA用的最多的,接下来只能从底层入手,直接使用EntiryManager。这种方法完全靠自己,所有接口都需要自己实现,丧失了Spring Data JPA的便利性。

 
@Repository
public class VmhostEMDao {

  @Autowired
  @PersistenceContext
  private EntityManager entityManager;

  // 方案三:使用原生的entityManager,解决@Query的SQL无法动态拼接问题
  // 此时分页就需要自己封装了,也没有了JPA自动实现的接口
  // 注意这里like后面要引号

  @SuppressWarnings("unchecked")
  public List<VmhostDTO> findVmhost(String name) {
    List<VmhostDTO> list = entityManager.createQuery(
        "select new com.example.demo.entity.VmhostDTO(v, u, t) from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id where v.name like '%"
            + name + "%'")
        .getResultList();
    return list;
  }

  @SuppressWarnings("unchecked")
  public List<VmhostInfoByProjection> findVmhostInfoByProjection() {
    // 此时总是Object[],不支持投影
    List<VmhostInfoByProjection> list = entityManager.createQuery(
        "select v.id as id, v.name as name, u.username as userName, t.name as tname from VmhostPO v left join AuthUserPO u on v.userid = u.id left join AuthTenantPO t on v.tenantid = t.id")
        .getResultList();
    return list;
  }

}

方案四

类似于方案二之于方案一,我们也可以使用类型安全的查询方式CriteraQuery。

 
@Repository
public class VmhostCQDao {

  @Autowired
  @PersistenceContext
  private EntityManager entityManager;

  // 方案四:相对于方案三,使用了类型安全的CriteriaQuery,其实Specification也是用的CriteriaQuery,所以存在和Specification一样的限制,但是可以控制select了,比Specification灵活一点

  public List<VmhostDTO> findVmhost(String name) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<VmhostDTO> query = builder.createQuery(VmhostDTO.class);
    // 实体上没有配置关系,无法使用left join,只能联合查询(inner join)
    Root<VmhostPO> root = query.from(VmhostPO.class);
    Root<AuthUserPO> rootUser = query.from(AuthUserPO.class);
    Root<AuthTenantPO> rootTenant = query.from(AuthTenantPO.class);
    query.multiselect(root, rootUser, rootTenant).where(builder.equal(root.get("userid"), rootUser.get("id")),
        builder.equal(root.get("tenantid"), rootTenant.get("id")), builder.like(root.get("name"), "%" + name + "%"));

    List<VmhostDTO> list = entityManager.createQuery(query).getResultList();
    return list;
  }

}

终极方案

        到了终极方案了,Spring Data JPA集成了对QueryDSL的支持,官方参考见:http://www.querydsl.com/static/querydsl/latest/reference/html_single。

        是不是有点像方案二+方案四,单表的时候直接使用JpaRepository和QuerydslPredicateExecutor提供的默认实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.demo.dao;

import com.example.demo.entity.VmhostPO;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;

public interface VmhostQDSLDao
    extends JpaRepository<VmhostPO, String>, QuerydslPredicateExecutor<VmhostPO>, VmhostRepository {

  // 方案五:VmhostRepository使用原生的entityManager配合QueryDSL,完美解决所有问题
  // 对于单表也可以使用QuerydslPredicateExecutor,自动拥有默认实现

}

        多表的时候就基于EntityManager扩展,但是querydsl已经帮我们做了很多工作,不是从头开始。querydsl的书写方式相对于CriteriaQuery也更加自然,易于理解。

1
2
3
4
5
6
7
@NoRepositoryBean
public class BaseRepository {

  @PersistenceContext
  protected EntityManager em;

}
1
2
3
4
5
6
7
public interface VmhostRepository {

  public List<VmhostDTO> findVmhost(Predicate predicate);

  public QueryResults<VmhostDTO> findVmhostByPage(Predicate predicate, Pageable pageable);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Repository
public class VmhostRepositoryImpl extends BaseRepository implements VmhostRepository {

  // 多表左连接

  @Override
  public List<VmhostDTO> findVmhost(Predicate predicate) {
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);
    JPAQuery<VmhostDTO> jpaQuery = queryFactory
        .select(Projections.constructor(VmhostDTO.class, QVmhostPO.vmhostPO, QAuthUserPO.authUserPO,
            QAuthTenantPO.authTenantPO))
        .from(QVmhostPO.vmhostPO).leftJoin(QAuthUserPO.authUserPO)
        .on(QVmhostPO.vmhostPO.userid.stringValue().eq(QAuthUserPO.authUserPO.id.stringValue()))
        .leftJoin(QAuthTenantPO.authTenantPO)
        .on(QVmhostPO.vmhostPO.tenantid.stringValue().eq(QAuthTenantPO.authTenantPO.id.stringValue()));
    jpaQuery.where(predicate);
    return jpaQuery.fetch();
  }

  @Override
  public QueryResults<VmhostDTO> findVmhostByPage(Predicate predicate, Pageable pageable) {
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);
    JPAQuery<VmhostDTO> jpaQuery = queryFactory
        .select(Projections.constructor(VmhostDTO.class, QVmhostPO.vmhostPO, QAuthUserPO.authUserPO,
            QAuthTenantPO.authTenantPO))
        .from(QVmhostPO.vmhostPO).leftJoin(QAuthUserPO.authUserPO)
        .on(QVmhostPO.vmhostPO.userid.stringValue().eq(QAuthUserPO.authUserPO.id.stringValue()))
        .leftJoin(QAuthTenantPO.authTenantPO)
        .on(QVmhostPO.vmhostPO.tenantid.stringValue().eq(QAuthTenantPO.authTenantPO.id.stringValue()))
        .offset(pageable.getOffset()).limit(pageable.getPageSize());
    jpaQuery.where(predicate);
    return jpaQuery.fetchResults();
  }

}

总结

        以上方法都还是在Spring Data JPA框架之内,如果你愿意,你也可以去重写SimpleJpaRepository,重写了注意通过如下注解启用。

1
@EnableJpaRepositories(repositoryBaseClass = XXXXXX.class)

        其实QueryDSL已经做了很好的封装,完全没有必要重复造轮子,Spring Data JPA也提供了很多扩展点,在保留其便利性的基础上,根据需要去扩展,不需要全部推倒重来。

参考:

Spring Data JPA方法名命名规则 - 简书

Spring Data JPA中多表联合查询最佳实践 | 钟潘的博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1202101.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java实现一个简单的贪吃蛇小游戏

一、创建新项目 首先创建一个新的项目&#xff0c;并命名为贪吃蛇。 其次在贪吃蛇项目下创建一个名为images的文件夹用来存放游戏相关图片。 用到的图片如下&#xff1a; 游戏标题&#xff1a; 贪吃蛇的身体&#xff1a; 贪吃蛇的头部&#xff1a; 因为要向四个方向移动&am…

VINS-Mono-后端优化 (四:边缘化原理)

滑窗中固定只能有11帧&#xff0c;当来了新的帧的时候旧的帧就需要抹掉&#xff0c;但是不能直接把旧的帧的全部信息抹掉&#xff0c;因为旧的帧的经历过11次优化&#xff0c;其地图点中的优化信息是有用&#xff0c;边缘化的操作就是为了只把最旧帧的变量去掉&#xff0c;但是…

霸榜“双11”,高端文创新品发布即售罄,剑南春大促节点再传佳绩

执笔 | 洪大大 编辑 | 萧 萧 作为一年一度的重要促销大节&#xff0c;“双11”线上购物已成为各大品牌奋战的重要战场。而在今年&#xff0c;剑南春也是再一次拔得头筹。 在刚刚出炉的“双11”战报中&#xff0c;天猫剑南春官方旗舰店以超高人气和销售量获得白酒行业交易指…

来看看电脑上有哪些不为人知的小众软件?

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.桌面停靠栏工具——BitDock ​ BitDock是一款运行在Windows系统中的桌面停靠栏工具&#xff0c;功能实…

RFID汽车制造工业系统解决方案

随着物联网技术的不断发展&#xff0c;汽车行业的信息化水平也在不断提高&#xff0c;随着近几年国产汽车的带动&#xff0c;汽车配件配套市场也已形成了一定的规模&#xff0c;初步形成比较完整成熟的零部件配套体系。 RFID汽车制造工业系统解决方案 与其他行业对比&#xff0…

【Springboot】基于注解式开发Springboot-Vue3整合Mybatis-plus实现分页查询(一)——后端实现思路

系列文章目录 基于注解式开发Springboot-Vue3整合Mybatis-plus实现分页查询(二&#xff09;——前端el-pagination实现 文章目录 系列文章目录系统版本实现功能操作步骤1. 新建Mybatis的全局分页配置文件2. 编写OrderMapper :继承Mybatis-plus提供的BaseMapper3. 编写OrderSer…

UE基础必学系列:项目和文件结构

官方文档:https://learn.unrealengine.com/course/ 张佳亮:UE4插件相关说明文档 1、uproject,以商城下载的ActionRPG为例 {"FileVersion": 3,"EngineAssociation": "4.20","Category": "Samples","Description&qu…

​《水经注全国三维离线GIS系统》硬件安装教程

有些工作&#xff0c;是需要一些外在动力才能完成的。 为什么这么讲呢&#xff1f; 因为正是在客户的要求下&#xff0c;我们才撰写了《水经注全国三维离线GIS系统》的硬件安装教程&#xff0c;而且还录制了视频教程。 当用户收到货物以后&#xff0c;就可以通过本教程清点货…

医学影像PACS系统:一种用于存储、管理和传输医学影像数据的系统

医疗软件中的影像归档与传输系统软件&#xff08;Picture Archiving and Communication System&#xff0c;简称PACS&#xff09;是一种用于存储、管理和传输医学影像数据的系统。 PACS是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff…

excel记录wFm数值(推理过程)

1 导入计算wfm库2 实例化具体的指标 3 列表循环之前&#xff0c;设置空list 4 单图评测-将图号、图片名、数值记录 列表里面存储dict 5 将excel列表结果逐个存入excel.xlsx文件 完整代码 test_CPD.py ### test_CPD.py ### import torch import torch.nn.functional as Fimpor…

卷积神经网络(CNN)-吴恩达

1 计算机视觉 得益于深度学习的发展&#xff0c;计算机视觉是发展的最好的领域之一。 计算机视觉包括图像分类、 目标检测、神经风格转换 1、图像分类&#xff0c;有时也叫图像识别 2、计算机视觉问题的一个挑战是输入可以是任意大 2 边缘检测例子 1、卷积运算是卷积神经网络…

深度神经网络算子参数量和计算量分析—卷积篇

前言 在用于计算机视觉任务的深度神经网络模型中&#xff0c;卷积算子作为一种重要的特征提取方式被广泛应用&#xff0c;本文针对常见的卷积算子参数量和计算量的计算方法进行分析&#xff0c;主要包括普通卷积、深度可分离卷积、分组卷积&#xff0c;以及自动计算模型参数量和…

无人机交付:跨境电商的数字化未来

随着科技的不断进步&#xff0c;跨境电商行业正经历着前所未有的数字化变革。其中&#xff0c;无人机交付正成为这一领域的未来之路&#xff0c;为电商企业和消费者带来了新的便利和机遇。本文将深入探讨无人机交付在跨境电商中的应用&#xff0c;以及它如何塑造数字化未来。 无…

大促期间治理品牌窜货的诀窍

渠道问题中&#xff0c;最常见的是窜货&#xff0c;窜货还会伴随低价&#xff0c;会影响其他经销商的利益&#xff0c;同时窜货还可能带来假货&#xff0c;所以治理窜货是品牌的责任&#xff0c;对于出货量巨大的双十一大促&#xff0c;品牌更应重视对窜货问题的治理。 力维网络…

上课笔记(11.11之前笔记)

一.数据结构的分类 1.数据结构中分为四大类&#xff1a;线性表&#xff0c;哈希表&#xff0c;树&#xff0c;图。 2.线性表&#xff08;line table&#xff09;&#xff1a;呈现线性结构的一种数据结构。具有顺序性&#xff0c;也就是所有数据都是有序的&#xff1b; 数组&…

(1)(1.14) LightWare SF10/SF11激光雷达

文章目录 前言 1 串行连接 2 I2C 连接 3 参数说明 前言 Lightware SF20 和 LW20 是体积小、测距远&#xff08;100m&#xff09;、精度高的测距仪。有两种型号&#xff0c;LW20/Ser 使用串行接口&#xff0c;LW20/I2C 使用 I2C 接口。 1 串行连接 对于串行连接&#xff0…

Autosar模块介绍:FEE(Flash模拟EEPROM)

上一篇 | 返回主目录 | 下一篇 Autosar模块介绍&#xff1a;FEE(Flash模拟EEPROM 1 基本术语解释2 Ea组成结构图3 Ea基本操作3.1 通用操作3.2 作业的进程&#xff08;通用需求&#xff09;3.3 读操作过程3.4 写操作过程3.5 擦除过程3.6 比较过程 4 Ea常用操作时序4.1 初始化4.…

uniapp打包安卓app获取包名

uniapp打包安卓app获取包名的两种方式 1.uniapp云打包 这上面直接可以看到包名&#xff0c;可以修改&#xff0c;也可以在 manifest.json 文件中配置修改 package配置的就是包名&#xff0c;要确保唯一性 2.使用aapt工具获取 1.下载aapt工具&#xff0c;然后添加到环境变量…

汽车FMCW毫米波雷达信号处理流程(推荐---基础详细---清楚的讲解了雷达的过程---强烈推荐)

毫米波雷达在进行多目标检测时&#xff0c;TX发射一个Chirp&#xff0c;在不同距离下RX会接收到多个反射Chirp信号&#xff08;仅以单个chirp为例&#xff09;。 雷达通过接收不同物体的发射信号&#xff0c;并转为IF信号&#xff0c;利用傅里叶变换将产生一个具有不同的分离峰…

高端NEV | 地表最强纯电,极氪001 FR上市做到“技惊四座”了吗?

百万超跑赛道越来越“香”&#xff0c;本以为它是来“凑热闹”的&#xff0c;竟成「地表最强」&#xff1f; “友商们&#xff0c;五年内造不出来&#xff01;”的极氪001 FR上市口号火速传遍全网。 ◎图源网络 上周&#xff0c;号称地表最强纯电“战士”极氪001 FR在北京举行…