quarkus学习、事务、获取请求信息、原生SQL

Quarkus学习

指令式与响应式

1.线程的问题
  1. 在传统的指令式方法中,框架分配一个线程来处理请求。因此,请求的整个处理都运行在这个工作线程上。这个模型的扩展性不太好。事实上,要处理多个并发请求,你需要多个线程。因此,应用程序的并发性受到线程数量的限制。此外,只要您的代码与远程服务交互,这些线程就会被阻塞。因此,这会导致资源的低效使用,因为您可能需要更多的线程,而每个线程在映射到OS线程时,在内存和CPU方面都有成本。
  2. 响应式模型依赖于非阻塞 I/O和不同的执行模型。非阻塞I/O提供了一种处理并发I/O的有效方法。最小数量的线程称为I/O线程,可以处理许多并发I/O。使用这样的模型,请求处理不会委托给工作线程,而是直接使用这些I/O线程。它节省了内存和CPU,因为不需要创建工作线程来处理请求。它还改善了并发性,因为它消除了对线程数量的限制。最后,它还改善了响应时间,因为它减少了线程开关的数量。
Uni<PanacheEntityBase> findById = Fruit.findById(id);
Uni<Fruit> findById2 = Fruit.<Fruit>findById(id);

Fruit 继承 PanacheEntityBase
指定返回类型为Fruit

quarkus中使用panache reactive工具使用原生sql查询

  1. 在实体类上使用注解@NamedNativeQueries
@NamedNativeQueries({
        @NamedNativeQuery(name = "Cat.findByName", query = "select * from cat where name = :name ", resultClass = Cat.class)
})
  1. 需要在repository中使用sessionFactory调用命名查询
@Inject
    Mutiny.SessionFactory sessionFactory;
    /**
     * 命名查询,使用原生SQL
     *
     * @param name 姓名
     * @return Uni<List<Cat>> 单项流
     */
    public Uni<List<Cat>> findCat(String name) {
        return sessionFactory.withSession(session -> session.createNamedQuery("Cat.findByName", Cat.class)
                .setParameter("name", name).getResultList());
    }
  1. 或者创建原生语句(此处使用文本块)
/**
     * 编写原生SQL语句
     *
     * @param id id
     * @return Uni<List < Cat>>
     */
    public Uni<List<Cat>> findByName(Long id) {
        return sessionFactory.withSession(session -> session.createNativeQuery(
                        """
                                SELECT c.*
                                FROM Cat c
                                join person p
                                on c.person_id=p.id
                                WHERE c.id = :id""", Cat.class)
                .setParameter("id", id).getResultList()
        );
    }

获取请求信息的问题

  • 使用@Context注入上下文对象
    @Context
    HttpServerRequest request;// 注意导包是 io.vertx.core.http.HttpServerRequest;而不是multy下的

    @Context
    UriInfo uriInfo;

    LOGGER.info("RequestMethod: " + request.method());
            LOGGER.info("URL: " + uriInfo.getPath());
            LOGGER.info("IP: " + request.remoteAddress());

事务例子

  • 事务已用Panache.WithTransaciton()开启,Uni的组合流会报错,不明原因。可转Multi后组合,但是不再是单项流了,另一种解决方法是使用transformToUni()进行转换,但会嵌套。
public Multi<Boolean> update(Account source, Account target) {
        Multi<Boolean> multi = sessionFactory.withSession((session) -> session.find(Account.class, source.id))
                .map(Objects::nonNull).toMulti();
        Multi<Boolean> multi1 = sessionFactory.withSession((session) -> session.find(Account.class, target.id))
                .map(Objects::nonNull).toMulti();


        return Multi.createBy().combining().streams(multi1, multi).asTuple().map(tuple -> tuple.getItem1() && tuple.getItem2());

    }

public static Uni<Boolean> transactionMoney(Account source, Account target) {

       Uni<Boolean> sourceSelect = findById(source.id)
               .map(Objects::nonNull);
       Uni<Boolean> targetSelect = findById(target.id)
               .map(Objects::nonNull);
       return sourceSelect.onItem().transformToUni(x ->
               x ? targetSelect : Uni.createFrom().item(false)
       ).onItem().transformToUni(flag -> {
           if (flag) {
               return update("set money=money-50 where id=?1", source.id).onItem().transformToUni(n -> {
                   if (n > 0) {
                       return update("set money=money+50 where id=?1", target.id).map(result -> result > 0);
                   }
                   return Uni.createFrom().item(false);
               });
           }
           return Uni.createFrom().item(() -> false);
       });

   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值