1、IP尋址java
1.劃分網絡ID和主機ID的最初方案是使用地址分類。mysql
2.A類:0.0.0.0-127.255.255.255web
B類:128.0.0.0-191.255.255.255算法
C類:192.0.0.0-223.255.255.255spring
D類:224.0.0.0-239.255.255.255sql
E類:240.0.0.0-247.255.255.255數據庫
2、子網apache
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地址爲特殊地址,不在實際中使用。
3、代碼實現
如下提供兩個在/24子網池下劃分更小的子網(24< x < 32)和在/16子網池下劃分更小的子網(16< x < 24)的實現類。注意:其中去掉了主要的業務邏輯代碼,僅提供了IP分配的算法實現。由於須要啓用的IP地址比較多,使用了源生的JDBC事務來提升執行效率。備註:此處使用的springCloud框架,底層實現僅供參考。
3.一、基礎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 }
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 }
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);
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,\n" + 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 }
3.四、常量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 }
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 }
水平有限,程序中的考慮不周或者精簡代碼時產生的BUG但願你們本身斧正。