• IP基础知识与分配实现


    一、IP寻址

    1.划分网络ID和主机ID的最初方案是使用地址分类。

    2.A类:0.0.0.0-127.255.255.255

    B类:128.0.0.0-191.255.255.255

    C类:192.0.0.0-223.255.255.255

    D类:224.0.0.0-239.255.255.255

    E类:240.0.0.0-247.255.255.255

    二、子网

    1.子网划分可以利用IP地址系统把物理网络分解为更小的逻辑实体——子网。

    2.子网的概念最早源自于地址分类系统,而且在ABC类地址中能够得到很好的展现。然而硬件厂商和internet社区建立了一种解析地址的新系统,名为无类别域间路由(CIDR),它不需要关心地址类别。

    192.168.1.0/24,它指的是IP地址是192.168.1.0,子网掩码中1的个数是24个,即255.255.255.0,二进制显示为11111111 11111111 11111111 00000000,很容易看出这个就是一个C类的网络,最后的八个0可以随意组合,取值范围为0-255。

    同理192.168.1.0/29,指的是IP地址是192.168.1.0,子网掩码中1的个数是24个,即255.255.255.248,二进制显示为11111111 11111111 11111111 11111000,可用IP地址个数有8个,

    一般首尾IP地址为特殊地址,不在实际中使用。

    三、代码实现

    以下提供两个在/24子网池下划分更小的子网(24< x < 32)和在/16子网池下划分更小的子网(16< x < 24)的实现类。注意:其中去掉了主要的业务逻辑代码,仅提供了IP分配的算法实现。因为需要启用的IP地址比较多,使用了源生的JDBC事务来提高执行效率。备注:此处使用的springCloud框架,底层实现仅供参考。

    3.1、基础PO

      1 package com.ccb.cloud.nw.ip.data.entity;
      2 // default package
      3 
      4 import javax.persistence.Column;
      5 import javax.persistence.Entity;
      6 import javax.persistence.Id;
      7 import javax.persistence.Table;
      8 import javax.persistence.Transient;
      9 
     10 
     11 
     12 /**
     13  * NwCclassPo entity. @author MyEclipse Persistence Tools
     14  */
     15 @Entity
     16 @Table(name="RM_NW_CCLASS")
     17 
     18 public class NwCclassPo  implements java.io.Serializable {
     19 
     20 
     21     // Fields    
     22 
     23      private Long cclassId;
     24      private Long bclassId;
     25      private String cclassTypeCode;
     26      private String secureAreaCode;
     27      private String cclassName;
     28      private String subnetmask;
     29      private String gateway;
     30      private Long vlanId;
     31      private String isActive;
     32      private String secureTierCode;
     33      private Integer aclassIp;
     34      private Integer bclassIp;
     35      private Integer cclassIp;
     36      private Integer ipStart;
     37      private Integer ipEnd;
     38      
     39      private Integer ipTotalCnt;
     40      private Integer ipAvailCnt;
     41      
     42      private Long datacenterId;
     43      private Long moduleId;
     44      private Long vmManagerServerId;
     45      private Long convergeId;
     46      private String routersId;
     47      
     48      @Transient
     49      private Integer useIpNum;
     50      @Transient
     51      private Integer unUseIpNum;
     52      @Transient
     53      private Long resPoolId;
     54      @Transient
     55      private String resPoolType;
     56      @Transient
     57      private String netArea;
     58 //     private RmNwSubnetmaskExtPo rmNwSubnetmaskExtPo;
     59 
     60     // Constructors
     61 
     62     /** default constructor */
     63     public NwCclassPo() {
     64     }
     65 
     66     /** minimal constructor */
     67     public NwCclassPo(Long cclassId, Long bclassId) {
     68         this.cclassId = cclassId;
     69         this.bclassId = bclassId;
     70     }
     71     
     72     /** full constructor */
     73     public NwCclassPo(Long cclassId, Long bclassId, String cclassTypeCode, String secureAreaCode, String cclassName, 
     74             String subnetmask, String gateway, Long vlanId, String isActive, String secureTierCode, Integer aclassIp, 
     75             Integer bclassIp, Integer cclassIp, Integer ipStart, Integer ipEnd,Integer ipTotalCnt,Integer ipAvailCnt,Long datacenterId) {
     76         this.cclassId = cclassId;
     77         this.bclassId = bclassId;
     78         this.cclassTypeCode = cclassTypeCode;
     79         this.secureAreaCode = secureAreaCode;
     80         this.cclassName = cclassName;
     81         this.subnetmask = subnetmask;
     82         this.gateway = gateway;
     83         this.vlanId = vlanId;
     84         this.isActive = isActive;
     85         this.secureTierCode = secureTierCode;
     86         this.aclassIp = aclassIp;
     87         this.bclassIp = bclassIp;
     88         this.cclassIp = cclassIp;
     89         this.ipStart = ipStart;
     90         this.ipEnd = ipEnd;
     91         
     92         this.ipTotalCnt=ipTotalCnt;
     93         this.ipAvailCnt=ipAvailCnt;
     94         this.datacenterId=datacenterId;
     95     }
     96 
     97    
     98     // Property accessors
     99     @Id 
    100     
    101     @Column(name="CCLASS_ID", unique=true, nullable=false, precision=18, scale=0)
    102 
    103     public Long getCclassId() {
    104         return this.cclassId;
    105     }
    106     
    107     public void setCclassId(Long cclassId) {
    108         this.cclassId = cclassId;
    109     }
    110        
    111     @Column(name = "VCENTER_ID", nullable =true, precision = 18, scale = 0)
    112     public Long getVmManagerServerId() {
    113         return vmManagerServerId;
    114     }
    115 
    116     public void setVmManagerServerId(Long vmManagerServerId) {
    117         this.vmManagerServerId = vmManagerServerId;
    118     }
    119 
    120     @Column(name = "MODULE_ID", nullable =true, precision = 18, scale = 0)
    121     public Long getModuleId() {
    122         return moduleId;
    123     }
    124 
    125     public void setModuleId(Long moduleId) {
    126         this.moduleId = moduleId;
    127     }
    128     
    129     @Column(name="BCLASS_ID", nullable=false, precision=18, scale=0)
    130 
    131     public Long getBclassId() {
    132         return this.bclassId;
    133     }
    134     
    135     public void setBclassId(Long bclassId) {
    136         this.bclassId = bclassId;
    137     }
    138     
    139     @Column(name="CCLASS_TYPE_CODE", length=32)
    140 
    141     public String getCclassTypeCode() {
    142         return this.cclassTypeCode;
    143     }
    144     
    145     public void setCclassTypeCode(String cclassTypeCode) {
    146         this.cclassTypeCode = cclassTypeCode;
    147     }
    148     
    149     @Column(name="SECURE_AREA_CODE", length=32)
    150 
    151     public String getSecureAreaCode() {
    152         return this.secureAreaCode;
    153     }
    154     
    155     public void setSecureAreaCode(String secureAreaCode) {
    156         this.secureAreaCode = secureAreaCode;
    157     }
    158     
    159     @Column(name="CCLASS_NAME", length=100)
    160 
    161     public String getCclassName() {
    162         return this.cclassName;
    163     }
    164     
    165     public void setCclassName(String cclassName) {
    166         this.cclassName = cclassName;
    167     }
    168     
    169     @Column(name="SUBNETMASK", length=20)
    170 
    171     public String getSubnetmask() {
    172         return this.subnetmask;
    173     }
    174     
    175     public void setSubnetmask(String subnetmask) {
    176         this.subnetmask = subnetmask;
    177     }
    178     
    179     @Column(name="GATEWAY", length=20)
    180 
    181     public String getGateway() {
    182         return this.gateway;
    183     }
    184     
    185     public void setGateway(String gateway) {
    186         this.gateway = gateway;
    187     }
    188     
    189     @Column(name="VLAN_ID", precision=18, scale=0)
    190 
    191     public Long getVlanId() {
    192         return this.vlanId;
    193     }
    194     
    195     public void setVlanId(Long vlanId) {
    196         this.vlanId = vlanId;
    197     }
    198     
    199     @Column(name="IS_ACTIVE", length=1)
    200 
    201     public String getIsActive() {
    202         return this.isActive;
    203     }
    204     
    205     public void setIsActive(String isActive) {
    206         this.isActive = isActive;
    207     }
    208     
    209     @Column(name="SECURE_TIER_CODE", length=32)
    210 
    211     public String getSecureTierCode() {
    212         return this.secureTierCode;
    213     }
    214     
    215     public void setSecureTierCode(String secureTierCode) {
    216         this.secureTierCode = secureTierCode;
    217     }
    218     
    219     @Column(name="ACLASS_IP", precision=3, scale=0)
    220 
    221     public Integer getAclassIp() {
    222         return this.aclassIp;
    223     }
    224     
    225     public void setAclassIp(Integer aclassIp) {
    226         this.aclassIp = aclassIp;
    227     }
    228     
    229     @Column(name="BCLASS_IP", precision=3, scale=0)
    230 
    231     public Integer getBclassIp() {
    232         return this.bclassIp;
    233     }
    234     
    235     public void setBclassIp(Integer bclassIp) {
    236         this.bclassIp = bclassIp;
    237     }
    238     
    239     @Column(name="CCLASS_IP", precision=3, scale=0)
    240 
    241     public Integer getCclassIp() {
    242         return this.cclassIp;
    243     }
    244     
    245     public void setCclassIp(Integer cclassIp) {
    246         this.cclassIp = cclassIp;
    247     }
    248     
    249     @Column(name="IP_START", precision=3, scale=0)
    250 
    251     public Integer getIpStart() {
    252         return this.ipStart;
    253     }
    254     
    255     public void setIpStart(Integer ipStart) {
    256         this.ipStart = ipStart;
    257     }
    258     
    259     @Column(name="IP_END", precision=3, scale=0)
    260 
    261     public Integer getIpEnd() {
    262         return this.ipEnd;
    263     }
    264     
    265     public void setIpEnd(Integer ipEnd) {
    266         this.ipEnd = ipEnd;
    267     }
    268     
    269     //
    270     @Column(name="IP_TOTAL_CNT", precision=3, scale=0)
    271 
    272     public Integer getIpTotalCnt() {
    273         return this.ipTotalCnt;
    274     }
    275     
    276     public void setIpTotalCnt(Integer ipTotalCnt) {
    277         this.ipTotalCnt = ipTotalCnt;
    278     }
    279    
    280     @Column(name="IP_AVAIL_CNT", precision=3, scale=0)
    281 
    282     public Integer getIpAvailCnt() {
    283         return this.ipAvailCnt;
    284     }
    285 
    286     public void setIpAvailCnt(Integer ipAvailCnt) {
    287         this.ipAvailCnt = ipAvailCnt;
    288     }
    289     @Column(name = "DATACENTER_ID",length=18)
    290     public Long getDatacenterId() {
    291         return datacenterId;
    292     }
    293 
    294     public void setDatacenterId(Long datacenterId) {
    295         this.datacenterId = datacenterId;
    296     }
    297     @Column(name = "CONVERGE_ID", nullable =true, precision = 18, scale = 0)
    298     public Long getConvergeId() {
    299         return convergeId;
    300     }
    301 
    302     public void setConvergeId(Long convergeId) {
    303         this.convergeId = convergeId;
    304     }
    305 
    306     @Column(name="ROUTERS_ID", length=36)
    307     public String getRoutersId() {
    308         return routersId;
    309     }
    310 
    311     public void setRoutersId(String routersId) {
    312         this.routersId = routersId;
    313     }
    314 
    315     @Transient
    316     public Integer getUseIpNum() {
    317         return useIpNum;
    318     }
    319 
    320     public void setUseIpNum(Integer useIpNum) {
    321         this.useIpNum = useIpNum;
    322     }
    323 
    324     @Transient
    325     public Integer getUnUseIpNum() {
    326         return unUseIpNum;
    327     }
    328 
    329     public void setUnUseIpNum(Integer unUseIpNum) {
    330         this.unUseIpNum = unUseIpNum;
    331     }
    332 
    333     @Transient
    334     public Long getResPoolId() {
    335         return resPoolId;
    336     }
    337 
    338     public void setResPoolId(Long resPoolId) {
    339         this.resPoolId = resPoolId;
    340     }
    341 
    342     @Transient
    343     public String getResPoolType() {
    344         return resPoolType;
    345     }
    346 
    347     public void setResPoolType(String resPoolType) {
    348         this.resPoolType = resPoolType;
    349     }
    350 
    351     @Transient
    352     public String getNetArea() {
    353         return netArea;
    354     }
    355 
    356     public void setNetArea(String netArea) {
    357         this.netArea = netArea;
    358     }
    359     
    360     
    361 }
    NwCclassPo
      1 package com.ccb.cloud.nw.ip.data.entity;
      2 
      3 import java.io.Serializable;
      4 import javax.persistence.*;
      5 import java.util.Date;
      6 
      7 
      8 /**
      9  * The persistent class for the RM_CDP_IP_ADDRESS database table.
     10  * 
     11  */
     12 @Entity
     13 @Table(name="RM_CDP_IP_ADDRESS")
     14 public class RmCdpIpAddressPo implements Serializable {
     15     private static final long serialVersionUID = 1L;
     16 
     17     @Id
     18     private String ip;
     19 
     20     @Column(name="ALLOCED_STATUS_CODE")
     21     private String allocedStatusCode;
     22 
     23     @Temporal(TemporalType.DATE)
     24     @Column(name="ALLOCED_TIME")
     25     private Date allocedTime;
     26 
     27     @Column(name="APP_DU_ID")
     28     private Long appDuId;
     29 
     30     @Column(name="CCLASS_ID")
     31     private Long cclassId;
     32 
     33     @Column(name="DEVICE_ID")
     34     private Long deviceId;
     35 
     36     @Column(name="IP_TYPE_ID")
     37     private String ipTypeId;
     38 
     39     private String remark;
     40 
     41     @Column(name="RES_CDP_ID")
     42     private Long resCdpId;
     43 
     44     @Column(name="RES_CLUSTER_ID")
     45     private Long resClusterId;
     46 
     47     @Column(name="RES_POOL_ID")
     48     private Long resPoolId;
     49 
     50     private Integer seq;
     51 
     52     public RmCdpIpAddressPo() {
     53     }
     54 
     55     public String getIp() {
     56         return ip;
     57     }
     58 
     59     public void setIp(String ip) {
     60         this.ip = ip;
     61     }
     62 
     63     public String getAllocedStatusCode() {
     64         return allocedStatusCode;
     65     }
     66 
     67     public void setAllocedStatusCode(String allocedStatusCode) {
     68         this.allocedStatusCode = allocedStatusCode;
     69     }
     70 
     71     public Date getAllocedTime() {
     72         return allocedTime;
     73     }
     74 
     75     public void setAllocedTime(Date allocedTime) {
     76         this.allocedTime = allocedTime;
     77     }
     78 
     79     public Long getAppDuId() {
     80         return appDuId;
     81     }
     82 
     83     public void setAppDuId(Long appDuId) {
     84         this.appDuId = appDuId;
     85     }
     86 
     87     public Long getCclassId() {
     88         return cclassId;
     89     }
     90 
     91     public void setCclassId(Long cclassId) {
     92         this.cclassId = cclassId;
     93     }
     94 
     95     public Long getDeviceId() {
     96         return deviceId;
     97     }
     98 
     99     public void setDeviceId(Long deviceId) {
    100         this.deviceId = deviceId;
    101     }
    102 
    103     public String getIpTypeId() {
    104         return ipTypeId;
    105     }
    106 
    107     public void setIpTypeId(String ipTypeId) {
    108         this.ipTypeId = ipTypeId;
    109     }
    110 
    111     public String getRemark() {
    112         return remark;
    113     }
    114 
    115     public void setRemark(String remark) {
    116         this.remark = remark;
    117     }
    118 
    119     public Long getResCdpId() {
    120         return resCdpId;
    121     }
    122 
    123     public void setResCdpId(Long resCdpId) {
    124         this.resCdpId = resCdpId;
    125     }
    126 
    127     public Long getResClusterId() {
    128         return resClusterId;
    129     }
    130 
    131     public void setResClusterId(Long resClusterId) {
    132         this.resClusterId = resClusterId;
    133     }
    134 
    135     public Long getResPoolId() {
    136         return resPoolId;
    137     }
    138 
    139     public void setResPoolId(Long resPoolId) {
    140         this.resPoolId = resPoolId;
    141     }
    142 
    143     public Integer getSeq() {
    144         return seq;
    145     }
    146 
    147     public void setSeq(Integer seq) {
    148         this.seq = seq;
    149     }
    150 
    151     public RmCdpIpAddressPo(String ip, String allocedStatusCode, Date allocedTime, Long appDuId, Long cclassId,
    152             Long deviceId, String ipTypeId, String remark, Long resCdpId, Long resClusterId, Long resPoolId,
    153             Integer seq) {
    154         super();
    155         this.ip = ip;
    156         this.allocedStatusCode = allocedStatusCode;
    157         this.allocedTime = allocedTime;
    158         this.appDuId = appDuId;
    159         this.cclassId = cclassId;
    160         this.deviceId = deviceId;
    161         this.ipTypeId = ipTypeId;
    162         this.remark = remark;
    163         this.resCdpId = resCdpId;
    164         this.resClusterId = resClusterId;
    165         this.resPoolId = resPoolId;
    166         this.seq = seq;
    167     }
    168 
    169     
    170 
    171 }
    RmCdpIpAddressPo

    3.2 DAO仅提供SQL

    1 //获取名称对应的子网信息
    2     @Query(value="select * from rm_cdp_ip_address a where a.ip = :ip",nativeQuery=true)
    3     RmCdpIpAddressPo getIpInfoByIp(@Param("ip") String ip);
    4 
    5 //获取名称对应的子网信息
    6     @Query(value="SELECT t.cclass_id,t.bclass_id,t.cclass_type_code,t.secure_area_code,t.secure_tier_code,t.cclass_name,t.subnetmask,t.gateway,t.vlan_id," + 
    7             "t.ip_start,t.ip_end,t.aclass_ip,t.bclass_ip,t.cclass_ip,t.ip_total_cnt,t.ip_avail_cnt,t.is_active,t.datacenter_id,t.module_id,t.vcenter_id,t.converge_id,t.template_id,t.routers_id"
    8             + " FROM rm_nw_cclass t WHERE t.cclass_name=:cclassName ",nativeQuery=true)
    9     List<NwCclassPo> getBclassByName(@Param("cclassName") String cclassName);
    View Code

    3.3 Service实现

      1 package com.ccb.cloud.nw.ip.service;
      2 
      3 import java.sql.Connection;
      4 import java.sql.PreparedStatement;
      5 import java.sql.SQLException;
      6 import java.util.ArrayList;
      7 import java.util.Date;
      8 import java.util.List;
      9 import java.util.Map;
     10 
     11 import javax.sql.DataSource;
     12 
     13 import org.slf4j.Logger;
     14 import org.slf4j.LoggerFactory;
     15 import org.springframework.beans.factory.annotation.Autowired;
     16 import org.springframework.jdbc.core.BatchPreparedStatementSetter;
     17 import org.springframework.jdbc.core.JdbcTemplate;
     18 import org.springframework.jdbc.datasource.DataSourceUtils;
     19 import org.springframework.stereotype.Service;
     20 import org.springframework.transaction.annotation.Transactional;
     21 import org.springframework.transaction.support.TransactionSynchronizationManager;
     22 import org.springframework.web.client.RestTemplate;
     23 
     24 import com.ccb.cloud.common.data.DBSeqUtils;
     25 import com.ccb.cloud.common.exception.BizException;
     26 import com.ccb.cloud.common.service.BaseService;
     27 import com.ccb.cloud.common.util.ExDateUtils;
     28 import com.ccb.cloud.nw.ip.constants.IpFwConstants;
     29 import com.ccb.cloud.nw.ip.data.dao.RmCdpIpAddressDAO;
     30 import com.ccb.cloud.nw.ip.data.dao.RmNwCclassDAO;
     31 import com.ccb.cloud.nw.ip.data.entity.NwCclassPo;
     32 import com.ccb.cloud.nw.ip.data.entity.RmCdpIpAddressPo;
     33 import com.ccb.cloud.nw.ip.data.entity.RmNwCclassFreelistPo;
     34 import com.ccb.cloud.nw.ip.data.entity.RmNwSubnetmaskExtPo;
     35 /**
     36  * @author liuqiang.zh
     37  *@version 
     38  */
     39 @Service
     40 @Transactional(readOnly = true)
     41 public class Temp extends BaseService<NwCclassPo> {
     42     private final Logger logger = LoggerFactory.getLogger(this.getClass());
     43     
     44     @Autowired
     45     JdbcTemplate jdbcTemplate;
     46 
     47     @Autowired
     48     RestTemplate restTemplate;
     49     
     50     @Autowired
     51     private RmNwCclassDAO rmNwCclassDAO;
     52     
     53     @Autowired
     54     private RmCdpIpAddressDAO rmCdpIpAddressDAO;
     55 
     56     /**
     57      * 在/24子网池下批量新增按子网掩码和个数分配的子网表
     58      * 在子网表记录创建成功后批量新增ip地址表记录
     59      * @author liuqiang.zh 
     60      * @param paramBody
     61      */
     62     public String batchSaveSubCclassAndCclassField(Map<String, Object> paramBody) throws Exception{
     63         String result = "";
     64         long startTime = System.currentTimeMillis();
     65         //调用通用方法获取C段列表,遍历
     66         String cclassNameTemp = (String)paramBody.get("className");
     67         String[] cclassNameTempList = cclassNameTemp.split("/");
     68         String cclassName = cclassNameTempList[0];
     69         //子网池掩码
     70         String poolSubnetmaskStr = cclassNameTempList[1];
     71         Integer poolSubnetmask = 0;
     72         if(!"".equals(poolSubnetmaskStr)) {
     73             poolSubnetmask = Integer.parseInt(poolSubnetmaskStr);
     74         }
     75         
     76         if(poolSubnetmask < IpFwConstants.BMAXIPUNIT) {
     77             //调用B段启用方法
     78             return batchSaveSubCclassByBName(paramBody);
     79         }
     80         if("".equals(cclassName)) {
     81             throw new BizException("001", "未获取到传入的C段Ip");
     82         }
     83         String[] CIpNumberList = cclassName.split("\.");
     84         Integer aclassIp = Integer.parseInt(CIpNumberList[0]);
     85         Integer bclassIp = Integer.parseInt(CIpNumberList[1]);        
     86         Integer cclassIp = Integer.parseInt(CIpNumberList[2]);
     87         //获取子网掩码格式,判断?是否小于/24子网(24-32)
     88         Integer subNetMaskUnit  = 0;
     89         Object subnetmaskTempStr = paramBody.get("subnetmask");
     90         if(subnetmaskTempStr !=null && !"".equals(subnetmaskTempStr)) {
     91             subNetMaskUnit = Integer.parseInt(subnetmaskTempStr.toString());
     92         }
     93         if(subNetMaskUnit < IpFwConstants.BMAXIPUNIT || subNetMaskUnit >= IpFwConstants.MAXIPUNIT) {
     94             throw new BizException("001", "输入的子网掩码超出范围");
     95         }
     96         //获取子网个数,判断?当前C段剩余的按子网格式分配的子网个数是否大于选择的子网个数
     97         Integer subNumber  = 0;
     98         Object subNumberTempStr = paramBody.get("subNumber");
     99         if(subNumberTempStr !=null && !"".equals(subNumberTempStr)) {
    100             subNumber = Integer.parseInt(subNumberTempStr.toString());
    101         }
    102         
    103         //获取最小单元的位数
    104         int subUnit = IpFwConstants.MAXIPUNIT - subNetMaskUnit;
    105         //最小单元存放的IP个数
    106         int ipUnit = (int)Math.pow(IpFwConstants.BASICUNIT, subUnit);
    107         //默认值
    108         Long bclassId = 0L;
    109         List<NwCclassPo> rmNwCclassList = new ArrayList<>();
    110         //批量新增IP表记录
    111         List<RmCdpIpAddressPo> ipsList =new ArrayList<>();
    112         //若为0,重新开始生成子网,若不为0,取最后一条记录的网关,并将此IP +1作为起始的地址
    113         Integer startIp = 0;
    114         RmCdpIpAddressPo rmCdpIpAddressPoTemp = null;
    115         for(int i=0;i < IpFwConstants.MAXIPNUMBER/ipUnit;i++) {
    116             //当前的C段数字
    117             int curCIp = i*ipUnit+1;
    118             String subCclassName = aclassIp+"."+bclassIp+"."+cclassIp+"."+curCIp;
    119             //此处去IP表中查找当前掩码格式下第一个IP,是否存在?若不存在,则取当前起始IP
    120             rmCdpIpAddressPoTemp = rmCdpIpAddressDAO.getIpInfoByIp(subCclassName);
    121             
    122             if(rmCdpIpAddressPoTemp == null) {
    123                 startIp = i*ipUnit;
    124                 break;
    125             }
    126             if(i == IpFwConstants.MAXIPNUMBER/ipUnit-1) {
    127                 startIp = IpFwConstants.MAXIPNUMBER;
    128             }
    129         }
    130         
    131         //获取子网个数,判断?当前C段剩余的按子网格式分配的子网个数是否大于选择的子网个数
    132         int availNum = (int)(IpFwConstants.MAXIPNUMBER - startIp)/ipUnit;
    133         
    134         Date date = ExDateUtils.getCurrentDateTime();
    135         //判断已经生成的子网个数
    136         int count = 0;
    137         RmCdpIpAddressPo rmCdpIpAddressPoTest = null;
    138         if(subNumber <= availNum) {
    139             for(int i=0;i < availNum;i++) {
    140                 //首先需要判断IP是否超出256的最大范围
    141                 if((startIp+(i+1)*ipUnit) > IpFwConstants.MAXIPNUMBER) {
    142                     throw new BizException("001", "待启用的子网个数不满足选择需求");
    143                 }
    144                 if(subNumber == count) {
    145                     break;
    146                 }
    147                 //此处重新去IP表中查找第一个IP是否存在
    148                 String testCclassName = aclassIp+"."+bclassIp+"."+cclassIp+"."+(startIp+i*ipUnit+1);
    149                 rmCdpIpAddressPoTest = rmCdpIpAddressDAO.getIpInfoByIp(testCclassName);
    150                 if(rmCdpIpAddressPoTest == null) {
    151                     NwCclassPo cclassPo = new NwCclassPo();
    152                     Long cclassId = DBSeqUtils.getSeq("IOMP_SEQ");
    153                     String subCclassName = aclassIp+"."+bclassIp+"."+cclassIp+"."+(startIp+i*ipUnit);
    154                     String gateway = aclassIp+"."+bclassIp+"."+cclassIp+"."+(startIp+(i+1)*ipUnit-IpFwConstants.BASICUNIT);
    155                     Integer ipStart = startIp+i*ipUnit + 1;
    156                     Integer ipEnd = startIp+(i+1)*ipUnit - IpFwConstants.BASICUNIT;
    157                     Integer ipTotalCnt = ipUnit;
    158                     Integer ipAvailCnt = ipUnit -IpFwConstants.BASICUNIT;
    159                     cclassPo.setCclassId(cclassId);
    160                     cclassPo.setBclassId(bclassId);
    161                     cclassPo.setCclassName(subCclassName);
    162                     cclassPo.setSubnetmask(subNetMaskUnit.toString());
    163                     cclassPo.setGateway(gateway);
    164                     cclassPo.setIpStart(ipStart);
    165                     cclassPo.setIpEnd(ipEnd);
    166                     cclassPo.setAclassIp(aclassIp);
    167                     cclassPo.setBclassIp(bclassIp);
    168                     cclassPo.setCclassIp(cclassIp);
    169                     cclassPo.setIpTotalCnt(ipTotalCnt);
    170                     cclassPo.setIpAvailCnt(ipAvailCnt);
    171                 
    172                     rmNwCclassList.add(cclassPo);
    173                     
    174                     //生成对应的IP表数据
    175                     String[] topCclassNameList = subCclassName.split("\.");
    176                     Integer aclassIpAddr = Integer.parseInt(topCclassNameList[0]);
    177                     Integer bclassIpAddr = Integer.parseInt(topCclassNameList[1]);        
    178                     Integer cclassIpAddr = Integer.parseInt(topCclassNameList[2]);
    179                     Integer dclassIpAddr = Integer.parseInt(topCclassNameList[3]);
    180                     for(int j=0;j < ipUnit-IpFwConstants.BASICUNIT;j++) {
    181                         RmCdpIpAddressPo ipAddressPo = new RmCdpIpAddressPo();
    182                         String curIpAddress = aclassIpAddr+"."+bclassIpAddr+"."+cclassIpAddr+"."+(dclassIpAddr+j+1) ;
    183                         ipAddressPo.setIp(curIpAddress);
    184                         ipAddressPo.setCclassId(cclassId);
    185                         ipAddressPo.setSeq(dclassIpAddr+j+1);
    186                         //待定字段值ALLOCED_STATUS_CODE
    187                         ipAddressPo.setAllocedStatusCode(IpFwConstants.NOTALLOCATE);
    188                         ipAddressPo.setAllocedTime(date);
    189                         ipsList.add(ipAddressPo);
    190                     }
    191                     count++;
    192                 }
    193             }
    194         }else {
    195             throw new BizException("001", "没有足够的子网可供分配");
    196         }
    197         
    198         Connection connection = null;    
    199         DataSource dataSource = null;
    200         try {
    201             TransactionSynchronizationManager.clearSynchronization();
    202             if (!TransactionSynchronizationManager.isSynchronizationActive()) {
    203                 TransactionSynchronizationManager.initSynchronization();
    204             }
    205             dataSource = jdbcTemplate.getDataSource();
    206             connection = DataSourceUtils.getConnection(dataSource);
    207             connection.setAutoCommit(false);
    208             if(rmNwCclassList.size() > 0) {
    209                 saveNwCclassPoList(rmNwCclassList);
    210             }
    211             if(ipsList.size() > 0) {
    212                 saveIpAddressList(ipsList);
    213                 result += "OK";
    214                 connection.commit();
    215             }
    216             long endTime = System.currentTimeMillis();
    217             logger.info("***************启用C段子网耗时:{}",endTime - startTime);
    218         } catch(Exception e) {
    219             try {
    220                 connection.rollback();
    221             } catch (SQLException e1) {
    222                 logger.error("启用子网报错:", e1);
    223             }
    224             logger.error("启用子网报错:", e);
    225         } finally {
    226             try {
    227                 TransactionSynchronizationManager.clearSynchronization();
    228             } catch (IllegalStateException e) {
    229                 logger.error("启用子网报错:", e);
    230                 connection.rollback();
    231             }
    232             TransactionSynchronizationManager.initSynchronization();
    233            
    234             try {
    235                 connection.setAutoCommit(true);
    236             } catch (SQLException e) {
    237                 logger.error("启用子网报错:", e);
    238                 connection.rollback();
    239             }
    240             
    241             if (connection != null) {
    242                 DataSourceUtils.releaseConnection(connection, dataSource);
    243             }
    244         }    
    245         return result;
    246     }
    247     
    248     /**
    249      * 在/16子网池下批量新增按子网掩码和个数分配的子网表
    250      * 在子网表记录创建成功后批量新增ip地址表记录
    251      * @author liuqiang.zh 
    252      * @param paramBody
    253      */
    254 //    @Transactional(readOnly = false)
    255     public String batchSaveSubCclassByBName(Map<String, Object> paramBody) throws Exception{
    256         String result = "";
    257         long startTime = System.currentTimeMillis();
    258         //调用通用方法获取C段列表,遍历
    259         String cclassNameTemp = (String)paramBody.get("className");
    260         String[] cclassNameTempList = cclassNameTemp.split("/");
    261         String bclassName = cclassNameTempList[0];
    262         //启用支持半个B段
    263         Integer bclassType = 0;
    264         String bclassTypeStr = cclassNameTempList[1];
    265         if(bclassTypeStr != null && !"".equals(bclassTypeStr)) {
    266             bclassType = Integer.parseInt(bclassTypeStr);
    267         }
    268         if("".equals(bclassName)) {
    269             throw new BizException("001", "未获取到B段ip");
    270         }
    271         String[] CIpNumberList = bclassName.split("\.");
    272         Integer aclassIp = Integer.parseInt(CIpNumberList[0]);
    273         Integer bclassIp = Integer.parseInt(CIpNumberList[1]);
    274         //半个B段的起始Ip
    275         Integer beginIp = Integer.parseInt(CIpNumberList[2]);
    276         //获取子网掩码格式,判断?是否小于/16子网(16-24)
    277         Integer subNetMaskUnit  = 0;
    278         Object subnetmaskTempStr = paramBody.get("subnetmask");
    279         if(subnetmaskTempStr !=null && !"".equals(subnetmaskTempStr)) {
    280             subNetMaskUnit = Integer.parseInt(subnetmaskTempStr.toString());
    281         }
    282         if(subNetMaskUnit < IpFwConstants.BUNIT || subNetMaskUnit > IpFwConstants.BMAXIPUNIT) {
    283             throw new BizException("001", "输入的子网掩码超出范围!");
    284         }
    285         Integer subNumber  = 0;
    286         Object subNumberTempStr = paramBody.get("subNumber");
    287         if(subNumberTempStr !=null && !"".equals(subNumberTempStr)) {
    288             subNumber = Integer.parseInt(subNumberTempStr.toString());
    289         }
    290         //机房模块,安全区域,安全分层,网络汇聚,VC服务器,数据中心
    291         String cclassTypeCode = String.valueOf(paramBody.get("cclassTypeCode"));
    292         //获取最小单元的位数selfDefIp
    293         int subUnit = IpFwConstants.BMAXIPUNIT - subNetMaskUnit;
    294         //最小单元存放的IP个数
    295         int ipUnit = (int)Math.pow(IpFwConstants.BASICUNIT, subUnit);
    296         //此处先查询B段表信息,更新资源池ID
    297         Long bclassId = 0L;
    298         //获取起始位子IP
    299         Integer startIp = 0;
    300         //判断是否启用的是一个完整B段
    301         if(bclassType > IpFwConstants.BUNIT) {
    302             startIp = beginIp;
    303         }
    304         //子网池结束ip
    305         int scope = (int)Math.pow(IpFwConstants.BASICUNIT,(IpFwConstants.BMAXIPUNIT-bclassType));
    306         int endIp = beginIp+scope;
    307         List<NwCclassPo> nwCclassPoTemp = null;
    308         for(int i=0;i < scope/ipUnit;i++) {
    309             //当前的C段数字
    310             int curCIp = startIp+i*ipUnit;
    311             String subCclassName = aclassIp+"."+bclassIp+"."+curCIp+".0";
    312             //此处去子网表中查找当前子网格式下第一个IP,是否存在?若不存在,则取当前起始IP
    313             nwCclassPoTemp = rmNwCclassDAO.getBclassByName(subCclassName);
    314             if(nwCclassPoTemp.size() == 0 || nwCclassPoTemp.isEmpty()) {
    315                 startIp += i*ipUnit;
    316                 break;
    317             }
    318             if(i == IpFwConstants.MAXIPNUMBER/ipUnit-1) {
    319                 startIp = endIp;
    320             }
    321         }
    322         //批量子网
    323         List<NwCclassPo> rmNwCclassList = new ArrayList<>();
    324         List<RmNwCclassFreelistPo> RmNwCclassFreelist = new ArrayList<>();
    325         List<RmNwSubnetmaskExtPo> rmNwSubnetmaskExtList = new ArrayList<>();
    326         //批量新增IP表记录
    327         List<RmCdpIpAddressPo> ipsList =new ArrayList<>();
    328         //获取子网个数,判断,当前C段剩余的按子网格式分配的子网个数是否大于选择的子网个数
    329         int availNum = (int)(endIp - startIp)/ipUnit;
    330         Date date = ExDateUtils.getCurrentDateTime();
    331         //统计可用个数
    332         int count = 0;
    333         if(subNumber <= availNum) {
    334             for(int i=0;i<subNumber;i++) {
    335                 //当前的C段数字,允许192.168.0.0/24子网
    336                 int curCIp = 0;
    337                 curCIp = startIp+i*ipUnit;
    338                 if(curCIp > endIp-1) {
    339                     throw new BizException("001", "可用的子网个数不足");
    340                 }
    341                 String subCclassName = aclassIp+"."+bclassIp+"."+curCIp+".0";
    342                 //此处去子网表中查找当前子网格式下第一个IP,是否存在?若不存在,则按
    343                 nwCclassPoTemp = rmNwCclassDAO.getBclassByName(subCclassName);
    344                 if(count == subNumber) {
    345                     break;
    346                 }
    347                 if(nwCclassPoTemp.size() == 0 || nwCclassPoTemp.isEmpty()) {
    348                     //子网表记录,这里与C段表为一对一关系
    349                     NwCclassPo cclassPo = new NwCclassPo();
    350                     RmNwCclassFreelistPo cclassFreePo = new RmNwCclassFreelistPo();
    351                     Long cclassId = DBSeqUtils.getSeq("IOMP_SEQ");
    352                     String gateway = aclassIp+"."+bclassIp+"."+curCIp+".254";
    353                     Integer ipStart = 1;
    354                     Integer ipEnd = IpFwConstants.MAXIPNUMBER-IpFwConstants.BASICUNIT;
    355                     Integer ipTotalCnt = IpFwConstants.MAXIPNUMBER;
    356                     Integer ipAvailCnt = IpFwConstants.MAXIPNUMBER -IpFwConstants.BASICUNIT;
    357                     cclassPo.setCclassId(cclassId);
    358                     cclassPo.setBclassId(bclassId);
    359                     //待定?
    360                     cclassPo.setCclassTypeCode(cclassTypeCode);
    361                     cclassPo.setCclassName(subCclassName);
    362                     cclassPo.setSubnetmask(subNetMaskUnit.toString());
    363                     cclassPo.setGateway(gateway);
    364                     cclassPo.setIpStart(ipStart);
    365                     cclassPo.setIpEnd(ipEnd);
    366                     cclassPo.setAclassIp(aclassIp);
    367                     cclassPo.setBclassIp(bclassIp);
    368                     cclassPo.setCclassIp(curCIp);
    369                     cclassPo.setIpTotalCnt(ipTotalCnt);
    370                     cclassPo.setIpAvailCnt(ipAvailCnt);
    371                     rmNwCclassList.add(cclassPo);
    372                     //子网扩展表数据
    373                     RmNwSubnetmaskExtPo rmNwSubnetmaskExtPo = new RmNwSubnetmaskExtPo();
    374                     rmNwSubnetmaskExtPo.setSubnetmaskId(cclassId);
    375                     //新增GatewayIp
    376                     rmNwSubnetmaskExtPo.setGatewayIp(gateway);
    377                     rmNwSubnetmaskExtPo.setIpVersion(4L);
    378                     rmNwSubnetmaskExtList.add(rmNwSubnetmaskExtPo);
    379                     //子网空闲表数据
    380                     cclassFreePo.setCclassId(cclassId);
    381                     cclassFreePo.setSeqStart(ipStart);
    382                     cclassFreePo.setSeqEnd(ipEnd);
    383                     cclassFreePo.setAvailCnt(ipAvailCnt);
    384                     RmNwCclassFreelist.add(cclassFreePo);
    385                     
    386                     //生成对应的IP表数据
    387                     for(int m=0;m < ipUnit;m++) {
    388                         for(int j=1;j <IpFwConstants.MAXIPNUMBER-1;j++) {
    389                             RmCdpIpAddressPo ipAddressPo = new RmCdpIpAddressPo();
    390                             String curIpAddress = aclassIp+"."+bclassIp+"."+(curCIp+m)+"."+j ;
    391                             ipAddressPo.setIp(curIpAddress);
    392                             ipAddressPo.setCclassId(cclassId);
    393                             ipAddressPo.setSeq(j);
    394                             //待定字段值ALLOCED_STATUS_CODE
    395                             ipAddressPo.setAllocedStatusCode(IpFwConstants.NOTALLOCATE);
    396                             ipAddressPo.setAllocedTime(date);
    397                             ipsList.add(ipAddressPo);
    398                         }
    399                     }
    400                     count++;
    401                 }
    402             }
    403         }else {
    404             throw new BizException("001", "没有足够的子网可供分配");
    405         }
    406         
    407         Connection connection = null;    
    408         DataSource dataSource = null;
    409         try {
    410             TransactionSynchronizationManager.clearSynchronization();
    411             if (!TransactionSynchronizationManager.isSynchronizationActive()) {
    412                 TransactionSynchronizationManager.initSynchronization();
    413             }
    414             dataSource = jdbcTemplate.getDataSource();
    415             connection = DataSourceUtils.getConnection(dataSource);
    416             connection.setAutoCommit(false);
    417             if(rmNwCclassList.size() > 0) {
    418                 saveNwCclassPoList(rmNwCclassList);
    419             }
    420             if(ipsList.size() > 0) {
    421                 saveIpAddressList(ipsList);
    422                 result += "OK";
    423                 connection.commit();
    424             }
    425             long endTime = System.currentTimeMillis();
    426             logger.info("***************启用B段子网耗时:{}",endTime - startTime);
    427         } catch(Exception e) {
    428             try {
    429                 connection.rollback();
    430             } catch (SQLException e1) {
    431                 logger.error("启用子网报错:", e1);
    432             }
    433             logger.error("启用子网报错:", e);
    434         } finally {
    435             try {
    436                 TransactionSynchronizationManager.clearSynchronization();
    437             } catch (IllegalStateException e) {
    438                 logger.error("启用子网报错:", e);
    439                 connection.rollback();
    440             }
    441             TransactionSynchronizationManager.initSynchronization();
    442            
    443             try {
    444                 connection.setAutoCommit(true);
    445             } catch (SQLException e) {
    446                 logger.error("启用子网报错:", e);
    447                 connection.rollback();
    448             }
    449             
    450             if (connection != null) {
    451                 DataSourceUtils.releaseConnection(connection, dataSource);
    452             }
    453         }    
    454         return result;
    455     }
    456     /**
    457      * jdbcTemplate批量新增NwCclassPo表
    458      * @param list
    459      * @author liuqiang
    460      */
    461     private void saveNwCclassPoList(final List<NwCclassPo> list) throws Exception{
    462         String sql = "insert into RM_NW_CCLASS (CCLASS_ID,BCLASS_ID,CCLASS_TYPE_CODE,CCLASS_NAME,SUBNETMASK,
    " + 
    463                 "GATEWAY,VLAN_ID,IP_START,IP_END,ACLASS_IP,BCLASS_IP,CCLASS_IP,IP_TOTAL_CNT,IP_AVAIL_CNT,IS_ACTIVE,DATACENTER_ID,SECURE_AREA_CODE,MODULE_ID)"
    464                 + "values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    465         jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
    466 
    467             @Override
    468             public int getBatchSize() {
    469                 return list.size();
    470             }
    471 
    472             @Override
    473             public void setValues(PreparedStatement ps, int i) throws SQLException {
    474                 ps.setLong(1, list.get(i).getCclassId());
    475                 ps.setLong(2, list.get(i).getBclassId());
    476                 ps.setString(3, list.get(i).getCclassTypeCode());
    477                 ps.setString(4, list.get(i).getCclassName());
    478                 ps.setString(5, list.get(i).getSubnetmask());
    479                 ps.setString(6, list.get(i).getGateway());
    480                 if (list.get(i).getVlanId() != null) {
    481                     ps.setLong(7, list.get(i).getVlanId());
    482                 } else {
    483                     ps.setLong(7, 0);
    484                 }
    485                 ps.setInt(8, list.get(i).getIpStart());
    486                 ps.setInt(9, list.get(i).getIpEnd());
    487                 ps.setInt(10, list.get(i).getAclassIp());
    488                 ps.setInt(11, list.get(i).getBclassIp());
    489                 ps.setInt(12, list.get(i).getCclassIp());
    490                 ps.setInt(13, list.get(i).getIpTotalCnt());
    491                 ps.setInt(14, list.get(i).getIpAvailCnt());
    492                 ps.setString(15, list.get(i).getIsActive());
    493                 Long datacenterId = list.get(i).getDatacenterId();
    494                 if(datacenterId != null) {
    495                     ps.setLong(16, list.get(i).getDatacenterId());
    496                 }else {
    497                     ps.setLong(16, 0L);
    498                 }
    499                 ps.setString(17, list.get(i).getSecureAreaCode());
    500                 Long moduleId = list.get(i).getModuleId();
    501                 if(moduleId != null) {
    502                     ps.setLong(18, list.get(i).getModuleId());
    503                 }else {
    504                     ps.setLong(18, 0L);
    505                 }
    506             }
    507         });
    508     }
    509         
    510     /**
    511      * jdbcTemplate批量新增RmCdpIpAddressPo表
    512      * @param list
    513      * @author zhangchaoyang
    514      */
    515     private void saveIpAddressList(final List<RmCdpIpAddressPo> list) throws Exception{
    516         String sql = "insert into RM_CDP_IP_ADDRESS (IP,CCLASS_ID,SEQ,IP_TYPE_ID,RES_POOL_ID,ALLOCED_STATUS_CODE,ALLOCED_TIME) "
    517                 + "values(?,?,?,?,?,?,?)";
    518         this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
    519 
    520             @Override
    521             public int getBatchSize() {
    522                 return list.size();
    523             }
    524 
    525             @Override
    526             public void setValues(PreparedStatement ps, int i) throws SQLException {
    527                 ps.setString(1, list.get(i).getIp());
    528                 ps.setLong(2, list.get(i).getCclassId());
    529                 ps.setInt(3, list.get(i).getSeq());
    530                 ps.setString(4, list.get(i).getIpTypeId());
    531                 if (list.get(i).getResPoolId() != null) {
    532                     ps.setLong(5, list.get(i).getResPoolId());
    533                 } else {
    534                     ps.setLong(5, 0);
    535                 }
    536                 ps.setString(6, list.get(i).getAllocedStatusCode());
    537                 ps.setDate(7, new java.sql.Date(list.get(i).getAllocedTime().getTime()));
    538             }
    539         });
    540     }
    541 }
    Temp

    3.4、常量Util

     1 package com.ccb.cloud.nw.ip.constants;
     2 
     3 public class IpFwConstants {
     4     //最大可用地址个数
     5     public static final int MAXIPNUMBER = 256;
     6     
     7     //Cip地址总位数
     8     public static final int MAXIPUNIT = 32;
     9     
    10     //Bip地址总位数
    11     public static final int BMAXIPUNIT = 24;
    12     
    13     //完整B段位数
    14     public static final int BUNIT = 16;
    15     
    16     //首位地址个数
    17     public static final int BASICUNIT = 2;
    18     
    19     //防火墙网络地址类型
    20     public static final String FWCCLASSTYPECODE = "FWINT";
    21         
    22     //没有激活
    23     public static final String NOTAVAILABLE = "N";
    24     
    25     //激活
    26     public static final String AVAILABLE = "Y";
    27     
    28     //激活
    29     public static final String HOLDPOSITION = "H";
    30     
    31     //激活
    32     public static final String NOTALLOCATE = "NA";
    33         
    34     //最大可用地址个数
    35     public static final String BCLASSSUBNETMASK = "255.255.0.0";
    36 }
    IpFwConstants
      1 /**
      2  * Copyright (c) 2017, China Construction Bank Co., Ltd. All rights reserved.
      3  * 中国建设银行版权所有.
      4  *
      5  * 审核人:
      6  */
      7 package com.ccb.cloud.common.data;
      8 
      9 import java.sql.Connection;
     10 import java.sql.SQLException;
     11 
     12 import javax.sql.DataSource;
     13 
     14 import org.apache.commons.lang3.StringUtils;
     15 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
     16 import org.springframework.transaction.PlatformTransactionManager;
     17 import org.springframework.transaction.TransactionDefinition;
     18 import org.springframework.transaction.TransactionStatus;
     19 import org.springframework.transaction.support.DefaultTransactionDefinition;
     20 
     21 import com.ccb.cloud.common.spring.SpringContextHolder;
     22 
     23 /**
     24  * 主键序列号生成器,统一数据库主键生成方式 每次获取一定长度的序列号缓存到内存中,提高应用程序获取序列号的效率
     25  * 
     26  * Oracle数据库采用序列生成序列号,MySQL数据库使用数据库表生成序列号
     27  * <p>
     28  * 
     29  * @author 
     30  * @version 1.0 2017年8月31日
     31  * @see
     32  */
     33 public class DBSeqUtils {
     34 
     35     // 默认序列名称
     36     private static final String DEFAULT_SEQ_KEY = "MAIN_SEQ";
     37 
     38     // 内存中序列长度(在Oracle数据中建立序列是,需要将序列的步长设置为500)
     39     private static final long SEQ_LEN = 100;
     40 
     41     // 序列获取控制参数
     42     private static long BEGIN_SEQ = 0 ;// 开始的序列号
     43     private static long CURRENT_SEQ = 0;// 当前序列号
     44 
     45     /**
     46      * 获取默认的最新序列值
     47      * @throws InterruptedException 
     48      * 
     49      */
     50     public static synchronized long getDefaultSeq(){
     51 
     52         long seq;
     53 
     54         if (BEGIN_SEQ == 0 || CURRENT_SEQ == SEQ_LEN) {
     55             // 重新获取序列
     56             BEGIN_SEQ = getCurrentSeq();
     57             CURRENT_SEQ = 0;
     58         }
     59 
     60         seq = BEGIN_SEQ + CURRENT_SEQ;
     61         CURRENT_SEQ++;
     62 
     63         return seq;
     64 
     65     }
     66     
     67     
     68     /**
     69      * 获取序列的最新序列值
     70      * 
     71      * @return
     72      */
     73     public static long getSeq(String seqKey) {
     74 
     75         DataSource dataSource = SpringContextHolder.getBean("dataSource");
     76 
     77         NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(
     78                 dataSource);
     79 
     80         return jdbcTemplate.getJdbcOperations()
     81                 .queryForObject(
     82                         "SELECT " + seqKey + ".nextval FROM dual",
     83                         Long.class);
     84 
     85     }        
     86 
     87     /**
     88      * 获取数据库中最新的序列值
     89      * 
     90      * @return
     91      */
     92     private static long getCurrentSeq() {
     93 
     94         DataSource dataSource = SpringContextHolder.getBean("dataSource");
     95 
     96         String jdbcUrl = getJdbcUrlFromDataSource(dataSource);
     97 
     98         NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(
     99                 dataSource);
    100 
    101         // 根据jdbc url判断数据库类型
    102         if (StringUtils.contains(jdbcUrl, ":mysql:")) {
    103             return getMySqlCurrentSeqVal(jdbcTemplate);
    104         } else if (StringUtils.contains(jdbcUrl, ":oracle:")) {
    105             return jdbcTemplate.getJdbcOperations().queryForObject(
    106                     "SELECT " + DEFAULT_SEQ_KEY + ".nextval FROM dual",
    107                     Long.class);
    108         } else {
    109             throw new IllegalArgumentException("数据库驱动配置错误,不支持的类型:" + jdbcUrl);
    110         }
    111     }
    112 
    113     /**
    114      * 获取mySql的当前序列值
    115      * @param jdbcTemplate
    116      */
    117     private static long getMySqlCurrentSeqVal(
    118             NamedParameterJdbcTemplate jdbcTemplate) {
    119         
    120         long currentSeq = 0;
    121 
    122         // 更新序列值的大小
    123         DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    124         def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
    125         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    126         PlatformTransactionManager txManager = SpringContextHolder
    127                 .getBean("transactionManager");
    128         TransactionStatus status = txManager.getTransaction(def);
    129 
    130         try {
    131             
    132             // 获取当前序列值
    133             currentSeq = jdbcTemplate.getJdbcOperations().queryForObject(
    134                     "SELECT cur_seq_val FROM admin_seq WHERE seq_name='"
    135                             + DEFAULT_SEQ_KEY + "' FOR UPDATE", Long.class);
    136             
    137             jdbcTemplate.getJdbcOperations().execute(
    138                     "UPDATE admin_seq set cur_seq_val="
    139                             + (currentSeq + SEQ_LEN) + " WHERE seq_name='"
    140                             + DEFAULT_SEQ_KEY + "'");
    141             txManager.commit(status);
    142             
    143         } catch (RuntimeException e) {
    144             txManager.rollback(status);
    145             throw new RuntimeException("无法生成序列号",e); 
    146         }
    147         
    148         return currentSeq;
    149     }
    150 
    151     /**
    152      * 通过数据源获取数据库连接URL
    153      * 
    154      * @param dataSource
    155      * @return
    156      */
    157     private static String getJdbcUrlFromDataSource(DataSource dataSource) {
    158         Connection connection = null;
    159         try {
    160             connection = dataSource.getConnection();
    161             if (connection == null) {
    162                 throw new IllegalStateException("数据源无法返回的connection");
    163             }
    164             return connection.getMetaData().getURL();
    165         } catch (SQLException e) {
    166             throw new RuntimeException("无法获取数据库的URL", e);
    167         } finally {
    168             if (connection != null) {
    169                 try {
    170                     connection.close();
    171                 } catch (SQLException e) {
    172                 }
    173             }
    174         }
    175     }
    176 
    177 }
    DBSeqUtils

    水平有限,程序中的考虑不周或者精简代码时产生的BUG希望大家自己斧正。

  • 相关阅读:
    都在谈零信任,网络安全和零信任架构的核心是什么?
    盘点:区块链有望被主流接纳的四个场景
    同态加密:密码学的下一个黄金时代
    浅谈人工智能应对数字化转型挑战的5个领域
    2021年7项物联网预测
    15分钟=1年!当人工智能遇到材料学……
    人工智能推理的演进
    保护加密货币资产的7种优秀做法
    ES6语法 Promise Iterator
    css阴影框
  • 原文地址:https://www.cnblogs.com/lq147760524/p/9115365.html
Copyright © 2020-2023  润新知