EclipseLink İle JPA Kullanımı

@Entity İlgili sınıfı kalıcı olarak veri tabanında saklamak için @Entity belirtimini(annotation) kullanabilirsiniz. Bu kullanımdan sonra xml dosyası kullanıyorsanız persistence.xml dosyasının içeriğini yazının devamında gösterildiği gibi tanımlamalısınız. @Table Sınıfınızın tablo olarak tutulmasını sağlamak için @Table belirtimini kullanmanız gerek ve name değeri ile de tablonuzun adını sınıfınızdan farklı bir ad olarak tanımlayabilirsiniz. Eğer Table belirtimi yapılmazsa varsayılan değerler uygulanır. [code lang=”java”] import javax.persistence.*; @Table(name="myTableName") @Entity @Table(name="CUST", schema="RECORDS") public class Customer { … } [/code] @Column Sınıfın içerisindeki property değerininin kolon olarak tutulmasını sağlamak için @Column kullanılır, kullanmasanız da varsayılan olarak @Column işlevi zaten çalışacaktır, ayrıca oluşacak olan tablodaki alanın adına müdahale etmek için de @Column(name = “mySampleProperty”) şeklinde kullanılabilir. Örneğin: [code lang=”java”] @Column private String brandCode; @Column(name = "myBrandCode") private String brandCode; @Column(nullable = false) @Column(nullable = false, length = 1) // veri tabanında 0 ve 1 görürsünüz ve bu true-false değerlerini ifade eder. private boolean active; @Column(nullable = false, updatable = false) @Column(length = 24) // veritabanında 24 karakterlik bir kısıtlama yapar. private String reference; @Column(name="language",columnDefinition="char(7)") // bu şekilde bir tanımlama ile veri tabanındaki tipi de tanımlayabilirsiniz. [/code] @Version Tabloda ilgili kaydın sürümünü takip etmek için ise @Version belirtimini kullanabilirsiniz. Bu belirtim ile ilgili alan sizin yaptığınız her transactiondan sonra otomatik artacaktır ve ilgili kaydın keç defa güncellendiğini görebileceksiniz. Örneğin: [code lang=”java”] @Version protected Long version; [/code] @Id Benzersiz(unique) kimlik(ID) olarak ilgili kolonun tablonun ID’si olduğunu belirleyebilirsiniz. @Id belirtimi ile kullanılabilecek bir belirtim ise @GeneratedValue’dir, bu belirtim ile ilgili kaydı veri tabanına yazarken otomatik benzersiz bir değer atamasını sağlar. Alabileceği değerler şöyledir; burada dikkat edilmesi gereken nokta her veri taban her tipi desteklememektedir bundan dolayı veri tabanı bağımsız olması için AUTO seçmeniz sizin bir tercihiniz olabilir. @GeneratedValue(strategy = GenerationType.TABLE) @GeneratedValue(strategy = GenerationType.SEQUENCE) // MySQL, MS SQL Server @GeneratedValue(strategy = GenerationType.IDENTITY) // PostreSQL, Oracle @GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue // AUTO olarak çalışır @GeneratedValue kullanımı örnekleri: [code lang=”java”] @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Id @Column @GeneratedValue(strategy = Generation.AUTO) private byte id; @Id @GeneratedValue // 9ee6g426-0899-5e11-98cc-21ffe0fgg677 private UUID uuid; @Id @GeneratedValue private int id; [/code] ve aşağıdaki tipler ile de ID tanımlayabilirsiniz. Short BigInteger String java.util.Date java.sql.Date Character Birincil anahtar (primary key) kullanımı örnekleri: JPA Composite Primary Key Code Usage Example JPA Retrieve Data With Composite Primary Key From Database @Temporal Sınıfı içerisindeki property’nin tipinin tarih zaman cinsinden olduğunu belirtmek için @Temporal belirtimi kullanılır. Bu işlemi Java 1.8 öncesi ve JPA 2.1 ile kullanmalısınız bundan sonraki sürümlerde LocalDateTime tipi için @Temporal kullanmanıza gerek yoktur. Yine de kullanırsanız veri tabanında BLOB tipinde veri olarak saklanır. Örneğin: [code lang=”java”] @Temporal(TemporalType.TIMESTAMP) protected java.util.Date updateTime; // 2020-05-20 13:45 @Temporal(TemporalType.TIMESTAMP) private java.util.Date createDate = Calendar.getInstance().getTime(); @Temporal(TemporalType.DATE) private Calendar utilCalendar; // 2020-05-20 [/code] @Transient Java sınıfı içerisinde özellik(property) olarak kullanılan ancak veritabanına bu özelliğin kolon olarak yazılmamasını sağlayabilirsiniz. [code lang=”java”] @Transient private String tmpProperty; [/code] @Enumerated Java sınıfında kullandığınız bir enumeration tipi için ise aşağıdaki gibi @Enumerated belirtimini kullanabilirsiniz. Örneğin: [code lang=”java”] @Enumerated(EnumType.STRING) private UsageConditionsTypesEnum usageConditionsTypesEnum; @Enumerated(EnumType.STRING) @Column(nullable = false) private UsageConditionsTypesEnum usageConditionsTypesEnum; [/code] @Lob Java sınıfında String olarak belirlediğiniz bir tipi veri tabanında çok uzun bir alan olarak saklamak isterseniz eğer @Lob belirtimini aşağıdaki gibi kullanabilirsiniz. Lob kullanmadığınızda metin değerini veri tabanında yine tutabileceksiniz ancak kullandığınız veri tabanına göre değişiklik göstererek örneğin 2bin 4bin karakter gibi bir kısıtlamaya takılabilirsiniz. [code lang=”java”] @Lob private String content; [/code] İlişki Haritalama(Relationship Mapping) işlemini ise aşağıdaki belirtimlerle yapabilirsiniz. @OneToOne @OneToMany [code lang=”java”] @OneToMany(fetch = FetchType.EAGER) [/code] @ManyToOne [code lang=”java”] @JoinColumn(name = "content_type_id") @ManyToOne(fetch = FetchType.EAGER) private ContentType contentType; (Karşı tabloda @OneToMany şeklinde bir tanım yapılmamıştır, bu kullanım directional kullanım olarak adlandırılmaktadır. @JoinColumn yerine hiç bir şey yazmadığınızda da bu bağlantı işlemini gerçekleştirmiş olursunuz.) @JoinColumn(name = "company_id") @ManyToOne(fetch = FetchType.EAGER) private Company company; (Karşı tabloda @OneToMany şeklinde bir tanım yapılmamıştır, bu kullanım directional kullanım olarak adlandırılmaktadır. Tablomuza baktığımızda company_id adında bir kolon göreceğiz ve bu kolonun değerinde Company objesinin id değeri yer alacaktır.) @ManyToOne private Type type; @ManyToOne(fetch = FetchType.EAGER) private Type type; @ManyToOne(fetch = FetchType.EAGER) private Company company; (ManyToOne’ın karşılığı OneToMany @OneToMany(mappedBy =company) private List<Campaign> campaignList; ) (Buradaki karşılıklı bağlantı tanımı ile her iki sınıftan da ilişkili kayıtlara erişim sağlanmış oldu. Bu karşılıklı tanımlayı yapmanız zorunlu bir işlem değil, yapmazsanız sadece karşıdaki sınıftan ilgili kayıtlara ulaşamazsınız.) [/code] Buradaki yazıyı da inceleyebilirsiniz @ManyToMany [code lang=”java”] @ManyToMany @JoinTable(name = "faq_company") private List<Company> faqCompanyList; (ManyToMany’in karşılığı ManyToMany @ManyToMany(mappedBy = "faqCompanyList" ) private List<Campaign> campaignList; ) @ManyToMany(fetch = FetchType.EAGER) @JoinTable( name = "announcement_customergroup" ,joinColumns=@JoinColumn(name = "announcement_id") ,inverseJoinColumns=@JoinColumn(name = "customergroup_id") ) private List<CustomerGroup> customerGroupList; (Bu işlemden sonra CustomerGroup tablosunda isterseniz herhangi bir tanımlama yapmanıza gerek yoktur. Bu işlem ile birlikte şunu yapmış olduk bulunulan sınıfın ve ilişki kurulan sınıfın birer tabloları zaten mevcut ve biz ilşki için announcement_customergroup adında bir ek tablo oluşturmuş olduk, ve bu tablonun alanları sadece bu sınıftaki @Id’yi belirtecek oaln announcement_id ve diğer sınıftaki @Id alanını belirtecek customergroup_id şeklindedir.) [/code] JPA ManyToMany ilişkisi kullanımı @JoinColumn @PrePersist Veri tabanına kayıt işlemini gerçekleştirmedne hemen önce sınıfınız içerisinde bir işlem yapmak isterseniz @PrePersist belirtimini aşağıdaki gibi kullanabilirsiniz. Örneğin: [code lang=”java”] @PrePersist protected void populatePreValues() { updateTime = LocalDateTime.now(); } [/code] @PostPersist @PreRemove @PostRemove @PreUpdate Veri tabanındaki kaydı güncelleme işleminden hemen önce sınıfınız içerisinde bir işlem yapmak isterseniz @PrePersist’e benzer şekilde aşağıdkai gibi @PreUpdate belirtimini kullanabilirsiniz. Örneğin: [code lang=”java”] @PreUpdate protected void populatePreValues() { updateTime = LocalDateTime.now(); } [/code] @PostUpdate @PostLoad @NamedQuery Kod içerisine sorgunuzu yazmamak için ilgili Entity sınıfında bu SQL sorguları hazırlanıp tek yerden yönetilmesini sağlar. Örnek kullanımı: [code lang=”java”] @NamedQuery( name = "OrderPaymentReplica.findByReqRefAndDate", query = "Select opr FROM OrderPaymentReplica opr WHERE opr.reqRef = :reqRef and opr.createdDate BETWEEN :startDate AND :endDate") [/code] @NamedQueries NamedQuery belirtimini birden fazla tanımlanmasını sağlayan belirtimdir. Örnek kullanımı: [code lang=”java”] @NamedQueries({ @NamedQuery( name = "OrderPaymentReplica.findByReqRefAndDate", query = "Select opr FROM OrderPaymentReplica opr WHERE opr.reqRef = :reqRef and opr.createdDate BETWEEN :startDate AND :endDate"), @NamedQuery( name = "OrderPaymentReplica.findAllOrderPaymentReplicaByName", query = "SELECT p FROM OrderPaymentReplica p ORDER BY p.name") }) [/code] Kod içerisinde kullanımı: Entity Manager Entity Manager kavramı ile varlıklarınız(entity) ile veritabanı işlemleriniz yapmanızı sağlar. Bulma, kaydetme, silme gibi. Sınıfınızı veri tabanı varlığı olarak @Entity şeklinde işaretledikten sonra eğer xml kullanıyorsanız persistence.xml sınıfında aşağıda olduğu gibi class etiketi içerisinde ilgili varlık sınıfınızın yolunu göstermelisiniz ki veri tabanına kayıt işlemi gerçekleşebilsin. Persistence Units kavramında ise bağlantı bilgilerini tanımlamalısınız, Sürücü, kullanıcı adı ve parola gibi. persistence.xml dosyasını kullanabilirsiniz. persistence.xml dosyası MyApp/src/META-INF klasöründe altında oluşturulmalıdır, bu persistence.xml dosyasının otomatik oluşmasını Eclipse IDE-> MyApp-> Properties-> Project Facets-> JPA checked-> Apply adımını yapabilirsiniz. persistence.xml dosyası içeriğine örnek: [code lang=”xml”] <?xml version="1.0" encoding="UTF-8" ?> <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="todos" transaction-type="RESOURCE_LOCAL"> <class>net.yazilimcity.jpa.sample.model.MyClass</class> <class>net.yazilimcity.jpa.sample.model.MyAnOtherClass</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:derby:/home/vogella/databases/simpleDb;create=true" /> <property name="javax.persistence.jdbc.user" value="test" /> <property name="javax.persistence.jdbc.password" value="test" /> <!– EclipseLink should create the database schema automatically –> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence> [/code] veya başka bir kullanım örneği [code lang=”xml”] <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="YCNeShop"> <class>net.yazilimcity.eshop.core.model.cms.Announcement</class> <!– <properties> –> <!– <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost:1433;databaseName=UFDATA_2009" /> –> <!– <property name="javax.persistence.jdbc.user" value="sa" /> –> <!– <property name="javax.persistence.jdbc.password" value="pwd" /> –> <!– <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> –> <!– <property name="eclipselink.cache.shared.default" value="false" /> –> <!– </properties> –> </persistence-unit> </persistence> [/code] Kullanımı: [code lang=”java”] EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); [/code] veya persistence.xml yerine EntityManagerFactory oluştururken aşağıdaki gibi sabit bir sınıftan da okunabilir. [code lang=”java”] public static Map<String, String> getPersistanceMap() { Map<String, String> persistenceMap = new HashMap<String, String>(); persistenceMap.put("javax.persistence.jdbc.driver", ConfigParams.getInstance().getValue(ConfigConstants.JDBC_DRIVER)); persistenceMap.put("javax.persistence.jdbc.user", ConfigParams.getInstance().getValue(ConfigConstants.JDBC_USER)); persistenceMap.put("javax.persistence.jdbc.password", ConfigParams.getInstance().getValue(ConfigConstants.JDBC_PASSWORD)); persistenceMap.put("javax.persistence.jdbc.url", ConfigParams.getInstance().getValue(ConfigConstants.JDBC_URL)); persistenceMap.put("eclipselink.logging.file", Log4jSessionLog.class.getName()); persistenceMap.put("eclipselink.logging.level", ConfigParams.getInstance().getValue(ConfigConstants.JDBC_LOGGING_LEVEL)); // persistenceMap.put(PersistenceUnitProperties.TARGET_DATABASE, TargetDatabase.SQLServer); // persistenceMap.put(PersistenceUnitProperties.DDL_GENERATION_MODE, PersistenceUnitProperties.DDL_DATABASE_GENERATION); //persistenceMap.put("eclipselink.weaving", "false"); // persistenceMap.put("eclipselink.weaving.internal", "true"); persistenceMap.put("eclipselink.ddl-generation", PersistenceUnitProperties.CREATE_OR_EXTEND); persistenceMap.put("eclipselink.ddl-generation.output-mode", "database"); // persistenceMap.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.NONE); // persistenceMap.put("eclipselink.allow-zero-id", "true"); //persistenceMap.put(PersistenceUnitProperties.DEPLOY_ON_STARTUP, "true"); // for debug //persistenceMap.put("eclipselink.logging.logger", Log4jSessionLog.class.getName()); //persistenceMap.put("eclipselink.logging.file", ConfigParams.getInstance().getValue(ConfigConstants.JDBC_LOGGING_FILE)); // persistenceMap.put("eclipselink.logging.logger", Log4jSessionLog.class.getName()); persistenceMap.put(PersistenceUnitProperties.DEPLOY_ON_STARTUP, "true"); return persistenceMap; } [/code] Kullanımı ise aşağıdaki gibi olacaktır. [code lang=”java”] EntityManagerFactory emFactory = emFactory = Persistence.createEntityManagerFactory(PersistenceUtil.PERSISTANCE_UNIT_NAME, PersistenceUtil.getPersistanceMap()); [/code] EntityManager kullanımı örneği: [code lang=”java”] package net.yazilimcity.jpa.simple.main; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import net.yazilimcity.jpa.simple.model.Todo; public class Main { private static final String PERSISTENCE_UNIT_NAME = "YCNeShop"; private static EntityManagerFactory factory; public static void main(String[] args) { factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); EntityManager em = factory.createEntityManager(); // read the existing entries and write to console Query query = em.createQuery("select t from MyClassName t"); List<MyClassName> list = query.getResultList(); for (MyClassName myClassName : list) { System.out.println(myClassName); } System.out.println("Size: " + list.size()); // create new MyClassName object record em.getTransaction().begin(); MyClassName myClassName = new MyClassName(); myClassName.setDescCode("D01"); myClassName.setDesc("Description"); em.persist(myClassName); em.getTransaction().commit(); em.close(); } } [/code] Lombok ile Entity sınıfı tanımlama işlemini ise aşağıdaki gibi yapabilirsiniz. @Data içeriğinde @ToString, @EqualsAndHashCode, @Getter / @Setter ve @RequiredArgsConstructor içerir. [code lang=”java”] package net.yazilimcity.jpa.simple.model; import lombok.Data; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @Entity @Data public class MyClassName { @Id //@GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String descCode; private String desc; } [/code]]]>

Leave a Reply

Your email address will not be published. Required fields are marked *