[오리지널] 캐 시 없 는 데이터베이스 에서 부서 트 리 구조 처리 - 전재 출처 를 밝 혀 주 십시오.

1. 데이터베이스 디자인
우 리 는 업무 중 에 자주 나무 구조의 데 이 터 를 사용한다. 예 를 들 어 회사 의 부서 구조, 창고 물품 의 분류 등 이다.일반적으로 이 나무 들 의 구 조 는 모두 고정된 몇 층 구조 가 아니 라 임 의 등급 이다.이때 우 리 는 트 리 의 데이터 구 조 를 사용 해 야 한다.다음은 부서 트 리 를 예 로 들 어 설명 한다.
데이터베이스 테이블 구조:
부서 Id - --- departmentId
부서 Url - --- url
부서 명 --- - department Name
부모 부서 Id - --- superDepartmentId
한 회사 의 부서 정 보 는 반드시 먼저 그것 을 데이터베이스 에 지속 시 켜 야 한다.부서 의 구 조 는 무한 한 등급 의 나무 구조 이기 때문에 우 리 는 데이터 베 이 스 를 디자인 할 때 부서 표 의 부서 Id 와 부서 이름 이라는 두 필드 를 바탕 으로 두 필드, 부모 부서 Id 와 부서 의 Url 링크 를 추가 해 야 한다.
부모 부서 Id: 이 필드 는 조 회 를 할 때 사용 합 니 다. 만약 에 한 부서 A 의 부모 부서 Id 가 부서 B 의 부서 Id 라면 저 희 는 부서 A 를 부서 B 의 여러 직접 하위 부서 중 하나 로 보고 순서대로 유추 합 니 다.
부서 Url: 만약 에 우리 가 한 부서 A 가 있 으 면 부서 A 의 아버지 부 서 는 부서 B 이 고 부서 B 의 아버지 부 서 는 부서 C 이 며 부서 Url 은 부서 CId부서 BId부서 AID.이 필드 는 일반적으로 한 부서 의 모든 부하 부 서 를 조회 하 는 데 사용 되 며, 트 리 구조 에 서 는 사용 되 지 않 습 니 다.
2. 데이터베이스 에서 부서 트 리 가 져 오기
a. 모델 류 Framework Tree
클래스 Framework Tree 에 여러 개의 속성 이 있 습 니 다. 여 기 는 일일이 열거 하지 않 고 중요 한 몇 가지 속성 만 설명 합 니 다.
String Id - --- 실제 부서 의 Url 이지 만 사용 하 는 전단 프레임 워 크 는 easyui 의 Tree 이기 때문에 여기 서 id 는 실제 url 입 니 다.
String thisId - 이 모델 이 대표 하 는 부서 의 실제 Id
String text --- - easyui 에 표 시 된 텍스트 입 니 다. 이 곳 은 부서 명 으로 채 워 져 있 습 니 다.
List children --- - 이 대상 은 이 부서 의 모든 하위 부서 대상 으로 저 장 됩 니 다.
b. Dao 층 Sql 문장:
 

	

 
 
 
우리 가 사용 하 는 특수 한 데이터 베이스 구조 로 인해 이곳 의 Sql 문 구 는 아버지 급 부서 Id 에 따라 이 아버지 급 부서 의 모든 직계 부 서 를 조회 하기 때문에 우 리 는 이 부 서 를 나무 형식 으로 모두 찾 으 려 면 재 귀적 인 형식 으로 조회 해 야 한다.
c. 서비스 계층 처리
 
/**
	 *              
	 *              
	 */
	public List injectFrameworkDepartment(FrameworkTree superDepartment){
		//      Id             
		List departments = departmentDao.getLowerBySuperId(superDepartment);
		//    ,                 ,       
		for(FrameworkTree department : departments){
			department.setChildren(this.injectFrameworkDepartment(department));
		}
		//         
		return departments;
	}

 
 
 
 
저 희 는 Service 층 에서 재 귀적 인 형식 을 사용 합 니 다. 먼저 Framework Tree 대상 에 들 어가 야 합 니 다. 이 대상 은 저희 가 사용 할 때의 부모 급 부서 모델 입 니 다.
d. 컨트롤 러 층 처리
contrller 층 의 재 귀 처리 방법 을 살 펴 보 겠 습 니 다.
 
