Enterprise JavaBean3.0 (第5版)

来源:互联网 发布:win7 资源管理器 软件 编辑:程序博客网 时间:2024/05/01 03:45

1. 实体关系

    1.1 单向One-to-One (Customer 1-1 Address)

        Public class Customer implements Serializable {

            private Address homeAddress;

            @OneToOne(cascade={CascadeType.ALL})    //cascade可以不写

            @JoinColumn(name="ADRDRESS_ID")    //JoinColumn可以不写

            或者使用@PrimaryKeyJoinColumn来代替上一行

            public Address getAddress() { return homeAddress; }

            public void setAddress(Address address) { this.homeAddress = address; }

        }

    1.2 双向One-to-One (Customer 1-1 CreditCard)

        Public class Customer implements Serializable {

            private CreditCard creditCard;

            @OneToOne(cascade={CascadeType.ALL})    //cascade可以不写

            @JoinColumn(name="CREDIT_CARD_ID")    //JoinColumn可以不写

            public CreditCard getCreditCard() { return creditCard; }

            public void setCreditCard(CreditCard creditCard) { this.creditCard = creditCard; }

        }

        Public class CreditCard implements Serializable {

            private Customer customer;

            @OneToOne(mappedBy="creditCard")  

            public Customer getCustomer() { return customer; }

            public void setCustomer(Customer customer) { this.customer = customer; }

        }

        创建实例

        Customer cust = new Customer();

        CreditCard card = new CreditCard();

        cust.setCreditCard(card);

        card.setCustomer(cust);

        em.persist(cust);

        删除实例

        Customer cust = em.find(Customer.class, id);

        em.remove(cust.getCreditCard());

        cust.setCreditCard(null);    

    1.3 单向One-to-Many (Customer 1-N Phone)

        Public class Customer implements Serializable {

            private Collection<Phone> phoneNumbers = new ArrayList<Phone>();

            @OneToMany(cascade={CascadeType.ALL})    //cascade可以不写

            @JoinColumn(name="CUSTOMER_ID")    //JoinColumn可以不写

            public Collection<Phone> getPhoneNumbers() {return phoneNumbers;}

            public void setPhoneNumbers(Collection<Phone> phoneNumbers) {this.phoneNumbers = phoneNumbers;}

        }

        另外可以使用关系表映射

        Public class Customer implements Serializable {

            private Collection<Phone> phoneNumbers = new ArrayList<Phone>();

            @OneToMany(cascade={CascadeType.ALL})    //cascade可以不写

            @JoinTable(name="CUSTOMER_PHONE",

                            JoinColumns={@JoinColumn(name="CUSTOMER_ID")},

                            inverseJoinColumns={@JoinColumn(name="PHONE_ID")})

            public Collection<Phone> getPhoneNumbers() {return phoneNumbers;}

            public void setPhoneNumbers(Collection<Phone> phoneNumbers) {this.phoneNumbers = phoneNumbers;}

        }

    1.4 双向One-to-Many | Many-to-One(Cruise 1-N Reservation)

        Public class Cruise implements Serializable {

            private Collection<Reservation> reservations = new ArrayList<Reservation>();

            @OneToMany(mappedBy="cruise")

            public Collection<Reservation> getReservations() { return reservations; }

            public void setReservations(Collection<Reservation> res) { reservations = res; }

        }

        public class Reservation implements java.io.Serializable {

            private Cruise cruise;

            @ManyToOne

            @JoinColumn(name="CRUISE_ID")

            public Cruise getCruise() { return cruise; }

            public void setCruise(Cruise cruise) { this.cruise = cruise; }

        }

    1.5 单向Many-to-One (Cruise N-1 Ship)

        Public class Cruise implements Serializable {

            private Ship ship;

            @ManyToOne

            public Ship getShip() { return ship; }

            public void setShip(Ship ship) { this.ship = ship; }

        }

    1.6 单向Many-to-Many (Cabin N-N Reservation)

        Public class Reservation implements Serializable {

            private Set<Cabin> cabins = new HashSet<Cabin>();

            @ManyToMany

            @JoinTable(name="RESERVATION_CABIN",

                        joinColumns={@JoinColumn(name="RESERVATION_ID")},

                        inverseJoinColumns={@JoinColumn(name="CABIN_ID")})

            public Set<Cabin> getCabins() { return cabins; }

            public void setCabins(Set<Cabin> cabins) { this.cabins = cabins; }

        }

    1.7 双向Many-to-Many (Customer N-N Reservation)

        Public class Reservation implements Serializable {

            private Set<Customer> customers = new HashSet<Customer>();

            @ManyToMany

            @JoinTable(name="RESERVATION_CUSTOMER",

                            joinColumns={@JoinColumn(name="RESERVATION_ID")},

                            inverseJoinColumns={@JoinColumn(name="CUSTOMER_ID")})

            public Set<Customer> getCustomers() { return customers; }

            public void setCustomers(Set<Customer> customers) { this.customers = customers; }

        }

        public class Customer implements java.io.Serializable {

            private Collection<Reservation> reservations = new ArrayList<Reservation>();

            @ManyToMany(mappedBy="customers")

            public Collection<Reservation> getReservations() {return reservations;}

            public void setReservations(Collection<Reservation> reservations) {this.reservations = reservations;}

        }

