0

我正在我的项目中实现身份映射模式和 DataMapper 模式。但我有一些问题。

当我通过网关从数据库中获取数据时,我正在创建对象的新实例并返回 List ...

关于身份映射,从数据库获取数据的最佳方法是什么?我想从数据库中获取患者并将这些数据显示给用户..

身份图中对象的 ID 呢?我的解决方案(在我看来):1)使用一些默认 id 创建新对象 2)将对象保存到数据库 3)获取数据库中最后一个对象的 id 4)设置对象的新 id 5)使用新 id 保存到缓存... .

这是一个很好的解决方案?

谢谢你的帮助!

我的身份映射对象(单例):

public class PacientMap
{

    //Cache obsahující jednotlivé instance entiti

    private static PacientMap _instance;
    private Dictionary<int, Pacient> _cache; // Slouží k ukládání objektů pacient

    //Privátní konstruktor, (zaručí mi, že nedojde k vytvoření další instance) => metoda PacientGetInstance ho zavolá jen jednou
    private PacientMap()
    {
            _cache = new Dictionary<int, Pacient>();
    }

    //Metoda pro vytvoreni objektu jedinacek
    public static PacientMap PacientGetInstance()
    {   
        //Je-li promenna instance null, tak se vytvori objekt
        if (_instance == null)
        {
            _instance = new PacientMap();
        }

       //Vratime jedinacka
        return _instance;
    }



    /***********************************
     Vrátí jedinečnou instanci pro zadaný klíč. Pokud instance neexistuje, bude
     vytvořena a uložena do cache.
    ***************************************/
    public Pacient GetPacient(int klic)
    {
        // Pokud je v cache objekt s daným klicem
        if (_cache.ContainsKey(klic))
        {
            //Vrátím objekt
            return _cache[klic];
        }
        // Pokud jsem ho v cache nenasel
        // Zkusím ho najít v databázi
        if (SerachInDb(klic))
        {
            // Pokud byl nalezen v DB, byl automaticky uložen do cahe a jen si ho pod jeho id v cahe nejdu
            return _cache[klic];
        }

        // Pokud nebyl nikde nalezen, vyhodíme chybu
        throw new Exception();
    }

    /// <summary>
    /// Najde Pacienta v databází a pokud ho najde ulozí ho do cache a vrací TRUE
    /// Pokud ho nenejde vrací FALSE
    /// </summary>
    /// <param name="klic"></param>
    /// <returns></returns>
    private bool SerachInDb(int klic)
    {

        Pacient pac = PacientDataGateway.GetInstance().SelectByPacientId(klic);

        if (pac == null)
        {
            return false;
        }

        _cache.Add(klic, pac);

        return true;
    }

    /// <summary>
    /// Vytvoření nového pacienta
    /// </summary>
    /// <param name="klic"></param>
    /// <param name="pacient"></param>
    /// <returns></returns>
    public bool Add(int IdPacienta, string jmeno, string prijmeni, DateTime datumNarozeni, string cisloPojisteni, string telefon, int zubarId)
    {
        if(SerachInDb(zubarId))
        {
            return true;
        }

        Pacient pacient = new Pacient(0, jmeno, prijmeni, datumNarozeni, cisloPojisteni, telefon, zubarId);

        if(PacientDataGateway.GetInstance().insert(pacient))
        {
            // TODO: Selectnu si púoslední záznam z DB a zjistím so jeho id
        }

        return true;
    }

}

还有Pacient Mapper:

      public List<Pacient> SelectPacient()
    {
        Database db = new Database();
        db.Connect();

        SqlCommand command = db.CreateCommand("SELECT ID,jmeno,prijmeni,datumNarozeni,cisloPojisteni,telefon,Zubarid FROM pacient");

        SqlDataReader reader = db.Select(command);

        List<Pacient> pacienti = new List<Pacient>();

        Pacient pacient = null;
        while (reader.Read())
        {
            pacient = new Pacient();

            pacient.Id = reader.GetInt32(0);
            pacient.Jmeno = reader.GetString(1);
            pacient.Prijmeni = reader.GetString(2);
            pacient.DatumNarozeni = reader.GetDateTime(3);
            pacient.CisloPojisteni = reader.GetString(4);
            pacient.Telefon = reader.GetString(5);
            pacient.idZubare = reader.GetInt32(6);

            pacienti.Add(pacient);
        }
        reader.Close();
        db.Close();

        return pacienti;
    }
4

1 回答 1

0

在从数据库中获取对象之前,您必须检查 IdentityMap 是否存在,这可以防止您获得同一对象的多个副本以及随后的更新冲突。当您通过 Id 请求单个对象时,您可以先检查该对象的 IdentityMap,如果您还没有该对象,则仅调用数据库。对于多个对象,这是无法做到的,因为结果是不确定的。您必须查询数据库,然后检查地图,填补空白。

最终,IdentityMap 的工作是确保在任何时候给定范围内只存在一个对象的内存副本。如果你的实现了这一点,那么它就完成了。

如果您的地图以 Id 为键,则在将其添加到地图之前,您需要一个 Id。这可以在客户端或通过插入查询完成。我更喜欢客户端分配密钥,因为您不必往返即可获得 Id。但是,您提出的方法似乎还可以。

我自己的 IdentityMap 实现由 Type 键入,然后 Id 使用嵌套字典。如果您的键是表范围的,这很方便。

于 2012-11-28T16:58:03.703 回答