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

seo网站建设规划做网站好的网络公司

seo网站建设规划,做网站好的网络公司,手机端快速建站工具,招聘桂林网站推广维护建设最近巩固一下JPA#xff0c;网上看到这些资料#xff0c;这里记录巩固一下。 一、Spring Data Jpa方法定义的规则 简单条件查询 简单条件查询#xff1a;查询某一个实体类或者集合。 按照Spring Data的规范的规定#xff0c;查询方法以find | read | get开头网上看到这些资料这里记录巩固一下。 一、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);排序也可以这么写 ListCus findBySexOrderByName(String sex); //名称正序正序时推荐此方式简单 ListCus findBySexOrderByNameAsc(String sex); //名称正序效果同上 ListCus findBySexOrderByNameDesc(String sex); //名称倒序四、查询参数是 对象里面的对象的属性 如查询参数是ERole.EMemberAccount.memberCode 一般我们会这么写 Query(select e from ERole e where e.memberAccount.memberCode ?1)ListERole findByMerchantCode(String merchantCode);如果用命名规则可以这么写 ListERole findByMemberAccountMemberCode(String merchantCode);查询方法解析流程 假如我们创建如下的查询findByUserDepUuid(),框架在解析该方法时首先剔除findBy然后对剩下的属性进行解析假设查询实体为Doc。 先判断userDepUuid (根据POJOPlain Ordinary Java Object简单java对象实际就是普通java bean规范首字母变为小写。)是否是查询实体的一个属性如果根据该属性进行查询如果没有该属性继续第二步。 从右往左截取第一个大写字母开头的字符串(此处为Uuid)然后检查剩下的字符串是否为查询实体的一个属性如果是则表示根据该属性进行查询如果没有该属性则重复第二步继续从右往左截取最后假设 user为查询实体的一个属性。 接着处理剩下部分DepUuid先判断user所对应的类型是否有depUuid属性如果有则表示该方法最终是根据 “Doc.user.depUuid” 的取值进行查询否则继续按照步骤 2的规则从右往左截取最终表示根据“Doc.user.dep.uuid” 的值进行查询。 可能会存在一种特殊情况比如 Doc包含一个user的属性也有一个 userDep 属性此时会存在混淆。可以明确在属性之间加上 _以显式表达意图比如findByUser_DepUuid() 或者findByUserDep_uuid()。 五、命名规则不适合动态查询 当查询条件为null时如 实体定义对于一个客户实体Cus,包含有name和sex均是String类型。查询方法定义ListCus 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分页多表联合问题方案一QueryJPQLDTO或投影原生SQLObject[]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提供的数据库访问能力如下 从上述接口的名字就可以看出 CrudRepository最基本的增删改查操作PagingAndSortingRepository分页查询QueryByExampleExecutor基于样本查询避免了传一堆参数还要判断是否nullJpaSpecificationExecutor基于Specification查询就是对CriteriaQuery的封装类型安全的查询方式QuerydslPredicateExecutor基于QueryDSL的查询也是类型安全的 上述接口的实现在SimpleJpaRepository和QuerydslJpaPredicateExecutor中其中就是基于JPA的EntiryManager接口进行封装。如果我们要重写实现也是通过EntiryManager来完成。 方案一 首先想到的方法自然是使用Query注解直接使用JPQL进行联合查询自定义接收对象left join都不在话下。主要的问题是对于一些复杂的、动态的查询条件不好处理另外分页的countQuery不得不把主查询重写一遍有点烦人。 Repository public interface VmhostDao extends JpaRepositoryVmhostPO, 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%)ListVmhostDTO 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%)ListVmhostInfoDTO 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)ListVmhostInfoByProjection 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%)PageVmhostInfoDTO findVmhostInfoByPage(String name, Pageable pageable);}方案二 那么SQL的组织能否动态编程控制呢自然会想到Specification查询查询条件可以通过CriteriaQuery动态拼装。这也是Spring Data JPA中用的最广泛的查询方式。 但是这种方式存在一些限制首先不能灵活自定义接收对象只能返回PO其次要想实现left join必须在实体上定义关系最后关联对象不是一次查询回来的而是单独的查询。 public interface VmhostSpecWithRelationDaoextends JpaRepositoryVmhostWithRelationPO, String, JpaSpecificationExecutorVmhostWithRelationPO {// 方案二使用Specification查询// 问题实体必须配置关系否则无法左连接每个关联对象是单独数据库查询 }package com.example.demo.service;Service public class VmhostService {public ListVmhostWithRelationPO listVmhostSpecWithRelation(String name) {SpecificationVmhostWithRelationPO spec (root, cq, cb) - {root.join(user, JoinType.LEFT);root.join(tenant, JoinType.LEFT);return cb.like(root.get(name), % name %);};ListVmhostWithRelationPO list vmhostSpecWithRelationDao.findAll(spec);return list;}}可能大家有两点疑问 Query和Specification能否混用Query定义select的结果Specification定义查询条件 答案不行总是Query有效你定义的Specification参数压根就不会理会 // JpaSpecificationExecutor的参数和JpaRepository不一样没啥用SimpleJpaRepository总是用的JpaRepository的参数 public interface VmhostSpecDao extends JpaRepositoryVmhostPO, String, JpaSpecificationExecutorVmhostInfoDTO {// 方案二Query和Specification是不能混用的也无法改变接收结果集对象// 无法混用总是query有效spec参数压根就不会理会Query(from VmhostPO)ListVmhostPO findVmhost(SpecificationVmhostPO spec);// 覆盖JpaSpecificationExecutor的方法可以吗一样的根本不会走到findAll的默认实现 OverrideQuery(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)ListVmhostInfoDTO findAll(SpecificationVmhostInfoDTO 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_.useridauthuserpo1_.id and vmhostpo0_.tenantidauthtenant2_.id and (vmhostpo0_.name like ?) public OptionalVmhostInfoDTO listVmhostSpec(String name) {SpecificationVmhostInfoDTO spec (root, cq, cb) - {// 只能cross join要left join需要在实体上建立关系RootAuthUserPO user cq.from(AuthUserPO.class);RootAuthTenantPO tenant cq.from(AuthTenantPO.class);// 这里执行select没有用这个函数只能返回查询条件外层会覆盖selectcq.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 TypedQueryS getQuery(Nullable SpecificationS spec, ClassS domainClass, Sort sort) {CriteriaBuilder builder em.getCriteriaBuilder();CriteriaQueryS query builder.createQuery(domainClass);RootS 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 {AutowiredPersistenceContextprivate EntityManager entityManager;// 方案三使用原生的entityManager解决Query的SQL无法动态拼接问题// 此时分页就需要自己封装了也没有了JPA自动实现的接口// 注意这里like后面要引号SuppressWarnings(unchecked)public ListVmhostDTO findVmhost(String name) {ListVmhostDTO 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 ListVmhostInfoByProjection findVmhostInfoByProjection() {// 此时总是Object[]不支持投影ListVmhostInfoByProjection 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 {AutowiredPersistenceContextprivate EntityManager entityManager;// 方案四相对于方案三使用了类型安全的CriteriaQuery其实Specification也是用的CriteriaQuery所以存在和Specification一样的限制但是可以控制select了比Specification灵活一点public ListVmhostDTO findVmhost(String name) {CriteriaBuilder builder entityManager.getCriteriaBuilder();CriteriaQueryVmhostDTO query builder.createQuery(VmhostDTO.class);// 实体上没有配置关系无法使用left join只能联合查询(inner join)RootVmhostPO root query.from(VmhostPO.class);RootAuthUserPO rootUser query.from(AuthUserPO.class);RootAuthTenantPO 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 %));ListVmhostDTO 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 14package 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 VmhostQDSLDaoextends JpaRepositoryVmhostPO, String, QuerydslPredicateExecutorVmhostPO, VmhostRepository {// 方案五VmhostRepository使用原生的entityManager配合QueryDSL完美解决所有问题// 对于单表也可以使用QuerydslPredicateExecutor自动拥有默认实现}多表的时候就基于EntityManager扩展但是querydsl已经帮我们做了很多工作不是从头开始。querydsl的书写方式相对于CriteriaQuery也更加自然易于理解。 1 2 3 4 5 6 7NoRepositoryBean public class BaseRepository {PersistenceContextprotected EntityManager em;}1 2 3 4 5 6 7public interface VmhostRepository {public ListVmhostDTO findVmhost(Predicate predicate);public QueryResultsVmhostDTO 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 35Repository public class VmhostRepositoryImpl extends BaseRepository implements VmhostRepository {// 多表左连接Overridepublic ListVmhostDTO findVmhost(Predicate predicate) {JPAQueryFactory queryFactory new JPAQueryFactory(em);JPAQueryVmhostDTO 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();}Overridepublic QueryResultsVmhostDTO findVmhostByPage(Predicate predicate, Pageable pageable) {JPAQueryFactory queryFactory new JPAQueryFactory(em);JPAQueryVmhostDTO 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重写了注意通过如下注解启用。 1EnableJpaRepositories(repositoryBaseClass XXXXXX.class)其实QueryDSL已经做了很好的封装完全没有必要重复造轮子Spring Data JPA也提供了很多扩展点在保留其便利性的基础上根据需要去扩展不需要全部推倒重来。 参考 Spring Data JPA方法名命名规则 - 简书 Spring Data JPA中多表联合查询最佳实践 | 钟潘的博客
http://www.hkea.cn/news/14265904/