2. EJB Query

    2.1 EJB QL和Native SQL由javax.persistence.Query执行

        createQuery(String ejbqlString);

        createNamedQuery(String name);

        createNativeQuery(String sqlString);

        createNativeQuery(String sqlString, Class resultClass);

        createNativeQuery(String sqlString, String resultSetMapping);

    2.2 查询示例

        String str = "SELECT c FROM Customer c WHERE c.firstName='Bill'";

        Query query = em.createQuery(str);

        Customer cust = (Customer)query.getSingleResult();    //单一结果

        java.util.List bills = query.getResultList();    //一组对象

    2.3 参数

        2.3.1 具名参数(named parameters)

                Query query = em.createQuery("SELECT c FROM Customer c WHERE c.firstName=:first");

                query.setParameter("first", first);

        2.3.2 指示参数(positional parameters)

                Query query = em.createQuery("SELECT c FROM Customer c WHERE c.firstName=?1");

                query.setParameter(1, first);

        2.3.3 日期型参数

                public enum TemporalType {DATE, TIME, TIMESTAMP}

                query.setParameter(2, Date value, TemporalType  temporalType );

    2.4 对结果分页

        query.setMaxResults(max);    //查询返回的记录数

        query.setFirstResult(index);     //结果集从哪个位置开始

        Iterator it = results.iterrator();

        while (it.hasNext()) {

            Customer c = (Customer)it.next();

            String first = (String)c[0];

            String last = (String)c[1];

        }

    2.5 Hints

        Java Persistence厂商自定义查询附加功能

        query.setHint("org.hibernate.timeout", 1000);    //JBoss定义查询超时功能

    2.6 FlushMode

        query.setFlushMode(FlushModeType.COMMIT|FlushModeType.AUTO);    //建议使用默认的AUTO

    2.7 EJB QL 

        2.7.1 选出相关联表数据

            SELECT c.creditCard FROM Customer c;

            SELECT c.address.city FROM Customer c;

            //所有Titan客运乘客所用信用卡所属公司所在的城市

            SELECT c.creditCard.creditCompany.address.city FROM Customer c;    

        2.7.2 多个字段组成一个名称

            SELECT new com.titan.domain.Name(c.firstName, c.lastName) FROM Customer c;

        2.7.3 IN和INNER JOIN

            从一个集合类型的关系属性中选择元素

            SELECT r.cruise FROM Customer c, IN(c.reservations) r;    //每个乘客预订过的所有航程

            SELECT r.cruise FROM Customer c INNER JOIN c.reservations r;    //功能同上,但和SQL更相似

            多个集合选择,所有拥有预订记录的乘客所乘坐的船只

            SELECT cbn.ship FROM Customer c INNER JOIN c.reservations r INNER JOIN r.cabins cbn;

        2.7.4 LEFT JOIN

            得到一组实体,但有些可能不存在join子句匹配,譬如所有乘客电话记录,但有些没有,还是列出姓名

            SELECT c.firstName, c.lastName, p.number FROM Customer c LEFT JOIN c.phoneNunbers p;

            SELECT c.firstName, c.lastName, p.number FROM Customer c LEFT OUTER JOIN c.phoneNunbers p;

        2.7.5 FETCH JOINS

            当从两个实体关联中查询数据,使用该方法,可以提前加载一个实体,提高性能

            SELECT c FROM Customer c LEFT JOIN FETCH c.phones;

        2.7.6 DISTINCT

            确保查询不会返回重复项

            SELECT DISTINCT cust FROM Reservation res, IN(res.customers) cust;

        2.7.7 WHERE子句

            1. 字符串使用单引号,字符串中有单引号,就使用两个'',整数和布尔型不需要

                WHERE c.firstName = 'Mary''s';

                WHERE s.ton = 10000.00

                WHERE c.hasGoodCredit = TRUE

            2. >=, <=, <>, AND, OR, NOT, BETWEEN, IN, IS NULL, IS NOT NULL, IS EMPTY, LIKE

                WHERE c.amount > 300.00

                WHERE c. ton >= 8000 AND c.ton <= 13000

                WHERE c.ton BETWEEN 8000 AND 13000

                WHERE c.ton NOT BETWEEN 8000 AND 13000

                WHERE c.address.state IN ('FL', 'TX')

                WHERE c.address IS NULL

                WHERE c.address IS NOT NULL

            3. MEMBER OF

                判断是否是关系中的一员

                WHERE cust = :myCustomer AND cust MEMBER OF res.customers

            4. 函数表达式

                LOWER, UPPER, TRIM, LENGTH, LOCATE, SUBSTRING, ABS, SQRT, MOD, COUNT, MAX, MIN, AVG

                CONCAT(String1, String2): 返回串联1和2的串, LENGTH

                时间戳: WHERE res.date = CURRENT_DATE

                SUM: 计算总数

            5. ORDER BY, GROUP BY, HAVING, EXISTS

        2.7.8 批量UPDATE和DELETE

            给所有名叫Bill Burke的乘客增收$10

            UPDATE reservation res SET res.amountPaid = (res.amountPaid + 10) WHERE EXISTS

            (SELECT c FROM res.customers c WHERE c.firstName = 'Bill' AND c.lastName='Burke')

    2.8 Native SQL

        String sqlstr = "SELECT p.phone_PK, p.phone_number FROM Phone p";

        em.createNativeQuery(sqlstr, Phone.class);

    2.9 具名查询

        预定义好EJB QL或者Native SQL

        @NamedQueries(

            @NamedQuery(name="getCustomer", query="SELECT c FROM Customer where c.firstName=?1"),

            @NamedQuery(name="findCustomer", query="SELECT c FROM Customer")

        )

        em.createNamedQuery("getCustomer");

        query.setParameter(1, "Charles");

3. 回调和监听器

    3.1 回调

        PrePersist, PostPersist, PostLoad, PreUpdate, PostUpdate, PreRemove, PostRemove

        @PrePersist void beforeInsert() {}

        定义一系列方法,可以在执行具体的操作之前或者之后,加入相应的方法

    3.2 监听器

        如果我们定义了一个Class方法,其中有很多PrePersist之类的方法,那么在执行Entity的时候,

        我们可以注册成Listeners,以实现其中的调用方法,主要是拦截Entity生命周期的事件

        @Entity

        @EntityListeners({TitanAuditLogger.class, EntityJmxNotifier.class})

        public class Cabin {}

        在Cabin执行Persist操作时,相应TitanAuditLogger中的方法就会被调用

        子类能继承基类的监听器,如果两者都定义,那么子类都会用到

4. Session Bean

    4.1 两种调用方式

        1. call-by-value: 远程接口,无论客户端是在同一JVM还是远程,EJB容器都对参数和返回值进行值拷贝

        2. call-by-reference: 本地接口,不会值拷贝

原创粉丝点击