Как добавить строку в таблицу, только если эта строка отсутствует с помощью спящего режима? - PullRequest
0 голосов
/ 02 ноября 2011

У меня есть таблица в базе данных, которая имеет следующую структуру (данные):

+--------------------------+
      Organization
+--------------------------+
    org_id | name
---------------------------
   1       | IBM
---------------------------
   2       | Google
---------------------------
   3       | Yahoo
+--------------------------+

В приведенной выше таблице org_id является первичным ключом.Я хочу вставить новую строку в этой таблице, только новое имя организации найдено.

Другие таблицы, которые должны использовать эту таблицу, следующие:

+--------------------------+
      Project
+--------------------------+
 project_id| description
---------------------------
   1       | foo
---------------------------
   2       | bar...
---------------------------
   3       | xyz
+--------------------------+

и таблица, которая связывает проектТаблица организации выглядит следующим образом:

+--------------------------+
      Project_Client
+--------------------------+
pc_id | project_id | org_id
---------------------------
   1  | 1          | 1
---------------------------
   2  | 1          | 3
---------------------------
   3  | 2          | 2
+--------------------------+

Я хочу реализовать что-то подобное, используя hibernate:

Каждый проект имеет свое описание и список имен клиентов.Имя клиента - это не что иное, как название организации.Чтобы избежать дублирования данных, я создал таблицу с именем Organization.

При вставке информации о проекте в базу данных, если какое-либо имя клиента уже существует в таблице Organization, тогда org_id этого имени клиента следует использовать при вставке строки в таблицу Project_Client.Если имя клиента отсутствует в таблице Organization, то в таблицу Organization должна быть добавлена ​​новая строка, а затем в таблице Project_Client должна использоваться соответствующая org_id.

Можем ли мы реализовать что-то подобное, используяhibernate?

EDIT # 1

Ранее у меня были следующие классы:

class Project {
    int projectID;
    String description;
    set<String> clients;
    set<String> employers;
    set<String> technologies;
}

Как видите, у каждого проекта будет один илибольше клиентов, работодателей и технологий.Я хочу избежать дублирования названия организации и технологии в нескольких проектах.Например, если для какого-либо проекта клиентом является XYZ, а для другого проекта также клиентом является XYZ, то я просто хочу сослаться на ту же таблицу org_id в organization вместо создания отдельных строк для одной организации.

IЯ надеялся, что Hibernate позволит мне достичь этого легко, но я не смог достичь этого с помощью или с и.Поэтому я изменил свою структуру классов следующим образом:

class Entity {
    int id;
    String name;
}

class Client extends Entity {
    // nothing special here
}

class Employer extends Entity {
    // nothing special here
}

class Technology extends Entity {
    // nothing special here
}

class Project {
    int projectID;
    List<Client> clients;
    List<Employer> employers;
    List<Technology> technologies;
}

Я создал отдельные файлы сопоставления для классов Client, Employer и Technology.Даже это также не помогло мне.

Ответы [ 3 ]

1 голос
/ 02 ноября 2011

Простые один ко многим Project и Organization в идеале должны решить проблему. Всякий раз, когда вы пытаетесь добавить организацию в проект

Классы могут быть определены как:

public class Project {
    private int projectId;
    private Set<Organization> clients;

    public void addClient(Organization org){
        if(clients==null){
            clients=new HashSet<Organization>();
        }
        org.setProject(this);
        clients.add(org);
    }
}

public class Organization{
    private int organizationId;
    private Project project;       //if bi-directional relation is required.
}

Таким образом

  1. Project отобразится в таблицу Project
  2. Organization отобразится в таблицу
  3. Отношение может быть сопоставлено с Project_Client

отношение может отображаться как:

Примечание: many-to-many используется с unique=true, поскольку один-ко-многим не известно о таблице объединения

<class name="Project" table="Project">
  <!-- just showing the relational mapping here , you can figure out the rest -->
  <set name="clients" table="Project_Client">
   <key column="project_id"/>
   <many-to-many class="Organization" unique="true" column="org_id"/>
  </set>
</class>

Остальные классы отображаются нормально

Каскадное можно рассмотреть, если вы не хотите обрабатывать жизненный цикл Organization.

Чтобы добавить организацию в проект

  • Запрос на поиск организации с именем.
  • если Организация нашла, Организация добавлена ​​в Проект с использованием вспомогательной функции addClient()
  • если организация не найдена, создайте ее, а затем используйте addClient()

Надеюсь, это поможет.

После изменения вопроса:

Вопрос был отредактирован для поддержки нескольких Set строк [Клиент, Технология] Поскольку ваше постановление задачи требует, чтобы Employer, Technology и Client были независимыми сущностями (то есть они должны совместно использоваться разными Projects), вам необходимо определить их как отдельную сущность. В вопросе Технология расширяет сущность только благодаря тому, что она обладает похожими свойствами (в будущем это может быть не так).

Следовательно, я предлагаю, чтобы каждый из Организации, Работодателя и Технологии был отображен в отдельную таблицу. Так как они будут иметь отношение многие-ко-многим с Project, для каждого будет отдельная реляционная таблица. Ниже приводится обновленная таблица, таблица классов и спящий режим:

Структура таблицы

Project (projectId, ...)
Organization (orgId,name)
Technology (technologyId,name)
Employer(employerId,name)

соответствующие реляционные таблицы как

project_organization (projectid,orgid)
project_employer (projectid,employerid)
project_tecnology(projectid,technologyid)

Структура класса

public class Project{
 private int projectId;
 private Set<Organization> clients;
 private Set<Employer> employer;
 private Set<Technology> technology;

  //..appropriate getter/setter and helper functions [like the one shown above]
}

Hibernate Mapping

<class name="Project" table="Project">
  <!-- just showing the relational mapping here , you can figure out the rest -->
  <set name="clients" table="Project_Client">
   <key column="projectid"/>
   <many-to-many class="Organization" unique="true" column="org_id"/>
  </set>
  <set name="technology" table="Project_Technology">
   <key column="projectid"/>
   <many-to-many class="Technology" unique="true" column="technologyid"/>
  </set>
  <set name="employer" table="Project_Employer">
   <key column="projectid"/>
   <many-to-many class="Employer" unique="true" column="employerid"/>
  </set>
</class>

Надеюсь, это поможет

1 голос
/ 03 ноября 2011

Да, вы бы сделали что-то вроде этого:

public Organization getOrCreateOrganization(String name) {
    Criteria crit = session.createCriteria(Organization.class);
    crit.add(Restrictions.eq("name", name));
    Organization result = (Organization)crit.uniqueResult();
    if (result == null) {
        result = new Organization();
        result.setName(name);
        session.save(result);
    }
    return result;
}
1 голос
/ 02 ноября 2011

У меня нет полной реализации, но я надеюсь, что этого можно достичь, если вы выполните следующие шаги:

Шаг 1: Создайте Бины, соответствующие таблице Project_Client иOrganization.

Шаг 2: Иметь поле organizationId в Project_Client бобе.

Шаг 3: При подготовке объекта Project_Clientдля вставки запустите запрос, чтобы выяснить, получает ли Organization в уже существующем значение organizationId из БД и устанавливает для него Project_Client

Шаг 4: В противном случае создайте новыйзапись в БД для Organization и установить его 'id' как 'organizationId' в bean-компоненте Project_Client.

Шаг 5: Сохраните бин Project_Client в БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...