29 Ocak 2015 Perşembe

Jsf Hibernate CRUD


     Daha önceki yazılarımda elimden geldiğince Jsf ile ilgili konulardan bahsetmiştim. Bu yazımın konusu ise okuma , yazma , silme ve güncellemedir. Şimdiye kadar ki Jsf  çalışmalarımda veri tabanı bağlantı ve işlemleri için Hibernate yi tercih etmiştim , bu yazımdaki örnek kodların bir kısmı da HQL mantığıyla bir kısmını da bildiğimiz SQL cümleleri ile gerçekleştirdim. Bunun sebebi HQL ile bazı işlemleri yapmak hem karmaşık hemde hataya sebep olabiliyor.


     Ayrıca bu dört işlem için küçük bir uygulama da yazdım , bu örnek kodları onun içerisinden alıyorum. Eğer isterseniz buradaki Github linkinden erişebilirsiniz. Örneğimiz şöyle ; bir veya birden fazla blog adresimiz var ve bu uygulamada hangi blogda hangi yazılar var ,bu yazılar kaç kez okunmuş , kaç yorum var gibi bilgiler mevcut biz de bunlar üzerinde işlemler yapıyoruz.

Create

public boolean saveUser(String ad, String soyad, String sifre) {
        ses = hu.getSessionFactory().openSession();
        ses.beginTransaction();
        Query q = ses.createSQLQuery("insert into user(ad,soyad,sifre) values(:ad,:soyad,:sifre)")
                .setParameter("ad", ad)
                .setParameter("soyad", soyad)
                .setParameter("sifre", sifre);
        int i = q.executeUpdate();
        ses.getTransaction().commit();
        ses.close();
        return true;
    }

     ses.createQuery(...) normal bir HQL ifadesidir. Yukarıdaki gibi  "SQL" eklediğimiz eklediğimiz zaman standart SQL cümleleri yazabiliriz. executeUpdate() integer değer dönderir ve kaydın başarılı bir şekilde eklenebilmesi için gereklidir.

Read

public List blogGetir(int id) {
        List blog = new ArrayList<>();
        Blog blg = new Blog();
        ses = hu.getSessionFactory().openSession();
        ses.beginTransaction();
        Query q = ses.createQuery("from Blog b join b.user where b.user.uid=:uid")
                .setParameter("uid", id);
        Iterator iter = q.list().iterator();
        Object[] obje;
        while (iter.hasNext()) {
            obje = (Object[]) iter.next();
            blg = (Blog) obje[0];
            blog.add(blg);
        }

        ses.getTransaction().commit();
        ses.close();
        return blog;
    }

     Bu örneği daha önceki yazılarımda belirtmiştim. Join şeklindeki bir sorguyu iterator yardımıyla pojoya yerleştirip List döndererek üzerinde istediğimiz işlemi yapabiliriz. Create de olduğu gibi executeUpdate()  olmadan da çalışacaktır.

Update

public boolean yaziUpdate(String blogAd, String yaziAd, String konu,
            Integer shows, Date tarih, Integer yorum, int id)  throws ParseException {
        boolean sonuc;
        ses = hu.getSessionFactory().openSession();
        try {
            ses.beginTransaction();
            Query q = ses.createSQLQuery("update blog b set blog_ad=:blog_ad , "
                    + "yazi_ad=:yazi_ad , konu=:konu , shows=:shows , tarih=:tarih , yorum=:yorum where b.bid=:bid")
                    .setParameter("blog_ad", blogAd)
                    .setParameter("konu",konu)
                    .setParameter("shows", shows)
                    .setParameter("tarih",tarih)
                    .setParameter("yazi_ad",yaziAd)
                    .setParameter("yorum",yorum)
                    .setParameter("bid",id);
            int a = q.executeUpdate();
            ses.getTransaction().commit();
            sonuc = true;
        } catch (Exception e) {
            sonuc = false;
        } finally {
            ses.close();
        }
        return sonuc;
    }

     Burada Bean içerisine aldığım yeni değerleri fonksiyonla göderip güncelleme yapıyorum. Güncelleyeceğim sütunun id sini de buraya gönderiyorum. Eğer eklemezsek o tablodaki bütün değerleri aynı olacak şekilde güncelleyebilir! o yüzden "where" kısmını unutmayalım. Ayrıca dikkatli bakarsanız burada tarih(Date) güncellemesi yapıyoruz. Dolayısıyla String bir ifadeyi direk tarih olarak ekleyemeyiz , hata verir. Bu hatayı engellemek için String ifadeyi Date formatında parse etmeliyiz. Ben bunu ManagedBean içerisinde aşağıdaki gibi yapmıştım;


 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 Date parseDate = sdf.parse(tarih);

