应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

SpringBoot与GraphQL集成

  目录GraphQL介绍SpringBoot与Graphql集成
  运行环境:JDK8,Maven3。0
  技术栈:SpringBoot2。5一、GraphQL介绍
  GraphQL既是一种用于API的查询语言也是一个满足你数据查询的运行时。GraphQL对你的API中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让API更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
  GraphQL优势请求你所要的数据,不多不少
  向你的API发出一个GraphQL请求就能准确获得你想要的数据,不多不少。GraphQL查询总是返回可预测的结果。使用GraphQL的应用可以工作得又快又稳,因为控制数据的是应用,而不是服务器。获取多个资源只用一个请求
  GraphQL查询不仅能够获得资源的属性,还能沿着资源间引用进一步查询。典型的RESTAPI请求多个资源时得载入多个URL,而GraphQL可以通过一次请求就获取你应用所需的所有数据。这样一来,即使是比较慢的移动网络连接下,使用GraphQL的应用也能表现得足够迅速。描述所有的可能类型系统
  GraphQLAPI基于类型和字段的方式进行组织,而非入口端点。你可以通过一个单一入口端点得到你所有的数据能力。GraphQL使用类型来保证应用只请求可能的数据,还提供了清晰的辅助性错误信息。应用可以使用类型,而避免编写手动解析代码。SpringBoot与GraphQL集成Graphql插件Idea开发工具集成Graphql插件,从FilesettingsPlugins安装插件
  安装完插件后,可创建graphql类型文件
  数据库及表创建数据库创建:
  createdatabasesopbase;表创建:
  createtablesysuser
  (
  useridbigintautoincrement
  primarykey,
  usernamevarchar(50)notnullcomment用户名,
  passwordvarchar(100)nullcomment密码,
  saltvarchar(20)nullcomment盐,
  emailvarchar(100)nullcomment邮箱,
  mobilevarchar(100)nullcomment手机号,
  statustinyintnullcomment状态0:禁用1:正常,
  deptidbigintnullcomment部门ID,
  createtimedatetimenullcomment创建时间,
  constraintusername
  unique(username)
  )
  comment系统用户charsetutf8mb4;项目工程结构及源码介绍项目工程结构
  核心源码介绍API层提供查询及更改类解析器,分别实现查询和更改接口
  用户查询类解析器
  authorlxj
  see〔相关类方法〕(可选)
  since〔产品模块版本〕(可选)
  Component
  publicclassUserQueryResolverimplementsGraphQLQueryResolver{
  Autowired
  privateUserServiceuserService;
  publicListgetUserList(){
  returnuserService。list();
  }
  publicUsergetUserInfo(LonguserId){
  returnuserService。getById(userId);
  }
  publicPageUtilsgetUserPage(MapString,Objectparams){
  PageUtilspageuserService。queryPage(params);
  returnpage;
  }
  }
  用户更新类解析器
  authorlxj
  see〔相关类方法〕(可选)
  since〔产品模块版本〕(可选)
  Component
  publicclassUserMutationResolverimplementsGraphQLQueryResolver,GraphQLMutationResolver{
  Autowired
  privateUserServiceuserService;
  publicRaddUser(Useruser){
  userService。stroe(user);
  returnR。ok();
  }
  publicRdeleteUser(IntegeruserId){
  if(userIdnull){
  returnR。error(1,fail);
  }
  userService。removeById(userId);
  returnR。ok();
  }
  publicRupdateUser(Useruser){
  if(usernull){
  returnR。error(1,fail);
  }
  userService。updateById(user);
  returnR。ok();
  }
  }dao数据操作层DAO
  Mapper
  表明这是一个Mapper,也可以在启动类上加上包扫描
  Mapper继承该接口后,无需编写mapper。xml文件,即可获得CRUD功能
  publicinterfaceUserMapperextendsBaseMapper{
  }entity实体类
  Data
  TableName(valuesysuser)
  ApiModel(description用户信息)
  publicclassUserimplementsSerializable{
  privatestaticfinallongserialVersionUID5644799954031156649L;
  value与数据库主键列名一致,若实体类属性名与表主键列名一致可省略value
  TableId(valueuserid,typeIdType。AUTO)指定自增策略
  ApiModelProperty(value用户ID,requiredtrue)
  privateLonguserId;
  用户名
  ApiModelProperty(value用户名,requiredtrue)
  privateStringusername;
  密码
  ApiModelProperty(value用户密码,requiredtrue)
  privateStringpassword;
  盐
  privateStringsalt;
  邮箱
  ApiModelProperty(value用户邮箱,requiredtrue)
  privateStringemail;
  手机号
  privateStringmobile;
  状态0:禁用1:正常
  privateIntegerstatus;
  部门ID
  privateLongdeptId;
  部门名称
  TableField(existfalse)
  privateStringdeptName;
  角色ID列表
  TableField(existfalse)
  privateListroleIdList;
  创建时间
  TableField(fillFieldFill。INSERTUPDATE)
  privateDatecreateTime;
  }service业务逻辑层
  接口类:
  publicinterfaceUserServiceextendsIService{
  分页查询
  paramparams
  return
  PageUtilsqueryPage(MapString,Objectparams);
  根据姓名查询
  paramname
  return
  UserqueryByName(Stringname);
  booleanstroe(Useruser);
  voidupdate(Useruser);
  UsergetUserById(LonguserId);
  }
  实现类:
  Service(userService)
  publicclassUserServiceImplextendsServiceImplUserMapper,UserimplementsUserService{
  Override
  publicPageUtilsqueryPage(MapString,Objectparams){
  Stringname(String)params。get(username);
  QueryWrapperuserQueryWrappernewQueryWrapper();
  userQueryWrapper。like(StringUtils。isNotEmpty(name),username,name);
  QueryquerynewQuery();
  IPagepagethis。page(query。getPage(params),userQueryWrapper);
  returnnewPageUtils(page);
  }
  Override
  publicUserqueryByName(Stringname){
  QueryWrapperuserQueryWrappernewQueryWrapper();
  userQueryWrapper。eq(username,name);
  returnthis。getOne(userQueryWrapper);
  }
  Override
  Transactional(rollbackForException。class)
  publicbooleanstroe(Useruser){
  StringsaltRandomStringUtils。randomAlphanumeric(20);
  Stringpwduser。getPassword()salt;
  user。setSalt(salt);
  user。setPassword(DigestUtils。md5Hex(pwd));
  this。save(user);
  returntrue;
  }
  Override
  Transactional(rollbackForException。class)
  publicvoidupdate(Useruser){
  if(org。apache。commons。lang。StringUtils。isBlank(user。getPassword())){
  user。setPassword(null);
  }else{
  StringsaltRandomStringUtils。randomAlphanumeric(20);
  Stringpwduser。getPassword()salt;
  user。setSalt(salt);
  user。setPassword(DigestUtils。md5Hex(pwd));
  }
  this。updateById(user);
  }
  Override
  publicUsergetUserById(LonguserId){
  Useruserthis。getById(userId);
  returnuser;
  }
  }Application应用启动类
  启动类
  authorlxj
  SpringBootApplication
  publicclassLearnGraphqlApplication{
  publicstaticvoidmain(String〔〕args){
  SpringApplication。run(LearnGraphqlApplication。class,args);
  }
  }Mapper配置
  lt;?xmlversion1。0encodingUTF8?
  mapperPUBLICmybatis。orgDTDMapper3。0ENhttp:mybatis。orgdtdmybatis3mapper。dtd
  mappernamespacecom。learn。springboot。dao。UserMapper
  resultMaptypecom。learn。springboot。entity。UseriduserMap
  resultpropertyuserIdcolumnuserid
  resultpropertyusernamecolumnusername
  resultpropertypasswordcolumnpassword
  resultpropertysaltcolumnsalt
  resultpropertyemailcolumnemail
  resultpropertymobilecolumnmobile
  resultpropertystatuscolumnstatus
  resultpropertydeptIdcolumndeptid
  resultpropertycreateTimecolumncreatetime
  spanresultMap
  spanmapperapplication。yml应用配置文件,应用启动会自动读取配置
  server:
  port:80
  servlet:
  contextpath:
  tomcat:
  tomcat的URI编码
  uriencoding:UTF8
  tomcat最大线程数,默认为200
  maxthreads:800
  Tomcat启动初始化的线程数,默认值25
  minsparethreads:30
  spring:
  datasource:
  type:com。alibaba。druid。pool。DruidDataSource
  druid:
  driverclassname:com。mysql。cj。jdbc。Driver
  username:sopbase
  password:sopbase
  url:jdbc:mysql:localhost:3306sopbase?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneUTC
  initialsize:10连接池初始大小
  maxactive:100连接池中最大的活跃连接数
  minidle:10连接池中最小的活跃连接数
  maxwait:60000配置获取连接等待超时的时间
  poolpreparedstatements:true打开PSCache,并且指定每个连接上PSCache的大小
  maxpoolpreparedstatementperconnectionsize:20
  timebetweenevictionrunsmillis:60000
  minevictableidletimemillis:300000
  Oracle需要打开注释
  validationquery:SELECT1FROMDUAL
  testwhileidle:true是否在连接空闲一段时间后检测其可用性
  testonborrow:false是否在获得连接后检测其可用性
  testonreturn:false是否在连接放回连接池后检测其可用性
  statviewservlet:
  enabled:true
  urlpattern:druid
  loginusername:admin
  loginpassword:admin
  filter:
  stat:
  logslowsql:true
  slowsqlmillis:1000
  mergesql:false
  wall:
  config:
  multistatementallow:true
  mybatis
  mybatisplus:
  mapperlocations:classpath:mapper。xml
  实体扫描,多个package用逗号或者分号分隔com。example。。entity
  typeAliasesPackage:com。learn。springboot。entity
  globalconfig:
  数据库相关配置
  dbconfig:
  主键类型AUTO:数据库ID自增,INPUT:用户输入ID,IDWORKER:全局唯一ID(数字类型唯一ID),UUID:全局唯一IDUUID;
  idtype:AUTO
  logicdeletevalue:1
  logicnotdeletevalue:0
  banner:false
  原生配置
  configuration:
  开启sql日志
  logimpl:org。apache。ibatis。logging。stdout。StdOutImpl
  logimpl:org。apache。ibatis。logging。slf4j。Slf4jImpl
  logimpl:org。apache。ibatis。logging。log4j2。Log4j2Impl
  该配置就是将带有下划线的表字段映射为驼峰格式的实体类属性
  mapunderscoretocamelcase:true
  cacheenabled:false
  callsettersonnulls:true
  jdbctypefornull:null
  GraphQLcom。graphqljavakickstart
  graphql:
  servlet:
  mapping:graphql
  enabled:true
  corsEnabled:true关闭跨域,仅使用浏览器插件调试时设置为false
  playground:
  cdn:
  enabled:trueplayground使用cdn的静态文件
  ifyouwanttoExceptionHandlerannotationforcustomGraphQLErrors
  exceptionhandlersenabled:true
  contextSetting:PERREQUESTWITHINSTRUMENTATION
  tools:
  扫描resource下。graphql后缀的文件
  schemalocationpattern:。graphqlGraphQL文件配置
  result。graphql
  typeR{
  code:Int!
  msg:String
  }
  root。graphql
  定义查询类型和更改类型
  schema{
  query:Query
  mutation:Mutation
  }
  定义一个空的查询类型
  typeQuery{
  }
  定义一个空的更改类型
  typeMutation{
  }
  user。graphql
  extendtypeQuery{
  getUserInfo(userId:String!):User
  getUserList:〔User〕
  getUserPage(params:paginationUserInput!):PageUserResult!
  }
  extendtypeMutation{
  addUser(user:addUserInput!):R
  deleteUser(userId:String!):R
  updateUser(user:updateUserInput):R
  }
  typeUser{
  userId:Long
  用户名
  username:String
  密码
  password:String
  盐
  salt:String
  邮箱
  email:String
  手机号
  mobile:String
  状态0:禁用1:正常
  status:Int
  部门ID
  deptId:Int
  createTime:Date
  }
  typePageUserResult{
  currPage:Int!
  pageSize:Int!
  totalPage:Int!
  totalCount:Int!
  list:〔User〕!
  }
  inputpaginationUserInput{
  limit:String10
  page:String0
  查询条件生成不固定
  用户名
  username:String
  密码
  password:String
  盐
  salt:String
  邮箱
  email:String
  手机号
  mobile:String
  状态0:禁用1:正常
  status:Int
  部门ID
  deptId:Int
  }
  添加系统用户输入参数
  inputaddUserInput{
  用户名
  username:String
  密码
  password:String
  盐
  salt:String
  邮箱
  email:String
  手机号
  mobile:String
  状态0:禁用1:正常
  status:Int
  部门ID
  deptId:Int
  }
  更新系统用户输入参数
  inputupdateUserInput{
  userId:String
  用户名
  username:String
  密码
  password:String
  盐
  salt:String
  邮箱
  email:String
  手机号
  mobile:String
  状态0:禁用1:正常
  status:Int
  部门ID
  deptId:Int
  }
  通常是一个对象就是一个java实体类,在graphql中也如此,也是一个对象对应一个。graphql文件。项目配置说明项目pom。xml添加graphql依赖
  dependency
  groupIdcom。graphqljavakickstartspangroupId
  artifactIdgraphqlspringbootstarterspanartifactId
  version11。0。0spanversion
  spandependency
  dependency
  groupIdcom。graphqljavakickstartspangroupId
  artifactIdgraphiqlspringbootstarterspanartifactId
  version8。1。1spanversion
  scoperuntimespanscope
  spandependencyapplication。yml中graphql配置
  GraphQL
  graphql:
  servlet:
  mapping:graphql
  enabled:true
  corsEnabled:true关闭跨域,仅使用浏览器插件调试时设置为false
  playground:
  cdn:
  enabled:trueplayground使用cdn的静态文件
  ifyouwanttoExceptionHandlerannotationforcustomGraphQLErrors
  exceptionhandlersenabled:true
  contextSetting:PERREQUESTWITHINSTRUMENTATION
  tools:
  扫描resource下。graphql后缀的文件
  schemalocationpattern:。graphql加载Mybatis配置
  MapperScan注解加载扫描持久层包路径,来增加配置。该配置也可以加在工程application启动类。无自定配置,只需通过持久层接口加Mapper注解,可不引用MapperScan注解。
  MybatisPlus插件加载
  authorlxj
  Configuration
  MapperScan(com。learn。springboot。dao)
  publicclassMybatisPlusConfig{
  新的分页插件
  Bean
  publicMybatisPlusInterceptormybatisPlusInterceptor(){
  MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();
  interceptor。addInnerInterceptor(newPaginationInnerInterceptor(DbType。MYSQL));
  returninterceptor;
  }
  }
  数据表字段自动填充实现
  定义写数据入库默认值
  authorlxj
  Component
  publicclassCTMetaObjectHandlerimplementsMetaObjectHandler{
  Override
  publicvoidinsertFill(MetaObjectmetaObject){
  this。setFieldValByName(createTime,newDate(),metaObject);
  }
  Override
  publicvoidupdateFill(MetaObjectmetaObject){
  自定元数据处理逻辑
  }
  }自定义graphql类型
  定义graphql新Long类型
  authorlxj
  Configuration
  publicclassLongScalarConfig{
  Bean
  publicGraphQLScalarTypelongScalar(){
  returnGraphQLScalarType。newScalar()
  。name(Long)
  。description(Java8Longasscalar。)
  。coercing(newCoercingLong,String(){
  Override
  publicStringserialize(finalObjectdataFetcherResult){
  if(dataFetcherResultinstanceofLong){
  returndataFetcherResult。toString();
  }else{
  thrownewCoercingSerializeException(ExpectedaLongobject。);
  }
  }
  Override
  publicLongparseValue(finalObjectinput){
  try{
  if(inputinstanceofString){
  returnnewLong((String)input);
  }else{
  thrownewCoercingParseValueException(ExpectedaString);
  }
  }catch(Exceptione){
  thrownewCoercingParseValueException(String。format(NotavalidLong:s。,input),e
  );
  }
  }
  Override
  publicLongparseLiteral(finalObjectinput){
  if(inputinstanceofStringValue){
  try{
  returnnewLong(((StringValue)input)。getValue());
  }catch(Exceptione){
  thrownewCoercingParseLiteralException(e);
  }
  }else{
  thrownewCoercingParseLiteralException(ExpectedaStringValue。);
  }
  }
  })。build();
  }
  }工程演示右键运行Application应用启动类的main函数,然后在浏览器访问图形化界面:
  http:localhostgraphiql
  新增数据调用
  查询调用:
  注意:typeQuery方法名和我们resolver中的方法名必须一致graphql文件中定义的对象的属性列,必须在java实体类中一一进行对应

