2017-01-03 3 views
1

Я использую myBatis для сопоставления простой базы данных (в качестве примера).Mybatis вложенное сопоставление один-к-одному или один ко многим.

Он состоит из 4-х моделей: Пользователь, автомобилей, Тариф, Страхование.

Пользователь имеет частный Список Карлистские и частный Тарифная тариф и некоторые другие поля с добытчиками и сеттеров.

автомобилей имеет частное страхование страхование и некоторые другие поля с добытчиками и сеттеров.

Таким образом, я могу отобразить только 1-й уровень гнездования. Я имею в виду, что могу отобразить Пользователь и его поля - Тариф и список Автомобили. Но я не могу указать Страхование Поле Автомобиль. Что мне делать?

Вот мой mapper.xml:

<?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:

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-select на полной карте - это сработало отлично, потому что JOIN создает одну таблицу, и сопоставление становится простым. Но мой главный вопрос все еще актуальен. –

ответ

0

Вы должны извлечь отображение автомобиля: <collection property="carList" column="id" select="getCars" javaType="ArrayList" ofType="Car" />

В разделенном resultMap: <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>

An d ссылку на него из выписки <select id = "getCars" parameterType="int" resultMap="resultCar">

Вы используете resultType="Car". Это нормально для базового картографирования, но существует ассоциация со страхованием: это не базовое и требует конкретного сопоставления.

Кроме того, getCars заявление использует свой собственный resultMap, то, что вы определяете внутри Карлистские коллекции фактически игнорируется (вне сферы). поэтому страховой список равен нулю.

+0

Я попробую то, что вы сказали, но я уверен - нет необходимости создавать другую resultMap. Я видел примеры вложенного сопоставления с одной результирующей картой и одним sql-select. Например, здесь: http://www.programering.com/a/MDN5MjMwATg.html –

+0

В примере, который вы предоставляете, используется один выбор с объединениями. Вы указали в предыдущем комментарии, что вы уже сделали это, и вы хотите использовать подход выбора N + 1 вместо этого с помощью _collection ** select = "getCars" ** _ – blackwizard

+0

Прошу прощения. Вот что я имею в виду: https://github.com/loiane/ibatis-handling-joins/blob/master/src/com/loiane/data/Blog.xml –

Смежные вопросы