Delete



 public void yaziSil(int id) {
        ses = hu.getSessionFactory().openSession();
        try {
            ses.beginTransaction();
            Query q = ses.createQuery("delete from Blog b where b.bid=:bid")
                    .setParameter("bid", id);
            int a = q.executeUpdate();
            ses.getTransaction().commit();
        } catch (Exception e) {
            throw e;
        } finally {
            ses.close();
        }
    }


     Kayıt silerken de yukarıdaki gibi id bilgisine göre silebiliriz. Belki dikkatinizi çekmiştir ilk ikisinde try catch finally bloğu yok son ikisinde var , daha düzenli ve hata yakalayabilmek için bu yapıyı da kullanabiliriz. Uygulamanın tamamlanmış halini aşağıdaki videodan izleyebilirsiniz!


22 Ocak 2015 Perşembe

Jsf Authentication & Web Filter



     Bu yazımın temel konusu yetkilendirme ve web filtresini beraber  oluşturmak. Buradaki yetkilendirmeden kastımız kullanıcının login olma durumudur. Web Filter da ise kullanıcının sayfalar arası gezerken bizim yapmak istediğimiz kontrollerdir. Örneğin kişi sisteme giriş yapmamışsa anasayfaya erişememeli , giriş yapmışsa anasayfaya erişebilmeli. Bu ve buna benzer kullanıcı tarafından gelen isteklerin  kontrol edilmesini biz Web Filter ile sağlarız. 


     Web Filter tek bir sayfaya uygulanabileceği gibi birkaç sayfaya veya bütün sayfalara uygulanabilir. Aşağıda yeri geldiği zaman bunun nasıl yapıldığını hatırlatacağım.


    Yapmamız gerekenler;



  1. Web Filter class ı oluşturmak
  2. Web.xml dosyasına Web Filter kodunu yazmak
  3. Session ile Kullanıcı Yetkilendirme



1.Web Filter

   Web Filter class ını NetBeans kullanıyorasanız otomatik oluşturabilirsiniz. Ya da normal bir class oluşturarak "Filter" implements ederiz ve bütün implement metodlarını oluştururuz. Daha sonra aşağıdaki gibi annotation ekleyerek web filterin hangi sayfayalarda uygulanacağını *.xhtml kısmını değiştirerek belirleyebiliriz.

    Aşağıdaki kodda asıl işi doFilter(...) ile yapıyoruz. Burada eğer istek var ve giriş yapılmışsa faces-config.xml e göre yönlendiriyor , giriş yapılmamışsa direk login.xhml e yönlendiriyor. Giriş yapmayan kişinin login sayfası hariç diğer bütün sayfalara erişimi engelleniyor.



@WebFilter(filterName = "AuthFilter", urlPatterns = {"*.xhtml"})
public class AuthFilter implements Filter {


AuthFilter.java



import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
@WebFilter(filterName = "AuthFilter", urlPatterns = {"*.xhtml"})
public class AuthFilter implements Filter {
     
    public AuthFilter() {
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
         
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
         try {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse res = (HttpServletResponse) response;
            HttpSession ses = req.getSession(false);
            String reqURI = req.getRequestURI();
            if ( reqURI.indexOf("/login.xhtml") >= 0 || (ses != null && ses.getAttribute("username") != null)
                                       || reqURI.indexOf("/public/") >= 0 || reqURI.contains("javax.faces.resource") )
                   chain.doFilter(request, response);
            else
                   res.sendRedirect(req.getContextPath() + "/login.xhtml"); 
                   
      }
     catch(Throwable t) {
         System.out.println( t.getMessage());
     }
    } //doFilter
 
