zoukankan      html  css  js  c++  java
  • JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)

    一、自定义映射的表名

    1.

    1 @Entity
    2 @Table(name = "USERS")
    3 public class User implements Serializable {
    4     // ...
    5 }

    2.用定界符

    1 //@Table(name = "`USER`")的标准
    2 @Table(name = "`USER`")
    3 
    4 //JPA的标准
    5 @Table(name = ""USER"")

    若全部SQL都加定界符, create an orm.xml file and add the setting <delimited-identifiers/> to its <persistence-unit-defaults> section,Hibernate then enforces quoted identifiers everywhere.

    3.若要映射的表都有前缀,则可用实现PhysicalNamingStrategy接口或继承已有的实现

     1 package org.jpwh.shared;
     2 
     3 import org.hibernate.boot.model.naming.Identifier;
     4 import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
     5 
     6 /**
     7  * Prefixes all SQL table names with "CE_", for CaveatEmptor.
     8  */
     9 public class CENamingStrategy extends
    10     org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl {
    11 
    12     @Override
    13     public Identifier toPhysicalTableName(Identifier name,
    14                                           JdbcEnvironment context) {
    15         return new Identifier("CE_" + name.getText(), name.isQuoted());
    16     }
    17 
    18 }

    You have to enable the naming-strategy implementation in persistence.xml:

    1 <persistence-unit>name="CaveatEmptorPU"> 
    2     ...
    3     <properties>
    4         <property name="hibernate.physical_naming_strategy" value="org.jpwh.shared.CENamingStrategy" />
    5     </properties>
    6 </persistence-unit>

    4.用ImplicitNamingStrategy

    二、自定义实体名

    1.

    1 package my.other.model;
    2 @javax.persistence.Entity(name = "AuctionItem")
    3 public class Item {
    4     // ...
    5 }

    三、动态生成SQL

    To disable generation of INSERT and UPDATE SQL statements on startup, you need native Hibernate annotations:

    1 @Entity
    2 @org.hibernate.annotations.DynamicInsert
    3 @org.hibernate.annotations.DynamicUpdate
    4 public class Item {
    5     // ...
    6 }

    四、实体相关选项

    1.Making an entity immutable

    1 @Entity
    2 @org.hibernate.annotations.Immutable
    3 public class Bid {
    4     // ...
    5 }

    2.Mapping an entity to a subselect

    When an instance of ItemBidSummary is loaded, Hibernate executes your custom SQL
    SELECT as a subselect:

    Synchronize注解的作用:Hibernate will then know it has to flush modifications of Item and Bid instances
    before it executes a query against ItemBidSummary

     1 package org.jpwh.model.advanced;
     2 
     3 import javax.persistence.Entity;
     4 import javax.persistence.Id;
     5 
     6 @Entity
     7 @org.hibernate.annotations.Immutable
     8 @org.hibernate.annotations.Subselect(
     9     value = "select i.ID as ITEMID, i.ITEM_NAME as NAME, " +
    10             "count(b.ID) as NUMBEROFBIDS " +
    11             "from ITEM i left outer join BID b on i.ID = b.ITEM_ID " +
    12             "group by i.ID, i.ITEM_NAME"
    13 )
    14 
    15 // TODO Table names are case sensitive, Hibernate bug HHH-8430
    16 @org.hibernate.annotations.Synchronize({"Item", "Bid"})
    17 public class ItemBidSummary {
    18 
    19     @Id
    20     protected Long itemId;
    21 
    22     protected String name;
    23 
    24     protected long numberOfBids;
    25 
    26     public ItemBidSummary() {
    27     }
    28 
    29     // Getter methods...
    30     public Long getItemId() {
    31         return itemId;
    32     }
    33 
    34     public String getName() {
    35         return name;
    36     }
    37 
    38     public long getNumberOfBids() {
    39         return numberOfBids;
    40     }
    41 
    42     // ...
    43 }

    五、测试代码

    1.

     1 package org.jpwh.test.advanced;
     2 
     3 import org.jpwh.env.JPATest;
     4 import org.jpwh.model.advanced.Bid;
     5 import org.jpwh.model.advanced.Item;
     6 import org.jpwh.model.advanced.ItemBidSummary;
     7 import org.testng.annotations.Test;
     8 
     9 import javax.persistence.EntityManager;
    10 import javax.persistence.Query;
    11 import javax.transaction.UserTransaction;
    12 import java.math.BigDecimal;
    13 
    14 import static org.testng.Assert.assertEquals;
    15 
    16 public class MappedSubselect extends JPATest {
    17 
    18     @Override
    19     public void configurePersistenceUnit() throws Exception {
    20         configurePersistenceUnit("AdvancedPU");
    21     }
    22 
    23     @Test
    24     public void loadSubselectEntity() throws Exception {
    25         long ITEM_ID = storeItemAndBids();
    26 
    27         UserTransaction tx = TM.getUserTransaction();
    28         try {
    29             tx.begin();
    30             EntityManager em = JPA.createEntityManager();
    31 
    32             {
    33                 ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID);
    34                 // select * from (
    35                 //      select i.ID as ITEMID, i.ITEM_NAME as NAME, ...
    36                 // ) where ITEMID = ?
    37 
    38                 assertEquals(itemBidSummary.getName(), "AUCTION: Some item");
    39             }
    40             em.clear();
    41 
    42             { // Hibernate will synchronize the right tables before querying
    43                 Item item = em.find(Item.class, ITEM_ID);
    44                 item.setName("New name");
    45 
    46                 // No flush before retrieval by identifier!
    47                  //ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID);
    48 
    49                 // Automatic flush before queries if synchronized tables are affected!
    50                 Query query = em.createQuery(
    51                     "select ibs from ItemBidSummary ibs where ibs.itemId = :id"
    52                 );
    53                 ItemBidSummary itemBidSummary =
    54                     (ItemBidSummary)query.setParameter("id", ITEM_ID).getSingleResult();
    55 
    56                 assertEquals(itemBidSummary.getName(), "AUCTION: New name");
    57             }
    58 
    59             tx.commit();
    60             em.close();
    61         } finally {
    62             TM.rollback();
    63         }
    64     }
    65 
    66     public Long storeItemAndBids() throws Exception {
    67         UserTransaction tx = TM.getUserTransaction();
    68         tx.begin();
    69         EntityManager em = JPA.createEntityManager();
    70         Item item = new Item();
    71         item.setName("Some item");
    72         item.setDescription("This is some description.");
    73         em.persist(item);
    74         for (int i = 1; i <= 3; i++) {
    75             Bid bid = new Bid();
    76             bid.setAmount(new BigDecimal(10 + i));
    77             bid.setItem(item);
    78             em.persist(bid);
    79         }
    80         tx.commit();
    81         em.close();
    82         return item.getId();
    83     }
    84 
    85 }

     Note that Hibernate doesn’t flush automatically before a find() operation—only before a Query is executed, if necessary. Hibernate detects that the modified Item will affect the result of the query, because the ITEM table is synchronized with ItemBid-Summary . Hence, a flush and the UPDATE of the ITEM row are necessary to avoid the

    query returning stale data.

    2.

      1 package org.jpwh.model.advanced;
      2 
      3 import org.jpwh.model.Constants;
      4 
      5 import javax.persistence.Access;
      6 import javax.persistence.AccessType;
      7 import javax.persistence.Basic;
      8 import javax.persistence.Column;
      9 import javax.persistence.Entity;
     10 import javax.persistence.EnumType;
     11 import javax.persistence.Enumerated;
     12 import javax.persistence.FetchType;
     13 import javax.persistence.GeneratedValue;
     14 import javax.persistence.Id;
     15 import javax.persistence.Lob;
     16 import javax.persistence.Temporal;
     17 import javax.persistence.TemporalType;
     18 import javax.validation.constraints.NotNull;
     19 import java.math.BigDecimal;
     20 import java.sql.Blob;
     21 import java.util.Date;
     22 
     23 @Entity
     24 public class Item {
     25 
     26     /* 
     27        The <code>Item</code> entity defaults to field access, the <code>@Id</code> is on a field. (We
     28        have also moved the brittle <code>ID_GENERATOR</code> string into a constant.)
     29      */
     30     @Id
     31     @GeneratedValue(generator = Constants.ID_GENERATOR)
     32     protected Long id;
     33 
     34     @org.hibernate.annotations.Type(type = "yes_no")
     35     protected boolean verified = false;
     36 
     37     // JPA says @Temporal is required but Hibernate will default to TIMESTAMP without it
     38     @Temporal(TemporalType.TIMESTAMP)
     39     @Column(updatable = false)
     40     @org.hibernate.annotations.CreationTimestamp
     41     protected Date createdOn;
     42 
     43     // Java 8 API
     44     // protected Instant reviewedOn;
     45 
     46     @NotNull
     47     @Basic(fetch = FetchType.LAZY) // Defaults to EAGER
     48     protected String description;
     49 
     50     @Basic(fetch = FetchType.LAZY)
     51     @Column(length = 131072) // 128 kilobyte maximum for the picture
     52     protected byte[] image; // Maps to SQL VARBINARY type
     53 
     54     @Lob
     55     protected Blob imageBlob;
     56 
     57     @NotNull
     58     @Enumerated(EnumType.STRING) // Defaults to ORDINAL
     59     protected AuctionType auctionType = AuctionType.HIGHEST_BID;
     60 
     61     @org.hibernate.annotations.Formula(
     62         "substr(DESCRIPTION, 1, 12) || '...'"
     63     )
     64     protected String shortDescription;
     65 
     66     @org.hibernate.annotations.Formula(
     67         "(select avg(b.AMOUNT) from BID b where b.ITEM_ID = ID)"
     68     )
     69     protected BigDecimal averageBidAmount;
     70 
     71     @Column(name = "IMPERIALWEIGHT")
     72     @org.hibernate.annotations.ColumnTransformer(
     73         read = "IMPERIALWEIGHT / 2.20462",
     74         write = "? * 2.20462"
     75     )
     76     protected double metricWeight;
     77 
     78     @Temporal(TemporalType.TIMESTAMP)
     79     @Column(insertable = false, updatable = false)
     80     @org.hibernate.annotations.Generated(
     81         org.hibernate.annotations.GenerationTime.ALWAYS
     82     )
     83     protected Date lastModified;
     84 
     85     @Column(insertable = false)
     86     @org.hibernate.annotations.ColumnDefault("1.00")
     87     @org.hibernate.annotations.Generated(
     88         org.hibernate.annotations.GenerationTime.INSERT
     89     )
     90     protected BigDecimal initialPrice;
     91 
     92     /* 
     93         The <code>@Access(AccessType.PROPERTY)</code> setting on the <code>name</code> field switches this
     94         particular property to runtime access through getter/setter methods by the JPA provider.
     95      */
     96     @Access(AccessType.PROPERTY)
     97     @Column(name = "ITEM_NAME") // Mappings are still expected here!
     98     protected String name;
     99 
    100     /* 
    101         Hibernate will call <code>getName()</code> and <code>setName()</code> when loading and storing items.
    102      */
    103     public String getName() {
    104         return name;
    105     }
    106 
    107     public void setName(String name) {
    108         this.name =
    109             !name.startsWith("AUCTION: ") ? "AUCTION: " + name : name;
    110     }
    111 
    112     public Long getId() { // Optional but useful
    113         return id;
    114     }
    115 
    116     public String getDescription() {
    117         return description;
    118     }
    119 
    120     public void setDescription(String description) {
    121         this.description = description;
    122     }
    123 
    124     public String getShortDescription() {
    125         return shortDescription;
    126     }
    127 
    128     public BigDecimal getAverageBidAmount() {
    129         return averageBidAmount;
    130     }
    131 
    132     public double getMetricWeight() {
    133         return metricWeight;
    134     }
    135 
    136     public void setMetricWeight(double metricWeight) {
    137         this.metricWeight = metricWeight;
    138     }
    139 
    140     public Date getLastModified() {
    141         return lastModified;
    142     }
    143 
    144     public BigDecimal getInitialPrice() {
    145         return initialPrice;
    146     }
    147 
    148     public Date getCreatedOn() {
    149         return createdOn;
    150     }
    151 
    152     public boolean isVerified() {
    153         return verified;
    154     }
    155 
    156     public void setVerified(boolean verified) {
    157         this.verified = verified;
    158     }
    159 
    160     public byte[] getImage() {
    161         return image;
    162     }
    163 
    164     public void setImage(byte[] image) {
    165         this.image = image;
    166     }
    167 
    168     public Blob getImageBlob() {
    169         return imageBlob;
    170     }
    171 
    172     public void setImageBlob(Blob imageBlob) {
    173         this.imageBlob = imageBlob;
    174     }
    175 
    176     public AuctionType getAuctionType() {
    177         return auctionType;
    178     }
    179 
    180     public void setAuctionType(AuctionType auctionType) {
    181         this.auctionType = auctionType;
    182     }
    183 }

    3.

     1 package org.jpwh.model.advanced;
     2 
     3 import org.jpwh.model.Constants;
     4 
     5 import javax.persistence.Entity;
     6 import javax.persistence.FetchType;
     7 import javax.persistence.GeneratedValue;
     8 import javax.persistence.Id;
     9 import javax.persistence.JoinColumn;
    10 import javax.persistence.ManyToOne;
    11 import javax.validation.constraints.NotNull;
    12 import java.math.BigDecimal;
    13 
    14 @Entity
    15 @org.hibernate.annotations.Immutable
    16 public class Bid {
    17 
    18     @Id
    19     @GeneratedValue(generator = Constants.ID_GENERATOR)
    20     protected Long id;
    21 
    22     @NotNull
    23     protected BigDecimal amount;
    24 
    25     @ManyToOne(optional = false, fetch = FetchType.LAZY) // NOT NULL
    26     @JoinColumn(name = "ITEM_ID") // Actually the default name
    27     protected Item item;
    28 
    29     public Long getId() {
    30         return id;
    31     }
    32 
    33     public BigDecimal getAmount() {
    34         return amount;
    35     }
    36 
    37     public void setAmount(BigDecimal amount) {
    38         this.amount = amount;
    39     }
    40 
    41     public Item getItem() {
    42         return item;
    43     }
    44 
    45     public void setItem(Item item) {
    46         this.item = item;
    47     }
    48 }
  • 相关阅读:
    jsp和servlet的联系与区别
    tomcat会如何处理请求
    java中synchronized的关键字
    mybatis的动态sql
    spring自带的json转换工具,支持@ResponseBody注解
    layer一个web弹窗/层解决方案
    spring mvc出现乱码的问题
    hdu1010 Tempter of the Bone
    hdu 3342 Legal or Not
    ThreadPoolExecutor线程池执行器源码解析
  • 原文地址:https://www.cnblogs.com/shamgod/p/5351942.html
Copyright © 2011-2022 走看看