相关文章:

  • 黄页网页的推广网站wordpress jexus
  • 外贸网站建设不可缺少的灵活性一般做企业网站需要什么
  • 揭阳网站开发mituad网站备案管理办法
  • 做网站服务费税率邯郸网站建设优化排名
  • 做网站需要会编程吗网站建设通常用到哪些编程
  • 中国网站建设市场排名做设计素材在哪个网站
  • 贵阳手机网站开发商务网站建设与维护 ppt
  • 域名网站注册最划算当前主流的网络营销方式
  • 搭建网站需要多少钱网站建设方式丨金手指排名26
  • 如何搭建网站教程南通做网站优化
  • 创建个人网站的流程平台搭建步骤
  • 做网站建设需要什么资质商城app开发价格
  • 如何提升网站的搜索排名网站快照
  • 关于做一动物网站的界面个互联网做网站怎么赚钱
  • 值得相信的西安网站开发英文网站建设公司 杭州
  • 职高门户网站建设标准书画网站建设方案策划
  • 门户网站什么意思游戏开发引擎
  • 做棋牌网站犯法吗石家庄有什么做网站的公司
  • asp做学生信息网站网上做头像用什么网站
  • 网站搜索不到公司网站外贸搜素网站
  • 河南建设厅网站查证阜宁做网站工作室
  • 百度网盘搜索引擎网站微信公众平台运营
  • 公司网站制作需要多少钱河北省住房城乡建设厅网站
  • 自己的网站什么做优化e时代速递搜索引擎网站建设
  • 企业网站建设策划书1万字足球世界排名前十
  • 南海区建设局网站首页1688平台
  • ftp 上传网站海珠区
  • 如何在谷歌上做网站优秀企业宣传册样本
  • 网站建设单位哪家好开发软件赚一千万
  • 网页制作与网站建设从入门到精通公司有网站有什么好处