sql server 数据库向java接口推送数据

6 篇文章 1 订阅
2 篇文章 0 订阅

 

 


因为以前从未用数据库向java接口推送数据,所以为了实现这个demo我是一步一个脚印的踩坑啊!!!

此文章的作用以及应用场景:利用数据库主动推送数据,实现前端页面数据实时更新,替换ajax轮询机制。推送的依据是,只要数据库指定的表中数据增加有了变化,数据库会触发触发器然后通过存储过程调用消息推送接口

 

代码如下:....

     

----------------------------触发器---------------------------------------
USE [devRep]
GO
/****** Object:  Trigger [dbo].[tr_sm_demo]    Script Date: 2019/9/26 14:06:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================


-- Description:	<Insert触发器>
-- =============================================
create TRIGGER [dbo].[tr_sm_demo] 
 
ON [dbo].[demo] 
 
AFTER insert
 
AS 
BEGIN
	declare @id int
 
	set @id = (select id from demo where id=@id)  --如不指定条件查询  会出现 子查询返回的不是一个参数 !<> >>?  乱七八糟的一个错误  就是这里返回必须是一个数据
 
	exec proc_useJPushAPI @id --调用存储过程并传参 如果传入的参数未变则不会触发
 
	SET NOCOUNT ON;
END
----------------------------存储过程--------------------------------

USE [devRep]
GO
/****** Object:  StoredProcedure [dbo].[proc_useJPushAPI]    Script Date: 2019/9/26 13:56:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================

-- Description:	<调用消息推送接口>
-- =============================================
CREATE procedure [dbo].[proc_useJPushAPI]
	@id varchar(20)		--demo表的id字段
AS
BEGIN
	--创建存储过程里的参数
	declare @url varchar(4000)	--接口路由
	declare @object int			--OLE对象实例
	declare @responseText varchar(4000) --文本
	declare @name varchar(20)
    select @name=name from demo;  --查询demo表为接口传递参数
	set @url = 'http://127.0.0.1:8080/site/recedata?name='+@name ;
	
	print @url
 
	exec sp_OACreate'MSXML2.XMLHTTP',@object out
	exec sp_OAMethod @object,'open',null,'get',@url,'false'
	exec sp_OAMethod @object,'send'
	exec sp_OAMethod @object,'responseText',@responseText output
 
	print @responseText
 
	exec sp_OADestroy @object
 
	SET NOCOUNT ON;
 
END
//接收java接口代码 
@RequestMapping(value = "/recedata")
    public String recedata( String name) {
        try {
            System.out.println("sql server 访问啦---");
            return "HELLO";
        } catch (Exception e) {
            logger.info(e.getMessage(),e);
        }
        return null;
    }

 

第二种写法

create table A(keyId int,info1 varchar(20))
go
insert into A values(1,'a')
insert into A values(2,'b')
insert into A values(3,'C')
insert into A values(4,'d')
insert into A values(5,'e')
insert into A values(6,'f')
go
create trigger tr_a_test on a
after update 
as
begin
 declare @keyId_old int ,@info1_old varchar(20)
 declare @keyId_new int ,@info1_new varchar(20)
  
  ---获取修改前的值
  select @keyId_old=keyId,@info1_old =info1 from deleted  
  ---获取修改后的值
  select @keyId_new=keyId,@info1_new =info1 from inserted    
  ----打印获取的相关值   
   print '-------修改前的值------'   
   print @keyId_old
   print @info1_old   
   print '-------修改后的值------'
   print @keyId_new
   print @info1_new   
end
go

update A set info1='testwwwtwt',keyId=108 where keyId =2 
go
drop trigger  tr_a_test
go
truncate table A
drop table A 
go

 

mybatis

 

 create TRIGGER ${triggerName}

        ON ${tableName}

        AFTER INSERT ,UPDATE ,DELETE

        AS
        BEGIN

       declare @id varchar(11)
       declare @url varchar(255)
       declare @object int
       declare @responseText varchar(255)
 --删除
    if(not exists(select 1 from inserted) and exists(select 1 from deleted))

          select @id=${titleId} from deleted
    ELSE
    ---获取修改后的值
      select @id=${titleId} from inserted
      print @id
        set @url = 'http://${urlApi}/${controUrl}?id='+@id;
        print @url


    Exec sp_OACreate 'Msxml2.ServerXMLHTTP.3.0', @Object OUT;
    exec sp_OAMethod @object,'open',null,'get',@url,'false'

    exec sp_OAMethod @object,'send'
    exec sp_OAMethod @object,'responseText',@responseText output

    Exec sp_OADestroy @Object
    EXEC sp_OAGetErrorInfo @Object --异常输出

END;

现在只要在数据库执行这个sql into demo (name) values  ('你真的很棒啊'); 就可以访问接口

这里有个坑啊     如果你的表名是demo,接收java接口的@RequestMapping 里也是叫demo, 那么无论你在怎么增加  它都不会跑到这个方法

嗨!出错了嘛? 看这

SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问

借鉴博客:

http://www.manongjc.com/article/44753.html

https://www.jianshu.com/p/244c3cc30123

https://www.cnblogs.com/tohen/p/4265263.html

https://www.cnblogs.com/lflyq/archive/2016/11/15/6065160.html

做个记录...

用数据库推送 websocket接收渲染前端页面应该是  万瑞古德!

 

-----------------补存-------2020年12月9日11:20:40

之前写的触发器向指定接口传数据,只是写了一个demo,并没有真正使用,后续使用遇到一些问题,做一些记录

问题:

使用mybatis创建触发器和存储过程后,在数据库里添加demo表中的数据,由于传的参数是id,在接口里查询当前参数id的值,结果mybatis查询走到mapper层就卡死了,当前百思不得其解,以为是程序写的有问题。经过不断的摸索和实验最后发现当在数据库中添加

一条数据时触发器立马请求存储过程中的http接口,然后接口根据id查询最新的数据,为啥会卡死呢?原因就是触发器之前,这个事务并未结束,insert并没有真正的添加到数据库中,所以导致一系列问题.

解决:

我的解决思路很简单,上代码

 new Thread(() -> {
                try {
                    //放到多线程中等待1-2秒,等他的事务完事后在查询
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
              
            }).start();

如有问题,请指出

 

DECLARE @Object int; DECLARE @HR int; DECLARE @Property nvarchar(255); DECLARE @Return nvarchar(255); DECLARE @Source nvarchar(255), @Desc nvarchar(255); DECLARE @httpStatus int; DECLARE @response varchar(8000); --创建 OLE 对象的实例 EXEC @HR = sp_OACreate N'MSXML2.XMLHTTP.6.0',@Object OUT; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('Error Creating COM Component 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO END_ROUTINE END BEGIN --Open EXEC @HR = sp_OAMethod @Object,N'open',Null,'GET','http://localhost:1728/HttpServer/submit.aspx',FALSE; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('Open 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO CLEANUP END --setRequestHeader EXEC @HR = sp_OAMethod @Object,N'setRequestHeader',Null,'Content-Type','text/xml'; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('setRequestHeader 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO CLEANUP END --send EXEC @HR = sp_OAMethod @Object,N'send',Null,''; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('send 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO CLEANUP END --readyState EXEC @HR = sp_OAGetProperty @Object,'readyState', @httpStatus OUT; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('readyState 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO CLEANUP END --verify status IF @httpStatus 4 BEGIN RAISERROR('readyState http status bad', 16,1) GOTO CLEANUP END --status EXEC @HR = sp_OAGetProperty @Object,'status', @httpStatus OUT; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('getstatus 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO CLEANUP END --verify status IF @httpStatus 200 BEGIN Print Cast(@httpStatus As varchar) RAISERROR('Open http status bad', 16,1) GOTO CLEANUP END --responseText EXEC @HR = sp_OAGetProperty @Object, 'responseText', @response OUT IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; RAISERROR('responseText 0x%x, %s, %s',16,1, @HR, @Source, @Desc) GOTO CLEANUP END Print @response END CLEANUP: BEGIN EXEC @HR = sp_OADestroy @Object; IF @HR 0 BEGIN EXEC sp_OAGetErrorInfo @Object,@Source OUT,@Desc OUT; SELECT HR = convert(varbinary(4),@HR),Source=@Source,Description=@Desc; END END END_ROUTINE: RETURN; GO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值