FrameworkTree superDepartment = new FrameworkTree();
superDepartment.setText("XXXX    ");
superDepartment.setId("0000");
superDepartment.setThisId("0000");
superDepartment.setChildren(departmentService.injectFrameworkDepartment(superDepartment));

 
 
 
Controller 층 에서 우 리 는 루트 등급 의 부 서 를 새로 만 들 었 습 니 다. 이 부서 의 부서 Id 는 모든 부서 의 최초 등급 의 부모 부서 로 자바 중의 Object 와 비슷 합 니 다.우 리 는 이 최초의 노드 를 이용 하여 Service 층 의 재 귀 를 시작 하고 재 귀 를 시작 한 후에 코드 의 재 귀 를 통 해 우 리 는 모든 부서 의 나무 구 조 를 얻 을 수 있 습 니 다. 이 나무 구 조 는 전단 의 easyui 에 피드백 한 후에 easyui 는 직접 분석 할 수 있 습 니 다.
3. 부서 트 리 의 단일 화
이 부서 트 리 에 중대 한 문제 가 존재 합 니 다. 바로 이 트 리 자체 가 만 들 때 데이터 베 이 스 를 여러 번 요청 해 야 한 다 는 것 입 니 다.데이터베이스 에서 한 부 서 를 찾 을 때마다 dao 층 방법 을 다시 호출 하여 이 부서 의 모든 하위 부 서 를 조회 해 야 합 니 다.그래서 우 리 는 이 부서 의 나 무 를 일례 화해 야 한다.
컨트롤 러 계층 전체 코드
 
