service.mdc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. ---
  2. description: 服务(Service)
  3. globs:
  4. ---
  5. # 服务(Service)
  6. 我们一般将业务逻辑写在`Service`层,`Controller`层只做参数校验、数据转换等操作,`Service`层做具体的业务逻辑处理。
  7. `cool-admin`对基本的`Service`进行封装;
  8. ## 重写 CRUD
  9. `Controller`的六个快速方法,`add`、`update`、`delete`、`info`、`list`、`page`,是通过调用一个通用的`BaseService`的方法实现,所以我们可以重写`Service`的方法来实现自己的业务逻辑。
  10. **示例**
  11. 重写 add 方法
  12. ```ts
  13. import { DemoGoodsEntity } from "./../entity/goods";
  14. import { Provide } from "@midwayjs/core";
  15. import { BaseService } from "@cool-midway/core";
  16. import { InjectEntityModel } from "@midwayjs/typeorm";
  17. import { Repository } from "typeorm";
  18. /**
  19. * 商品示例
  20. */
  21. @Provide()
  22. export class DemoGoodsService extends BaseService {
  23. @InjectEntityModel(DemoGoodsEntity)
  24. demoGoodsEntity: Repository<DemoGoodsEntity>;
  25. /**
  26. * 新增
  27. * @param param
  28. * @returns
  29. */
  30. async add(param: any) {
  31. // 调用原本的add,如果不需要可以不用这样写,完全按照自己的新增逻辑写
  32. const result = await super.add(param);
  33. // 你自己的业务逻辑
  34. return result;
  35. }
  36. }
  37. ```
  38. 记得在`Controller`上配置对应的`Service`才会使其生效
  39. ```ts
  40. import { DemoGoodsService } from "../../service/goods";
  41. import { DemoGoodsEntity } from "../../entity/goods";
  42. import { Body, Inject, Post, Provide } from "@midwayjs/core";
  43. import { CoolController, BaseController } from "@cool-midway/core";
  44. import { InjectEntityModel } from "@midwayjs/typeorm";
  45. import { Repository } from "typeorm";
  46. /**
  47. * 测试
  48. */
  49. @Provide()
  50. @CoolController({
  51. api: ["add", "delete", "update", "info", "list", "page"],
  52. entity: DemoGoodsEntity,
  53. service: DemoGoodsService
  54. })
  55. export class AppDemoGoodsController extends BaseController {}
  56. ```
  57. ## 普通查询(TypeOrm)
  58. 普通查询基于[TypeOrm](mdc:https:/typeorm.io),点击查看官方详细文档
  59. **示例**
  60. ```ts
  61. import { DemoGoodsEntity } from "./../entity/goods";
  62. import { Provide } from "@midwayjs/core";
  63. import { BaseService } from "@cool-midway/core";
  64. import { InjectEntityModel } from "@midwayjs/typeorm";
  65. import { In, Repository } from "typeorm";
  66. /**
  67. * 商品示例
  68. */
  69. @Provide()
  70. export class DemoGoodsService extends BaseService {
  71. @InjectEntityModel(DemoGoodsEntity)
  72. demoGoodsEntity: Repository<DemoGoodsEntity>;
  73. async typeorm() {
  74. // 新增单个,传入的参数字段在数据库中一定要存在
  75. await this.demoGoodsEntity.insert({ title: "xxx" });
  76. // 新增单个,传入的参数字段在数据库中可以不存在
  77. await this.demoGoodsEntity.save({ title: "xxx" });
  78. // 新增多个
  79. await this.demoGoodsEntity.save([{ title: "xxx" }]);
  80. // 查找单个
  81. await this.demoGoodsEntity.findOneBy({ id: 1 });
  82. // 查找多个
  83. await this.demoGoodsEntity.findBy({ id: In([1, 2]) });
  84. // 删除单个
  85. await this.demoGoodsEntity.delete(1);
  86. // 删除多个
  87. await this.demoGoodsEntity.delete([1]);
  88. // 根据ID更新
  89. await this.demoGoodsEntity.update(1, { title: "xxx" });
  90. // 根据条件更新
  91. await this.demoGoodsEntity.update({ price: 20 }, { title: "xxx" });
  92. // 多条件操作
  93. await this.demoGoodsEntity
  94. .createQueryBuilder()
  95. .where("id = :id", { id: 1 })
  96. .andWhere("price = :price", { price: 20 })
  97. .getOne();
  98. }
  99. }
  100. ```
  101. ## 高级查询(SQL)
  102. **1、普通 SQL 查询**
  103. ```ts
  104. import { DemoGoodsEntity } from "./../entity/goods";
  105. import { Provide } from "@midwayjs/core";
  106. import { BaseService } from "@cool-midway/core";
  107. import { InjectEntityModel } from "@midwayjs/typeorm";
  108. import { Repository } from "typeorm";
  109. /**
  110. * 商品示例
  111. */
  112. @Provide()
  113. export class DemoGoodsService extends BaseService {
  114. @InjectEntityModel(DemoGoodsEntity)
  115. demoGoodsEntity: Repository<DemoGoodsEntity>;
  116. /**
  117. * 执行sql
  118. */
  119. async sql(query) {
  120. return this.nativeQuery("select * from demo_goods a where a.id = ?", [query.id]);
  121. }
  122. }
  123. ```
  124. **2、分页 SQL 查询**
  125. ```ts
  126. import { DemoGoodsEntity } from "./../entity/goods";
  127. import { Provide } from "@midwayjs/core";
  128. import { BaseService } from "@cool-midway/core";
  129. import { InjectEntityModel } from "@midwayjs/typeorm";
  130. import { Repository } from "typeorm";
  131. /**
  132. * 商品示例
  133. */
  134. @Provide()
  135. export class DemoGoodsService extends BaseService {
  136. @InjectEntityModel(DemoGoodsEntity)
  137. demoGoodsEntity: Repository<DemoGoodsEntity>;
  138. /**
  139. * 执行分页sql
  140. */
  141. async sqlPage(query) {
  142. return this.sqlRenderPage("select * from demo_goods ORDER BY id ASC", query, false);
  143. }
  144. }
  145. ```
  146. **3、非 SQL 的分页查询**
  147. ```ts
  148. import { DemoGoodsEntity } from "./../entity/goods";
  149. import { Provide } from "@midwayjs/core";
  150. import { BaseService } from "@cool-midway/core";
  151. import { InjectEntityModel } from "@midwayjs/typeorm";
  152. import { In, Repository } from "typeorm";
  153. /**
  154. * 商品示例
  155. */
  156. @Provide()
  157. export class DemoGoodsService extends BaseService {
  158. @InjectEntityModel(DemoGoodsEntity)
  159. demoGoodsEntity: Repository<DemoGoodsEntity>;
  160. /**
  161. * 执行entity分页
  162. */
  163. async entityPage(query) {
  164. const find = this.demoGoodsEntity.createQueryBuilder();
  165. find.where("id = :id", { id: 1 });
  166. return this.entityRenderPage(find, query);
  167. }
  168. }
  169. ```
  170. **4、SQL 动态条件**
  171. 分页查询和普通的 SQL 查询都支持动态条件,通过`this.setSql(条件,sql语句,参数)`来配置
  172. ```ts
  173. import { DemoGoodsEntity } from "./../entity/goods";
  174. import { Provide } from "@midwayjs/core";
  175. import { BaseService } from "@cool-midway/core";
  176. import { InjectEntityModel } from "@midwayjs/typeorm";
  177. import { Repository } from "typeorm";
  178. /**
  179. * 商品示例
  180. */
  181. @Provide()
  182. export class DemoGoodsService extends BaseService {
  183. @InjectEntityModel(DemoGoodsEntity)
  184. demoGoodsEntity: Repository<DemoGoodsEntity>;
  185. /**
  186. * 执行sql
  187. */
  188. async sql(query) {
  189. return this.nativeQuery(`
  190. select * from demo_goods a
  191. WHERE 1=1
  192. ${this.setSql(query.id, "and a.id = ?", [query.id])}
  193. ORDER BY id ASC
  194. `);
  195. }
  196. }
  197. ```
  198. ## 修改之前(modifyBefore)
  199. 有时候我们需要在数据进行修改动作之前,对它进行一些处理,比如:修改密码时,需要对密码进行加密,这时候我们可以使用`modifyBefore`方法来实现
  200. ```ts
  201. import { DemoGoodsEntity } from "./../entity/goods";
  202. import { Provide } from "@midwayjs/core";
  203. import { BaseService } from "@cool-midway/core";
  204. import { InjectEntityModel } from "@midwayjs/typeorm";
  205. import { Repository } from "typeorm";
  206. import * as md5 from "md5";
  207. /**
  208. * 商品示例
  209. */
  210. @Provide()
  211. export class DemoGoodsService extends BaseService {
  212. @InjectEntityModel(DemoGoodsEntity)
  213. demoGoodsEntity: Repository<DemoGoodsEntity>;
  214. /**
  215. * 修改之前
  216. * @param data
  217. * @param type
  218. */
  219. async modifyBefore(data: any, type: "delete" | "update" | "add") {
  220. if (type == "update") {
  221. data.password = md5(data.password);
  222. }
  223. }
  224. }
  225. ```
  226. ## 修改之后(modifyAfter)
  227. 有时候我们需要在数据进行修改动作之后,对它进行一些处理,比如:修改完数据之后将它放入队列或者 ElasticSearch
  228. ```ts
  229. import { DemoGoodsEntity } from "./../entity/goods";
  230. import { Provide } from "@midwayjs/core";
  231. import { BaseService } from "@cool-midway/core";
  232. import { InjectEntityModel } from "@midwayjs/typeorm";
  233. import { Repository } from "typeorm";
  234. import * as md5 from "md5";
  235. /**
  236. * 商品示例
  237. */
  238. @Provide()
  239. export class DemoGoodsService extends BaseService {
  240. @InjectEntityModel(DemoGoodsEntity)
  241. demoGoodsEntity: Repository<DemoGoodsEntity>;
  242. /**
  243. * 修改之后
  244. * @param data
  245. * @param type
  246. */
  247. async modifyAfter(data: any, type: "delete" | "update" | "add") {
  248. // 你想做的其他事情
  249. }
  250. }
  251. ```
  252. ## 设置实体
  253. `Service`与`Service`之间相互调用`BaseService`里的方法,有可能出现“未设置操作实体”的问题可以通过以下方式设置实体
  254. ::: warning 建议
  255. 但是一般不建议这样做,因为这样会导致`Service`与`Service`耦合,不利于代码的维护,如果要操作对应的表直接在当前的`Service`注入对应的表操作即可
  256. :::
  257. ```ts
  258. @Provide()
  259. export class XxxService extends BaseService {
  260. @InjectEntityModel(XxxEntity)
  261. xxxEntity: Repository<XxxEntity>;
  262. @Init()
  263. async init() {
  264. await super.init();
  265. // 设置实体
  266. this.setEntity(this.xxxEntity);
  267. }
  268. }
  269. ```