2017-01-03 1 views
1

예를 들어 myBatis를 사용하여 간단한 데이터베이스를 매핑합니다.Mybatis 중첩 된 일대일 또는 일대 다 관계 매핑

은 4 개 모델로 구성 : 사용자, 자동차,관세, 보험.

사용자개인 목록 carList개인 관세 관세와 getter 및 setter와 다른 필드가 있습니다.

자동차에는 개인 보험 보험과 게터 및 설정자가있는 다른 필드가 있습니다.

그래서 첫 번째 중첩 수준 만 매핑 할 수 있습니다. 내 말은 사용자 및 그 필드 -관세목록은입니다. 그러나 나는지도 할 수 없다 의 분야는 이다. 어떻게해야합니까?

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace = "UserNamespace"> 
    <resultMap id="resultUser" type="User"> 
     <id property="id" column="id"/> 
     <result property="name" column="name"/> 
     <association property="tariff" column="tariff" select="getTariff" javaType="Tariff"/> 
     <collection property="carList" column="id" select="getCars" javaType="ArrayList" ofType="Car"> 
      <id property="id" column="id"/> 
      <result property="model" column="model"/> 
      <association property="insurance" column="insurance" select="getInsurance" javaType="Insurance"/> 
     </collection> 
    </resultMap> 

    <select id = "getAll" resultMap = "resultUser"> 
     SELECT * FROM carwashservice.users 
    </select> 

    <select id = "getTariff" parameterType="int" resultType="Tariff"> 
     SELECT tariffs.description FROM carwashservice.tariffs WHERE tariffs.id = #{id} 
    </select> 

    <select id = "getCars" parameterType="int" resultType="Car"> 
     SELECT * FROM carwashservice.cars WHERE cars.user = #{id} 
    </select> 

    <select id = "getInsurance" parameterType="int" resultType="Insurance"> 
     SELECT * FROM carwashservice.insurance WHERE insurance.id = #{insurance} 
    </select> 
</mapper> 

그리고 내 DB : 분리 된 된 resultMap에서 <collection property="carList" column="id" select="getCars" javaType="ArrayList" ofType="Car" />

:

CREATE DATABASE IF NOT EXISTS `carwashservice` /*!40100 DEFAULT CHARACTER SET latin1 */; 

USE `carwashservice`; 

DROP TABLE IF EXISTS `cars`; 
CREATE TABLE `cars` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `model` VARCHAR(45) NOT NULL, 
    `user` INT(11) DEFAULT NULL, 
    `insurance` INT(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `user_idx` (`user`), 
    KEY `insurance_idx` (`insurance`), 
    CONSTRAINT `user` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `insurance`; 
CREATE TABLE `insurance` (
    `id` INT(11) NOT NULL, 
    `cost` VARCHAR(45) NOT NULL, 
    `exp_date` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`id`), 
    CONSTRAINT `id` FOREIGN KEY (`id`) REFERENCES `cars` (`insurance`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `tariffs`; 
CREATE TABLE `tariffs` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `description` VARCHAR(45) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `id` (`id`,`description`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `users`; 
CREATE TABLE `users` (
    `id` INT(11) NOT NULL, 
    `name` VARCHAR(45) NOT NULL, 
    `tariff` INT(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `tariff_idx` (`tariff`), 
    KEY `id` (`id`,`name`), 
    CONSTRAINT `tariff` FOREIGN KEY (`tariff`) REFERENCES `tariffs` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 
+0

어떤 오류가 발생합니까? – Lucky

+0

보험 필드에 액세스 할 때 NullPointerException이 발생합니다. 다른 필드는 값으로 올바르게 채워집니다. JOIN을 통해 전체 맵을 선택하려고 시도했습니다. JOIN이 하나의 테이블을 만들고 매핑이 간단 해 졌기 때문에 완벽하게 작동했습니다. 하지만 내 주요 질문은 여전히 ​​실제입니다. –

답변

0

당신은 차 매핑을 추출한다 <resultMap id="resultCar" type="Car"> <id property="id" column="id"/> <result property="model" column="model"/> <association property="insurance" column="insurance" select="getInsurance" javaType="Insurance"/> </resultMap>

을 여기

내 mapper.xml입니다

d 명세서에서 참조하십시오. <select id = "getCars" parameterType="int" resultMap="resultCar">

resultType="Car"을 사용하고 있습니다. 기본 매핑에는 문제가 없지만 Insurance와의 제휴가 있습니다. 이는 기본이 아니며 특정 매핑이 필요합니다.

또한, getCars 문 자체 된 resultMap을 사용하여, 당신은 carList 수집 안에 정의 무엇 실제로 (범위를 벗어난) 무시됩니다. 그래서 보험 목록이 null입니다.

+0

나는 당신이 말한 것을 시도 할 것이지만 나는 확신한다 - 다른 결과 맵을 생성 할 필요가 없다. 하나의 결과 맵과 하나의 sql-select로 중첩 매핑 예제를 보았습니다. 예를 들면 다음과 같습니다. http://www.programering.com/a/MDN5MjMwATg.html –

+0

제공하는 예는 조인과 함께 단일 선택을 사용합니다. 앞선 설명에서 이미 작동하도록 만들었고 대신에 _collection ** select = "getCars"로 N + 1 선택 접근법을 사용하려고합니다 ** _ – blackwizard

+0

죄송합니다. 다음은 내 뜻입니다. https://github.com/loiane/ibatis-handling-joins/blob/master/src/com/loiane/data/Blog.xml –