/**
	 *            ,               ,   service     ,           
	 * @return     json
	 */
	@RequestMapping("getFramework.do")
	public String getFramework(){
		try{
			Gson gson = new Gson();
			if(FrameWorkConstant.frameworkDepartments != null){
				String json = gson.toJson(FrameWorkConstant.frameworkDepartments);
				return json;
			}else{
				synchronized(this){
					if(FrameWorkConstant.frameworkDepartments != null){
						String json = gson.toJson(FrameWorkConstant.frameworkDepartments);
						return json;
					}
					FrameworkTree superDepartment = new FrameworkTree();
					superDepartment.setText("XXXX    ");
					superDepartment.setId("0000");
					superDepartment.setThisId("0000");
					superDepartment.setChildren(departmentService.injectFrameworkDepartment(superDepartment));
					FrameWorkConstant.frameworkDepartments = new LinkedList();
					FrameWorkConstant.frameworkDepartments.add(superDepartment); 
					String json = gson.toJson(FrameWorkConstant.frameworkDepartments);
					return json;
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			return Constant.SERVER_ERROR_CODE;
		}
	}

 
 
 
단일 화 된 부서 트 리 구 조 를 만 들 었 는 지 여 부 를 판단 하면 됩 니 다. 대상 을 만 들 었 으 면 이 대상 으로 돌아 가 고 만 들 지 않 으 면 대상 을 만 듭 니 다.
저희 가 여기 서 주의해 야 할 문 제 는 서버 를 시작 한 후에 부서 정 보 를 처음 얻 었 을 때 병발 현상 이 발생 하면 새로운 두 번 의 대상 할당 상황 이 발생 할 수 있 습 니 다. 따라서 저 희 는 synchronized 를 사용 하여 일부 코드 를 잠 가 야 합 니 다.잠 긴 코드 에서 비어 있 는 지 다시 판단 해 야 합 니 다.
4. 부서 의 첨삭 과 수정 처리.
부서 에 대한 첨삭 검 사 를 할 때 우리 가 얻 은 부서 구 조 는 데이터베이스 에 있 는 부서 가 아니 라 메모리 에 있 는 단일 부서 이기 때문에 우 리 는 데이터 베 이 스 를 첨삭 하고 검사 할 때 도 단일 부서 트 리 를 처리 해 야 한다.예 를 들 어 부서 이름 을 수정 할 때 먼저 부서 의 데이터 베이스 중의 이름 을 수정 한 다음 에 단일 부서 트 리 의 데 이 터 를 수정 해 야 한다.
단일 부서 트 리 의 데 이 터 를 찾 는 코드 는 다음 과 같 습 니 다.
 
	/**
	 *   Url     
	 * @param url
	 * @return
	 */
	public FrameworkTree getTargetByUrl(String url, List targets){
		FrameworkTree child = null;
		for(FrameworkTree target:targets){
			if (StringUtil.isInclude(url, target.getId())) {
				
				if(url.equals(target.getId())){
					return target;
				}else{
					child =  getTargetByUrl(url, target.getChildren());
				}
				break ;
			}
		}
		return child;
	}

 
 
 
우리 가 노드 Url 을 통 해 노드 를 찾 는 방법 을 가 진 후에 부서 에 대한 수정 과 삭 제 는 단순화 되 었 다.예 를 들 어 우 리 는 이 노드 를 삭제 해 야 한다 면 null 로 설정 할 수 있 고 부서 이름 을 수정 해 야 한다 면 노드 중의 text 를 수정 하면 데이터 베이스 중의 정보 와 단일 트 리 의 정보 가 일치 하 는 것 을 실현 할 수 있다.
5. 노드 드래그
우리 가 노드 드래그 를 해 야 할 때 (예 를 들 어 기 존 부서 A, 부모 부 서 는 B 이 고 A 를 부서 C 아래로 수정) 데이터 베 이 스 를 처리 한 다음 에 하나의 트 리 를 처리 해 야 합 니 다.주의해 야 할 것 은 드래그 한 후에 이 노드 의 모든 하위 노드 의 Url 도 수정 해 야 한 다 는 것 이다.
서비스 계층 드래그 코드
 
/**
 *         ,            
 */
public void moveDepartment(String startNodeUrl, String endNodeUrl,HttpServletRequest reuqest){
String newUrl = endNodeUrl + "_" +StringUtil.getIdFromUrl(startNodeUrl);
String superDeptId = StringUtil.getIdFromUrl(endNodeUrl);
HashMap params = new HashMap();
params.put("newUrl",newUrl);
params.put("superDeptId",superDeptId);
params.put("startNodeUrl",startNodeUrl);
UserInfo userInfo = getUser(reuqest);
params.put("updateUserId", userInfo.getUserId());
params.put("updateUserName", userInfo.getUserName());
if(!departmentDao.updateDepartmentUrl(params)){
throw new RuntimeException("    Url  ");
}
params.put("startNodeUrl", "'" + startNodeUrl + "%'");
departmentDao.updateChildDepartmentUrl(params);
//              
FrameworkTree oldParent = this.getTargetByUrl(
startNodeUrl.substring(0, startNodeUrl.lastIndexOf("_")), FrameWorkConstant.frameworkDepartments);
//               
for(int i = 0; i < oldParent.getChildren().size() ; i++){
FrameworkTree target = oldParent.getChildren().get(i);
if(target.getId().equals(startNodeUrl)){
//          
FrameworkTree newParent = this.getTargetByUrl(endNodeUrl, FrameWorkConstant.frameworkDepartments);
//         
newParent.getChildren().add(target);
//  Url   Url
target.setId(newUrl);
//             
List childs = this.getAllChildren(target);
//    Url
for(FrameworkTree child : childs){
//         Url      url
child.getId().replace(startNodeUrl, newUrl);
}
//              
oldParent.getChildren().remove(target);
break ;
}
}
}

 
데이터베이스 처리 sql 은 다음 과 같 습 니 다.
  UPDATE framework_department SET super_department_id = #{superDeptId}, url = #{newUrl}, update_time = NOW(), update_user_id = #{updateUserId}, update_user_name = #{updateUserName} WHERE url = #{startNodeUrl} UPDATE framework_department SET url = REPLACE(url,#{startNodeUrl},#{newUrl}), update_time = NOW(), update_user_id = #{updateUserId}, update_user_name = #{updateUserName} WHERE url LIKE (${startNodeUrl}) UPDATE framework_department
SET
super_department_id = #{superDeptId},
url = #{newUrl},
update_time = NOW(),
update_user_id = #{updateUserId},
update_user_name = #{updateUserName}
WHERE
url = #{startNodeUrl}
UPDATE framework_department
SET
url = REPLACE(url,#{startNodeUrl},#{newUrl}),
update_time = NOW(),
update_user_id = #{updateUserId},
update_user_name = #{updateUserName}
WHERE
url LIKE (${startNodeUrl})
 
노드 의 모든 하위 노드 를 가 져 오 는 방법:
  /** * , */ public List getAllChildren(FrameworkTree target){ List childs = target.getChildren(); for(FrameworkTree child: childs){ childs.addAll(getAllChildren(child)); } return childs; } /**
* 노드 의 목 표를 통 해 이 노드 의 모든 하위 노드 가 져 오기
*/
public List getAllChildren(FrameworkTree target){
List childs = target.getChildren();
for(FrameworkTree child: childs){
childs.addAll(getAllChildren(child));
}
return childs;
}
 
 
 
 

좋은 웹페이지 즐겨찾기