过程短暂,难入睡做梦多!中医清热固精,帮助恢复邵大夫,我这几年一直有行事太短暂的情况,尝试过很多调理方法,但效果也是时好时坏。另外,最近一段时间晚上遗X比较频繁,一周有个两三次。其实之前偶有也会有这种情况,但是不太频繁,也……从绝地求生中毒圈影响看待核武器威胁以及辐射的意义绝地求生在绝地求生的游戏过程中,每一个玩家都遇到一个蓝色的光圈驱逐玩家到一个较小的地方交火。这个蓝圈就是毒圈。游戏的每一局比赛的毒圈都是随机位置范围开始缩小的,游戏……早财经丨上海放开地摊经济不再全面禁止路边摊iPhone14发NO。19月24日,全球财富管理论坛2022秋季峰会举行。全球财富管理论坛理事长、财政部原部长楼继伟表示,中国继续坚定不移地支持全球化,坚定不移地融入和推进全球化。我国主动扩大……一本会动的书,带孩子了解自己的身体人体是世界上最伟大的工程,它不仅能支撑我们的行动,还可以学习、思考、创造,这使得我们在智慧和创新上优于地球上其他物种。足够了解人体,我们才能很好地保护和使用自己的身体。……直击21世纪亚洲金融年会丨科技赋能提升金融服务质效长尾小微融由南方财经全媒体集团指导,数字化智库型财经媒体领跑者《21世纪经济报道》、21财经APP主办的第十七届21世纪亚洲金融年会,于2022年12月19日23日隆重举行。此次亚……50女人秋冬穿搭禁忌黑色裤袜没脖子,膝上裙!妈妈们总爱穿一年四季,深冬阶段算是最磨人的。漂亮的衣服穿着冷,想要保暖就得层层叠叠,再好看的人,裹成一个粽子,也看不到什么优势了。但即便如此,你会发现,会打扮的女人,反而可以利用叠穿……一个掀翻世界第三一个追平个人最佳,王曦雨张帅闯入美网32强北京时间今天凌晨,经过2小时44分的鏖战,21岁的中国女网小将、现单打世界排名第75位的王曦雨,在美国网球公开赛女单第二轮中,以3比6、7比5和7比5淘汰赛会3号种子、希腊名将……一年卖出百亿!闷声不吭的牛栏山,为何比纯粮酒卖得还火还赚钱?牛栏山15块一瓶,你敢相信他能卖到年销100亿?别不信,这是真实的数据,年销量能达到20亿瓶,这是什么概念啊,相当于每天的销量都达到了50多万瓶。这个惊人的数字无时……解决自卑!突破困境!全面分析孩子的教育《孩子的教育》一书,是由国际文化出版公司出版,光尘系列的心理学书籍。今年我阅读了很多光尘的心理学书籍,包括《心理咨询与治疗》《儿童教育法则》等等非常优秀的大师作品。对于光尘的心……晓春哥每日推荐聊一款性能实在的洗衣机晓春哥每日推荐今天聊一款性能实在的洗衣机小天鹅TG100V66WIADY。这款洗衣机,我们的综合评分是7。27分,虽然不是特别高,但相对它2千出头的价格来看,对手也不多了……瓜德尔港经多次转手,中国接手后变成什么样了?中国人说话是算数的,这是巴基斯坦JOLTA电动车公司主席阿基姆,在听到瓜德尔港招商后说的一句话,他也是该港口开始招商以来,第一个在这里投资建厂的巴基斯坦商人。瓜德尔港是巴……中国国内最具代表性的五大美食小吃,每个都好吃绝了中国,以华夏文明为源泉,中华文化为基础,是世界上历史最悠久的国家之一。我国的美食多样化可以说没有任何一个国家可比的,要说到美食排名,更是每个人心目中都有自己的排名,接下来……
iPhone15或全系列搭载灵动岛,网友却更期待这项升级文名动科技今年发布的iPhone14系列,最受欢迎的并不是标准版,而是Pro系列,相信大家也有所发现。目前的市场反馈来看,也确实是这般情况,据网友给出了iPhone……中药当归补益气血的日常应用及浪漫民间传说前言:今天,人们衣食不愁,祛病延年已成为大家追求的目标。现代医学研究证实,中药当归具有防病、治病、延年益寿等多种功效,在食疗保健领域的应用相当广泛当归补血汤、当归生姜羊肉汤等都……2022LPL春季赛常规赛赛程正式公布揭幕战OMG对战TTIT之家12月31日消息,英雄联盟赛事官方微博,2022LPL春季赛常规赛赛程正式公布,17支蓄势待发的战队再次站在同一起跑线上,为银龙冠军奖杯冲刺,无畏竞巅峰!据介绍,……立秋过后是长高黄金期,多给孩子吃这10道菜,营养高长得快大家好,欢迎大家来到我的美食自媒体,我是美食领域创作者锦绣V山东:专注美食,让生活更有味。今天为大家带来了几道家常美食的做法,这几道美食也是深受大家的喜欢,而且是很常见的几道美……TES零封EDG晋级决赛,JDG锁定S12门票,资格赛赛程也前言:2022LPL夏季赛已经来到末端,败者组决赛也即将开始,最终获胜的一方将会和JDG会师决赛,而失利的一方夏季赛就会止步于此,不过对于TES来说影响不是很大,毕竟他们已经晋……强硬!曝上港正式通知奥斯卡别想转会,你哪里都不能去中超头号球星、上海海港队长奥斯卡与弗拉门戈的转会绯闻,已经落下帷幕,最终上海海港拒绝放奥斯卡离队,也让这位巴西球星梦碎。而根据知名足球网站goal的爆料,奥斯卡近日再度向上港递……所有人告诉你花几千护肤,没人讲好好洗脸卸妆对,嘴姐帮你省钱来了!花了好几年悟出来的清洁误区,不想阴沟里翻船的来【好好洗脸】1。谁告诉你可以十天半月不洗脸,皮肤会妈生好皮请火速取关他!除了敏感肌以及美容项目后……智能手表对心率变异性分析的作用以及如何监测II?上一篇,我们主要讲了HRV的含义和HRV分析对我们健康管理的重要性,这一篇我们就来着重讲一下,智能可穿戴是如何利用技术实现HRV监测并进行分析的。市面上专业的智能手表如Appl……建议中老年人上年纪后要忌嘴,要少吃3种食物,缺乏营养还伤身中年以后身体开始走下坡路,不能再像年轻时一样消耗自己,时刻都要注意身体的养护。其中不能忽略的就是三餐的饮食,年轻时大家工作忙碌,上年纪后肠胃或多或少都有点不舒服。因此适当忌嘴,……Prada让白背心再度成为时尚单品关注时尚的人应该早就知道,今年秋季有一款白菜价的时尚单品白色背心。Prada2022FWBottegaVeneta2022fallChlo2022fall……北京故宫博物院故宫位于北京市中心,现名故宫博物院,旧称紫禁城,始建于明朝永乐四年(1406),是明、清两朝的皇宫,历时14年建成经历两朝24个皇帝,至今已经有600多年的历史,占地面积达72……世锦赛最新积分榜!三大夺冠热门齐头并进!奥运会四强四连败出局2022年世界女排锦标赛结束了又一个比赛日争夺,三大夺冠热门意大利、塞尔维亚和美国女排齐头并进继续保持不败,意大利横扫肯尼亚豪取四连胜,塞尔维亚女排遭遇德国女排挑战,她们直落三……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网