    @Override
    public void destroy() {
         
    }
}


Gerekli yetkilendirmeyi yapabilmek için yardımcı class ım aşağıdaki gibidir



Util.java




import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class Util {

    public static HttpSession getSession() {
        return (HttpSession) FacesContext.
                getCurrentInstance().
                getExternalContext().
                getSession(false);
    }

    public static HttpServletRequest getRequest() {
        return (HttpServletRequest) FacesContext.
                getCurrentInstance().
                getExternalContext().getRequest();
    }

    public static String getUserName() {
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        return session.getAttribute("username").toString();
    }

    public static String getUserId() {
        HttpSession session = getSession();
        if (session != null) {
            return (String) session.getAttribute("userid");
        } else {
            return null;
        }
    }
}

  

2. Web.xml 

    Bu oluşturduğum Web Filter i web.xml de belirtmeliyim yoksa hata verir.

web.xml

3.Session ile Kullanıcı Yetkilendirme

     Aşağıda görüldüğü gibi HttpSession nesnemizi giriş yapan kişinin adı ile set ediyoruz.

loginBean.java



public String login() {

        sonuc = lc.login(this.ad, this.sifre);
        if (sonuc) {
            HttpSession hs = Util.getSession();
            hs.setAttribute("username", ad);
            return "anasayfa.xhtml";
        } else {
            return "login.xhtml";
        }

    }

18 Ocak 2015 Pazar

JSF PrimeFaces Hibernate dataTable with Joins


     JSF öğrenmeye başladığımdan beri en çok takıldığım noktalardan birisi de birkaç tablodan ortak veri çekip bu verileri dataTable(PrimeFaces)  içerisinde göstermek ve üzerinde işlemler yapmak oldu. Belki de bu problemi aşmak çok kolaydı ve ben amatör olduğum için aşamamış olabilirim. Yine de kayda değer bir konu olduğunu düşündüğüm için burada bu konudan bahsedeceğim.

     Elimizde "user" ve  "blog" adında iki tablomuz var ve aşağıda bunlar bu tablolara denk gelen POJO lardır.. User da kullanıcı bilgileri , blog da ise kullanıcının yazdığı yazıların bilgileri var. Ben de aşağıda olduğu gibi sorgu ile iki tablodaki verileri çekiyorum. Buradaki benim asıl sıkıntım dönen sorgudaki veriler ile pojom tam eşleşmediği için hata alıyordum. Yani blog = q.list() dediğimde veriler aslında pojoya yerleştirilemiyor. Çözüm olarak aşağıdaki gibi önce iterator içerisine sonra object dizisine son olarakta pojoma yerleştiriyorum. Böylece bu problemi halletmiş oluyoruz.

     Daha sonra dataTable üzerinde her türlü işlemi sorunsuz yapabiliyoruz. Bunun haricinde daha kolay bir yöntemi de olabilir. Ancak ben bilmiyorum. Eğer siz biliyorsanız beni de bilgilendirirseniz sevinirim!



public List blogGetir(int id) {
        List blog = new ArrayList<>();
        Blog blg = new Blog();
        ses = hu.getSessionFactory().openSession();
        ses.beginTransaction();
        Query q = ses.createQuery("from Blog b join b.user where b.user.uid=:uid")
                .setParameter("uid", id);
        Iterator iter = q.list().iterator();
        Object[] obje;
        while (iter.hasNext()) {
            obje = (Object[]) iter.next();
            blg = (Blog) obje[0];
            blog.add(blg);
        }

        ses.getTransaction().commit();
        ses.close();
        return blog;
    }
Aşağıda bu yöntemi kullanmadan tek tablodan veri çekmiştim , isterseniz izleyip bu bahsettiğim olayın kısmen uygulanışını görebilirsiniz.

13 Ocak 2015 Salı

Hasta Bilgi Sistemi


