如何在愤怒中检入DB表的ip地址?

时间:2017-01-27 08:38:03

标签: java sql oracle

我有实体

public class CrmActionLogIp implements Serializable {
    @Id
    private long id;
    @Column(name = "ip_start")
    private String ipStart;
    @Column(name = "ip_end")
    private String ipEnd;
    @Column(name = "office_name")
    private String officeName;

我保存ip ti这个表。 如果officeName有1个ip地址,我保存ipStart = ipEnd 如果officeName的范围是ips,我保存ipStart = range start和ipEnd = range end。例如:

id   ipStart       ipEnd          officeName
0    127.0.0.1     127.0.0.1      local office
1    129.127.0.0   129.127.0.12   test office
2    132.127.0.11   132.127.0.22   test office2

如何通过ip从DB获取officeName?对于exaple,我129.127.0.5介于129.127.0.0 AND 129.127.0.12之间,所以我得到officeName = test office。

2 个答案:

答案 0 :(得分:0)

我建议添加两个额外的列,即ipStartNumipEndNum,您可以将ip字符串值转换为数字,例如,使用以下公式(此公式已采用来自this SO answer,如果有帮助,请提出投票。然后,当根据特定的ip搜索办公室时,将此ip转换为这样的数字并执行BETWEEN查询:

CREATE TABLE actionlog
    ("id" int, "ipStart" varchar2(12), "ipEnd" varchar2(12), "officeName" varchar2(12), "ipStartNum" number, "ipEndNum" number)
\\

INSERT ALL 
    INTO actionlog ("id", "ipStart", "ipEnd", "officeName")
         VALUES (0, '127.0.0.1', '127.0.0.1', 'local office')
    INTO actionlog ("id", "ipStart", "ipEnd", "officeName")
         VALUES (1, '129.127.0.0', '129.127.0.12', 'test office')
    INTO actionlog ("id", "ipStart", "ipEnd", "officeName")
         VALUES (2, '132.127.0.11', '132.127.0.22', 'test office2')
SELECT * FROM dual
\\

update actionlog set "ipStartNum" = to_number(regexp_substr("ipStart", '\d+', 1, 1)) * 16777216 +
           to_number(regexp_substr("ipStart", '\d+', 1, 2)) * 65536 +
           to_number(regexp_substr("ipStart", '\d+', 1, 3)) * 256 +
           to_number(regexp_substr("ipStart", '\d+', 1, 4))
\\

update actionlog set "ipEndNum" = to_number(regexp_substr("ipEnd", '\d+', 1, 1)) * 16777216 +
           to_number(regexp_substr("ipEnd", '\d+', 1, 2)) * 65536 +
           to_number(regexp_substr("ipEnd", '\d+', 1, 3)) * 256 +
           to_number(regexp_substr("ipEnd", '\d+', 1, 4))
\\

select * from actionlog
where to_number(regexp_substr('129.127.0.5', '\d+', 1, 1)) * 16777216 +
           to_number(regexp_substr('129.127.0.5', '\d+', 1, 2)) * 65536 +
           to_number(regexp_substr('129.127.0.5', '\d+', 1, 3)) * 256 +
           to_number(regexp_substr('129.127.0.5', '\d+', 1, 4)) between "ipStartNum" and "ipEndNum"
\\

注意:为了使ipStartNumipEndNum的值保持最新,您可以使用计算列,触发器或基于Java应用程序的逻辑。请参阅以下计算列中的解决方案:

CREATE TABLE actionlog
    ("id" int, "ipStart" varchar2(12), "ipEnd" varchar2(12), "officeName" varchar2(12),
     "ipStartNum"  as (to_number(regexp_substr("ipStart", '\d+', 1, 1)) * 16777216 +
           to_number(regexp_substr("ipStart", '\d+', 1, 2)) * 65536 +
           to_number(regexp_substr("ipStart", '\d+', 1, 3)) * 256 +
           to_number(regexp_substr("ipStart", '\d+', 1, 4))),
     "ipEndNum" as (to_number(regexp_substr("ipEnd", '\d+', 1, 1)) * 16777216 +
           to_number(regexp_substr("ipEnd", '\d+', 1, 2)) * 65536 +
           to_number(regexp_substr("ipEnd", '\d+', 1, 3)) * 256 +
           to_number(regexp_substr("ipEnd", '\d+', 1, 4))))

答案 1 :(得分:0)

我写这个util方法

public static long ipToLong(String ip) {
        String[] addrArray = ip.split("\\.");

        long ipDecimal = 0;

        for (int i = 0; i < addrArray.length; i++) {

            int power = 3 - i;
            ipDecimal += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power)));
        }
        return ipDecimal;
    }

并保存4列ipStart ipEnd ipStartLond ipEndLog