          Hastanelere gittiğimizde ve tedavi olduğumuzda bizim ile alakalı teşhisleri , tedavi yöntemleri ve verdiği ilaçları doktorlar veri tabanına kaydetmekte. Tedavi sonucunda ise bize reçete numarasını yazarak veriyor , istediğimiz eczaneden bu numara ve TC No ile ilaçlarımızı alabiliyoruz. Sonuç olarak teknoloji bizim işimizi oldukça kolaylaştırıyor.(Tabi ki Medula çökerse tüm Türkiye'de ilaç satışları duruyor , ancak bunlar binde bir olur!)

          Ama bizim bu veri tabanlarına erişme ve muayene bilgilerini , reçete bilgilerini , anne veya baba isek çocuğumuzun muayene , aşı vs. görmemizi sağlayan bir sistem mevcut değil.(Yanlış biliyorsam düzeltin!) Sonuçta e-reçete uygulaması ile verilen numara ile eczaneye gidiyoruz ve bize ilaç veriyor. Bize ilacın aslını mı yoksa muadilini mi veriyor , eğer raporlu isek rapora göre mi ilaç giriyor yoksa daha fazlasını mı giriyor gibi durumları görebilmemiz gerektiğini düşünüyorum. 

          Bu amaçla bende bu bahsettiklerimden yola çıkarak HBS adında kendimce bir çalışma yaptım. Bu sistemde birey ve personel girişi mevcut olacak. Bunlardan personel girişi ve personelin sistemde yapabileceklerinden bahsedeyim. Personel girişi ile Ambulans personeli harita üzerinden aradığı adresi kolayca bulacak.(google map) Eğer kişinin evini arıyorlarsa direk TC No ile harita üzerinde adres işaretli olarak getirilecek. Kişinin TC No'su ile kalıcı hastalığı , alerji durumu gibi bilgilere de erişebilecektir. Sonuç itibariyle acil müdahalede bunlar hayati önem arz edebilir. 

          Birey girişinde ise bireye ait adres bilgileri , aile bireyleri (aile soy ağacı) , reçete bilgileri , muayene olduğu hastane ve doktor bilgileri , kalıcı hastalık ve alerji durumu gibi bireysel bilgilerine erişebilecek. Adresini güncelleyebilecek. Reçete , muayene bilgilerini Excel ve PDF formatında çıktı alabilecek.

          Bir de her iki girişten giren kullanıcılara ortak sunulan bilgiler mevcut olacaktır. Bunlar hastane ve eczane konumları (haritada işaretli) , ilaç bilgileridir.(kullanım , etken madde , SGK durumu vs)

           Aşağıdaki videodan çalışmamın son halini görebilirsiniz!




Kaynak Kod: https://github.com/Guvenir/Hasta-Bilgi-Sistemi

8 Ocak 2015 Perşembe

Aile Hekimliği Bilgi Sistemi





          Öncelikle bu çalışma benim staj projemdi ve 1 ay boyunca bu proje ile uğraştım. Bu benim ilk web sitesi çalışmam olduğu için son derece amatör bir iş oldu. Ama bir işte de uzmanlaşmak için bu tarz deneyimler şart. Bir anda kimse bir işte uzmanlaşamaz tabi ki. Geçen bu bir ay içerisinde CSS , JSF , Primefaces , Hibernate , Ajax gibi teknolojileri tanıma ve öğrenme çabasında oldum. Bu saydığım teknolojileri kullanabildiğim ölçüde staj projemde kullandım. Şuanda da yine aynı teknolojileri kullanarak yeni ve daha iyi bir proje çalışmam devam ediyor. Bitirdiğimde yine bu blog üzerinden paylaşırım. Aşağıda AHBS ' nin ne işe yaradığını kısmen anlatmaya çalıştım. Paragraf aralarında ise projemden aldığım ekran görüntüleri bulunmaktadır.




          Aile Hekimliği Bil Sistemi günümüzde neredeyse doktorların tamamının kullandığı bir sistemdir. AHBS doktorların kolay bir şekilde hasta bilgileri kayıt etmesini , güncellemesini , silmesini ve verilerin düzenli bir şekilde saklanmasını sağlar. Ayrıca bu sistemlerde ilaç bilgilileri , müdahale bilgileri , muayene bilgileri , randevu bilgileri , yeni doğan bilgileri gibi daha da çoğaltabileceğimiz bilgiler de saklanır. Aynı şekilde bu sistemler saklanan verileri işleyerek doktorun veya doktorun yanında bulunan hemşirenin işini kolaylaştırır. Örneğin yeni doğan kayıtları ile aşı takvimleri ve kontrol zamanları belirlenir , bu da takibi yapması gereken hemşirenin işini oldukça kolaylaştırır. Bu ve benzeri bilgilerin saklanabilmesi için her kullanıcının bilgisayarına yazılım ile birlikte yerel veritabanı kurulur.




          Bu sistemlerin doktorlar ve hemşireleri tarafından kullanılması Sağlık Bakanlığı tarafından da desteklenmektedir. Yukarıda bu sistemlerin bilgileri sakladığından ve bu bilgileri işleyerek doktor  ve hemşirenin işlerinin kolaylaştırdığından bahsettim. Diğer önemli bir özelliği ise hastalar ile ilgili yapılan işlemlerin bilgilerinin Sağlık Bakanlığı veritabanına gönderilmesidir. Bu doktorları çifte iş yapmaktan kurtarmakta ve hızlı bir şekilde muayene yapmasını sağlamakta ve aynı zamanda hasta bilgilerini sürekli olarak güncel tutmaktadır.





Aile Hekimliği Bilgi Sistemlerinde gerekli olan çeşitli raporlarda program içerisine dahil edilmiş olarak doktorların hizmetine sunulmaktadır. Bunun yanı sıra Sağlık Bakanlığı veritabanı ile hasta eşleştirme gibi özellikleri de vardır. Daha sayamayacağımız birçok özellikte bu sistemlerde bulunabilmektedir. Günümüzde sıkça kullanılan bu sistemler yeni oluşan şartlara göre sürekli gelişmesi gerekmektedir.




          Sonuç olarak bu sistemler doktorların her türlü ihtiyacına cevap verebilen , yapılan işlerin kaydını düzenli olarak tutan ve bunları bakanlığın veritabanına gönderen , çocuk izlem-gebe izlem ,aşı takvimi gibi hesaplamaları yapan sistemlerdir. Ancak bu tarz yapılacak olan projelerin uygulamaya konulabilmesi için gerekli bakanlıklar ve kurumlardan izin alınmalıdır.




5 Ocak 2015 Pazartesi

El Tipi GPS Cihazı



          Bu çalışmayı donanım stajımda gerçekleştirdim. Geçen bir aylık süre içerisinde elimde MSP 430 ve Arduino Uno mevcuttu. Ben bunlardan Arduino'yu daha yaygın ve programlaması kolay olduğunu bildiğim için tercih ettim. MSP 430 da Texas Instruments firmasının kolay programlanabilmesi için Arduino tarzı bir geliştirme kartıdır. MSP 430 IDE si ücretsiz olarak sitesinden indirilebiliyor. Tam incelemedim ancak göz attığım kadarıyla C++ a çok yakın bir kod yapısı gördüm.



          Çalıştığım yer bir Elektrik-Elektronik Mühendisi nin kendi işlettiği bir yeriydi. Genel çalışmaları ise ev , bina tarzı yapıların elektrik projelerini çizmek , elektrik ve trafo için gerekli hesaplamaları yapmak ve dikmek , Avea – Vodafone – Turkcell için baz istasyonu kurmak üzerineydi. Genelde iş yaparken yapılan işin gps'ten konumu alınıyor ve harita üzerinde işaretlenerek yapılacak firmaya rapor ediliyordu. Bende bundan esinlenerek Arduino ile GPS Cihazı yapılabilir mi , yapılırsa maliyeti ne olur gibi kısa bir araştırma yaptım. İnternette benzer çalışmalar gördüm biraz değiştirerek biraz ekleyerek projeyi tamamladım. (El Tipi GPS fiyatları 500-2000 TL arasıda)

İhtiyaçlar;

Yazılım : Arduino IDE ve Fritzing , TinyGPS kütüphanesi
Donanım : Arduino Uno , GPS , 9 V Pil , Buton , SD Card Shield , 16x2 LCD

Projenin temel mantığı şu şekildedir;

          Ekranı , güç kaynağı , SD kart ve gps olacak , gerektiğinde biz çalıştırıp butona her bastığımızda GPS verisini SD karta kaydedecek ve ekranda konum değerlerini gösterecek, kayıt edilen dosyayı biz Google Earth içerisinde açtığımızda direk kayıtlı konumları işaretli olarak gelecek.

          GPS verilerini düzenli alabilmek için TinyGPS adında bir kütüphane mevcut. Bu kütüphaneyi import edip kolay bir şekilde verileri alabiliriz. Ekran ve SD Kart içinde aynı şekilde kütüphanesini import edip kolayca kullanabiliriz.

          Verileri aldık ama bu konum bilgilerini direk SD kart içerisine txt uzantılı olarak kaydetmiyoruz. Buradaki dosya formatımız CSV (Comma Seperated Value - Virgülle Ayrılmış Veriler) şeklinde kayıt ediyoruz. Bu dosya formatını başta MS Excel ,MS Access olmak üzere birçok veri tabanı uygulaması da açabiliyormuş. Bu yüzden çok kullanışlı. Google Earth ise KML dosya uzantısını kullanıyor. Biz kaydettiğimiz CSV dosyasını internet üzerinde kolayca KML uzantısına çevirebiliyoruz. Daha sonra Google Earth ile açıtığımızda noktalar işaretli olarak geliyor.

          Proje için detaylı araştırma yaptım hatta kodlarını bile yazdım ancak yukarıdaki donanımlar mevcut olmadığından dolayı projeyi direk deneyemedim ! Arduino Uno da yeterli pin olmayabilir.

          Deneyip görmek lazım. Aşağıda devrenin şeması ve Github linki üzerinden ulaşabileceğiniz kodları bulunmaktadır.  

1 Ocak 2015 Perşembe

Java Arduino Seri Haberleşme



          Daha önce arduino ile C# arasında seri haberleşmenin nasıl sağlandığını yazmıştım. Aynı şekilde bunun Java ile nasıl gerçekleştirileceğini de araştırdım.  Arduino ' nun kendi sitesinde ve birçok sitede bu konu mevcut. Ben yinede bu işin nasıl yapıldığından bahsetmek istedim. Bunun için kodları kendim yazmadım sadece düzenledim. Aşağıdaki linkten derlediğim kodun kaynağına erişebilirsiniz.

Java Arduino Seri Haberleşme

         Öncelikle Arduino bağlantımız için RXTX kütüphanemizi proje kütüphanemize eklemeliyiz. Bu siteden işletim sistemimize göre indirdiğimiz rar dosyasının içerisindekileri (Windows için rxtxserial.dll ve rxtxparalel.dll , Linux için rxtxserial.so ve rxtxparalel.so ) projemizin oluşturulduğu dosyanın içerisine kopyalıyoruz. Aksi taktirde program hata verecektir.

          Daha sonrasında Arduino'nun bilgisayarımızda hangi porttan bağlandığını aşağıdaki String içerisinde belirtiyoruz. Bu String ifadeyi kullanarak hangi portta bağlı olduğunu buluyor.

private static final String PORT_NAMES[] = { 
   "/dev/tty.usbserial-A9007UX1", // Mac OS X
                        "/dev/ttyACM0", // Raspberry Pi
   "/dev/ttyUSB0", // Linux
   "COM3", // Windows
 };

     Bu kodun tamamına  http://playground.arduino.cc/Interfacing/Java    adresinden erişebilirsiniz.

            Bende aynen C# ta olduğu gibi butonlar ile led yakıp söndürme işlemini burada da yaptım. Resmin altındaki linkten de çalışır haldeki kodlarına erişebilirsiniz. ino dosyasıda rar içerisinde bulunmaktadır.


Örnek Çalışma