• SSH框架之Hibernate第四篇


    Hibernate中有两套实现数据库数据操作的方式 : 
            hibernate前3天讲解的都是 : hibernate自己的操作方式(纯XML配置文件的方式)
            另一种方式是基于JPA的操作方式(通过注解的方式替代之前的部分XML)
            
        JPA相关概念:
            1.1JPA概述 : (java的持久化规范(规范即接口))
                全称是 : Java Persistence API. 是SUN公司推出的一套基于ORM的规范.hibernate框架中提供了JPA的实现.
                JAP通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.
            1.2JPA要明确的
                a. JPA是一套ORM规范(算是一个接口),hibernate实现了JPA规范(算是一个实现类).
                b. hibernate中有自己的独立ORM操作数据库方式,也有JPA规范实现的操作数据库方式.
                c. 在数据库增删改查操作中,我们hibernate和JPA的操作都要会.
            JPA和hibernate的关系?
                JPA是接口,hibernate是实现.
                所有的ORM框架都可以去实现JPA接口,通过JPA提供的一些接口来操作数据库的数据.
                
            JPA的使用 : 
                JPA是通过注解的方式来描述,对象和表的映射关系.
                之前的对象和表的映射关系配置是通过XML,今天要替换成注解的方式.
                
            注释 : 给程序员看的.
            注解 : 给程序来使用的.
                为什么要出现注解?
                    一开始就是为了替代所有的XML配置文件.
                    
                    工作中两种方式结合使用 : 
                        配置文件 + 注解
                            如果是需要常常改动的程序 : 用配置文件.
                            如果是定义好了不需要更改的程序 : 注解.
                        
        2.1 2 JPA的环境搭建
            1 hibernate的环境(16个包)
            2 JPA的环境(1个包)
                
            2.2.2 创建配置文件
                    要求:在src下面的META-INF文件夹下面创建一个名称为persistence.xml的文件。
                配置文件的内容:
                    <?xml version="1.0" encoding="UTF-8"?>  
                    <persistence xmlns="http://java.sun.com/xml/ns/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_1_0.xsd"  
                        version="1.0">  
                        <!--Name属性用于定义持久化单元的名字 (name必选,空值也合法);   
                            transaction-type 指定事务类型(可选)    
                                取值:
                                    JTA:默认值
                                    RESOURCE_LOCAL
                        -->  
                        <persistence-unit name="myPersistUnit" transaction-type="RESOURCE_LOCAL">  
                           
                          <properties>    
                                <!-- 生成DDL的策略 -->
                                   <property name="hibernate.hbm2ddl.auto" value="update" />  
                                   <!-- 数据库的连接信息 -->    
                                   <property name="hibernate.connection.driver_class" 
                                            value="com.mysql.jdbc.Driver" />    
                                   <property name="hibernate.connection.url" 
                                            value="jdbc:mysql://localhost:3306/hibernate_jpa"/>  
                                   <property name="hibernate.connection.username" value="root" />    
                                   <property name="hibernate.connection.password" value="1234" />   
                                   <!-- 指定方言 -->   
                                   <property name="hibernate.dialect" 
                                            value="org.hibernate.dialect.MySQL5Dialect" />
                                   <!-- 是否显示SQL语句 -->    
                                   <property name="hibernate.show_sql" value="false" />
                                   <!-- 是否格式化SQL语句 -->    
                                   <property name="hibernate.format_sql" value="true" />   
                            </properties>    
                        </persistence-unit>  
                    </persistence> 
        
            2.2.3 编写工具类,用于获取JPA的操作数据库对象
                public class HibernateUtils {
                    //JPA的实体管理器工厂 : 相当于Hibernate的SessionFactory
                    private static EntityManagerFactory em;
                    //使用静态代码块赋值
                    static {
                        //加载一次配置文件
                        //注意 : 该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致
                        em = Persistence.createEntityManagerFactory("aaa");
                    }
                    /*
                     * 使用管理器工厂生产一个管理器对象
                     */
                    //相当于获取连接
                    public static EntityManager getEntityManager() {
                        return em.createEntityManager();
                    }
                }
            
            jpa 的批量查询方式 :
                类似咋们之前学习的query方式查询 :
                    1 : qr.getResultList() ;  类似之前的qr.list();
                    2 : hibernate对于占位符?    以前是从0开始,jpa是从1开始.
                    3 : 聚合 qr.getSingleResult();   类似之前的uniqueResult();
            
            2.2.4 编写实体类,并使用注解配置
                //级联保存 (保存客户的同时把关联的联系人给保存了)
                //jpa的注解里面 @OneToMany  添加属性cascade = CascadeType.PERSIST_STORE
                //根据一的一方保存多的一方的数据.
                // 级联保存 (保存联系人的同时把关联的客户给保存了)
                // jpa的注解里面 @ManyToOne  添加属性cascade=CascadeType.PERSIST
                //jpa的一对多没有普通删除
                // 级联删除
                // jpa的注解里面 @OneToMany  添加属性cascade=CascadeType.REMOVE (All)
            
                /**
                 * 客户的实体类
                 */
                @Entity
                @Table(name="cst_customer")
                public class Customer implements Serializable {
    
                    @Id
                    @GeneratedValue(strategy=GenerationType.IDENTITY)
                    @Column(name="cust_id")
                    private Long custId;
                    
                    @Column(name="cust_name")
                    private String custName;
                    
                    @Column(name="cust_source")
                    private String custSource;
                    
                    @Column(name="cust_industry")
                    private String custIndustry;
                    
                    @Column(name="cust_level")
                    private String custLevel;
                    
                    @Column(name="cust_address")
                    private String custAddress;
                    
                    @Column(name="cust_phone")
                    private String custPhone;
                        
                    public Long getCustId() {
                        return custId;
                    }
                    public void setCustId(Long custId) {
                        this.custId = custId;
                    }
                    public String getCustName() {
                        return custName;
                    }
                    public void setCustName(String custName) {
                        this.custName = custName;
                    }
                    public String getCustSource() {
                        return custSource;
                    }
                    public void setCustSource(String custSource) {
                        this.custSource = custSource;
                    }
                    public String getCustIndustry() {
                        return custIndustry;
                    }
                    public void setCustIndustry(String custIndustry) {
                        this.custIndustry = custIndustry;
                    }
                    public String getCustLevel() {
                        return custLevel;
                    }
                    public void setCustLevel(String custLevel) {
                        this.custLevel = custLevel;
                    }
                    public String getCustAddress() {
                        return custAddress;
                    }
                    public void setCustAddress(String custAddress) {
                        this.custAddress = custAddress;
                    }
                    public String getCustPhone() {
                        return custPhone;
                    }
                    public void setCustPhone(String custPhone) {
                        this.custPhone = custPhone;
                    }
                    @Override
                    public String toString() {
                        return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
                                + ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
                                + ", custPhone=" + custPhone + "]";
                    }    
                }
            
            2.3 常用注解说明
                @Entity
                    作用 : 指定当前类是实体类.写上此注解用于在创建SessionFactory/EntityManager时,加载映射配置.
                    
                @Table
                    作用 : 指定实体类和表之间的对应关系.
                    属性 :
                        name : 指定数据库表的名称.
                
                @Id
                    作用 : 指定当前字段是主键.
                    
                @GeneratedValue
                    作用 : 指定主键的生成方式.JPA的主键生成方式
                    属性 : 
                        strategy : 指定主键生成策略.JPA支持四种生成策略,
            
                @Column : 
                    作用 : 指定实体类属性和数据库表之间的对应关系.
                    属性 : 
                        name : 指定数据库表的列名称.
                        unique : 是否唯一 .
                        nullable : 是否可以为空
                        inserttable : 是否可以插入
                        updateable : 是否可以更新
                        columnDefinition : 定义建表时创建此列的DDL.
                        secondaryTable : 从表名.如果此列不建在主表上(默认键在主表),该属性定义该列所在从表的名字.
                2.4主键生成策略
                    通过annotation(注解)来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, 
                    其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法。
                    JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO。具体说明如下:
                    2.4.1IDENTITY:主键由数据库自动生成(主要是自动增长型) 
                    用法:
                        @Id  
                        @GeneratedValue(strategy = GenerationType.IDENTITY) 
                        private Long custId;
                    2.4.2SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。 
                    用法:
                        @Id  
                        @GeneratedValue(strategy = GenerationType.SEQUENCE,generator="payablemoney_seq")      
                        @SequenceGenerator(name="payablemoney_seq", sequenceName="seq_payment")  
                    说明:
                        @SequenceGenerator源码中的定义 
                        @Target({TYPE, METHOD, FIELD})   
                        @Retention(RUNTIME)  
                        public @interface SequenceGenerator {  
                            String name();  
                             String sequenceName() default "";  
                             int initialValue() default 0;  
                             int allocationSize() default 50;  
                        }  
                    name:表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。 
                        sequenceName:属性表示生成策略用到的数据库序列名称。 
                        initialValue:表示主键初识值,默认为0。 
                        allocationSize:表示每次主键值增加的大小,例如设置1,则表示每次插入新记录后自动加1,默认为50。
                        
                    2.4.3AUTO:主键由程序控制。 
                    用法:
                        @Id  
                        @GeneratedValue(strategy = GenerationType.AUTO)  
    
    
                    2.5JPA的CRUD操作
                    2.5.1保存
                    /**
                         * 保存一个实体
                         */
                        @Test
                        public void testAdd(){  
                            //定义对象
                            Customer c = new Customer();
                            c.setCustName("传智学院");
                            c.setCustLevel("VIP客户");
                            c.setCustSource("网络");
                            c.setCustIndustry("IT教育");
                            c.setCustAddress("昌平区北七家镇");
                            c.setCustPhone("010-84389340");
                            EntityManager em=null;  
                            EntityTransaction tx=null;  
                            try{  
                                //获取实体管理对象
                                em=JPAUtil.getEntityManager();
                                //获取事务对象
                                tx=em.getTransaction();
                                //开启事务
                                tx.begin();
                                //执行操作
                                em.persist(c);
                                //提交事务
                                tx.commit();  
                            }catch(Exception e){
                                //回滚事务
                                tx.rollback();
                                e.printStackTrace();  
                            }finally{  
                                //释放资源
                                em.close();  
                            }    
                        }
    
                    2.5.2修改
                        /**
                         * 修改
                         */
                        @Test
                        public void testUpdate(){  
                            //定义对象
                            EntityManager em=null;  
                            EntityTransaction tx=null;  
                            try{  
                                //获取实体管理对象
                                em=JPAUtil.getEntityManager();
                                //获取事务对象
                                tx=em.getTransaction();
                                //开启事务
                                tx.begin();
                                //执行操作
                                Customer c1 = em.find(Customer.class, 1L);
                                c1.setCustName("江苏传智学院");
                                //提交事务
                                tx.commit();  //使用JPA中快照机制实现更新
                            }catch(Exception e){
                                //回滚事务
                                tx.rollback();
                                e.printStackTrace();  
                            }finally{  
                                //释放资源
                                em.close();  
                            }    
                        }
    
                    merge方法实现修改
                        @Test
                        public void testMerge(){  
                            //定义对象
                            EntityManager em=null;  
                            EntityTransaction tx=null;  
                            try{  
                                //获取实体管理对象
                                em=JPAUtil.getEntityManager();
                                //获取事务对象
                                tx=em.getTransaction();
                                //开启事务
                                tx.begin();
                                //执行操作
                                Customer c1 = em.find(Customer.class, 6L);
                                c1.setCustName("江苏传智学院");
                                em.clear();//把c1对象从缓存中清除出去
                                em.merge(c1);
                                //提交事务
                                tx.commit(); 
                            }catch(Exception e){
                                //回滚事务
                                tx.rollback();
                                e.printStackTrace();  
                            }finally{  
                                //释放资源
                                em.close();  
                            }    
                        }
                    2.5.3删除
                        /**
                         * 删除
                         */
                        @Test
                        public void testRemove(){  
                            //定义对象
                            EntityManager em=null;  
                                EntityTransaction tx=null;  
                                try{  
                                    //获取实体管理对象
                                    em=JPAUtil.getEntityManager();
                                    //获取事务对象
                                    tx=em.getTransaction();
                                    //开启事务
                                    tx.begin();
                                    //执行操作
                                    Customer c1 = em.find(Customer.class, 6L);
                                    em.remove(c1);
                                    //提交事务
                                    tx.commit(); 
                                }catch(Exception e){
                                    //回滚事务
                                    tx.rollback();
                                    e.printStackTrace();  
                                }finally{  
                                    //释放资源
                                    em.close();  
                                }    
                        }
                    2.5.4查询一个
                        /**
                         * 查询一个:
                         *     使用立即加载的策略
                         */
                        @Test
                        public void testGetOne(){  
                            //定义对象
                            EntityManager em=null;  
                                EntityTransaction tx=null;  
                             try{  
                                    //获取实体管理对象
                                    em=JPAUtil.getEntityManager();
                                    //获取事务对象
                                    tx=em.getTransaction();
                                    //开启事务
                                    tx.begin();
                                    //执行操作
                                    Customer c1 = em.find(Customer.class, 1L);
                                    //提交事务
                                    tx.commit();  
                                    System.out.println(c1); //输出查询对象
                             }catch(Exception e){
                                    //回滚事务
                                    tx.rollback();
                                    e.printStackTrace();  
                                }finally{  
                                    //释放资源
                                    em.close();  
                                }    
                        } 
                        
                    查询实体的缓存问题
                    @Test
                        public void testGetOne(){  
                            //定义对象
                            EntityManager em=null;  
                            EntityTransaction tx=null;  
                            try{  
                                //获取实体管理对象
                                em=JPAUtil.getEntityManager();
                                //获取事务对象
                                tx=em.getTransaction();  
                                //开启事务
                                tx.begin();
                                //执行操作
                                Customer c1 = em.find(Customer.class, 1L);
                                Customer c2 = em.find(Customer.class, 1L);
                                System.out.println(c1 == c2);//输出结果是true,EntityManager也有缓存
                                //提交事务
                                tx.commit();  
                                System.out.println(c1);
                            }catch(Exception e){
                                //回滚事务
                                tx.rollback();
                                e.printStackTrace();  
                            }finally{  
                                //释放资源
                                em.close();  
                            }    
                        }
    
                    延迟加载策略的方法:
                        /**
                         * 查询一个:
                         *     使用延迟加载策略
                         */
                        @Test
                        public void testLoadOne(){  
                            //定义对象
                            EntityManager em=null;  
                            EntityTransaction tx=null;  
                            try{  
                                //获取实体管理对象
                                em=JPAUtil.getEntityManager();
                                //获取事务对象
                                tx=em.getTransaction();
                                //开启事务
                                tx.begin();
                                //执行操作
                                Customer c1 = em.getReference(Customer.class, 1L);
                                //提交事务
                                tx.commit();  
                                System.out.println(c1);
                            }catch(Exception e){
                                //回滚事务
                                tx.rollback();
                                e.printStackTrace();  
                            }finally{  
                                //释放资源
                                em.close();  
                            }    
                        }
                    2.5.5查询所有
                        /**
                         * 查询所有
                         *     涉及的对象:
                         *         Query(注意:不是Hibernate的Query)
                         *      如何获取:
                         *          使用EntityManager的createQuery(String JPQL)方法;
                         *      参数的含义
                         *          JPQL:jpa  query language
                         *          JPQL的写法:
                         *          表名使用实体类名称替代
                         *          列名使用实体类属性名称替代
                         *          不能使用*号。查询所有,需要在from关键字后面的类名上加别名
                         *          例如: select c from Customer c
                         *          查询条件可以使用?作为参数占位符。
                         *          给占位符赋值时,占位符索引位置从1开始
                         *    获取结果集的方法
                         *        getResultList():查询结果是一个List集合
                         *         getSingleResult():查询结果是一个对象
                         */
                        @Test
                        public void testFindAll(){
                            //定义对象
                            EntityManager em=null;  
                            EntityTransaction tx=null;  
                            try{  
                                //获取实体管理对象
                                em=JPAUtil.getEntityManager();
                                //获取事务对象
                                tx=em.getTransaction();
                                //开启事务
                                tx.begin();
                                //执行操作
                                Query query = em.createQuery("select c from Customer c where custName like ? ");
                                query.setParameter(1,"%学院%");
                                List list = query.getResultList();
                                //提交事务
                                tx.commit(); 
                                
                                for(Object o : list){
                                    System.out.println(o);
                                }
                            }catch(Exception e){
                                //回滚事务
                                tx.rollback();
                                e.printStackTrace();  
                            }finally{  
                                //释放资源
                                em.close();  
                            }   
                        }
            
            3.1一对多关系映射
                3.1.1常用注解
                3.1.1.1@OneToMany:
                作用:
                    建立一对多的关系映射
                属性:
                    targetEntityClass:指定多的方的类的字节码
                    mappedBy:指定从表实体类中引用主表对象的名称。
                    cascade:指定要使用的级联操作
                    fetch:指定是否采用延迟加载
                    orphanRemoval:是否使用孤儿删除
                3.1.1.2@ManyToOne
                作用:
                    建立多对一的关系
                属性:
                    targetEntityClass:指定一的一方实体类字节码
                    cascade:指定要使用的级联操作
                    fetch:指定是否采用延迟加载
                    optional:关联是否可选。如果设置为false,则必须始终存在非空关系。
                3.1.1.3@JoinColumn
                作用:
                    用于定义主键字段和外键字段的对应关系。
                属性:
                    name:指定外键字段的名称
                    referencedColumnName:指定引用主表的主键字段名称
                    unique:是否唯一。默认值不唯一
                    nullable:是否允许为空。默认值允许。
                    insertable:是否允许插入。默认值允许。
                    updatable:是否允许更新。默认值允许。
                    columnDefinition:列的定义信息。
                3.1.2配置代码
                3.1.2.1客户配置
                /**
                 * 客户的实体类 
                 * 明确使用的注解都是JPA规范的
                 * 所以导包都要导入javax.persistence包下的
                 *
                 */
                @Entity//表示当前类是一个实体类
                @Table(name="cst_customer")//建立当前实体类和表之间的对应关系
                public class Customer implements Serializable {
                    
                    @Id//表明当前私有属性是主键
                    @GeneratedValue(strategy=GenerationType.IDENTITY)//指定主键的生成策略
                    @Column(name="cust_id")//指定和数据库表中的cust_id列对应
                    private Long custId;
                    @Column(name="cust_name")//指定和数据库表中的cust_name列对应
                    private String custName;
                    @Column(name="cust_source")//指定和数据库表中的cust_source列对应
                    private String custSource;
                    @Column(name="cust_industry")//指定和数据库表中的cust_industry列对应
                    private String custIndustry;
                    @Column(name="cust_level")//指定和数据库表中的cust_level列对应
                    private String custLevel;
                    @Column(name="cust_address")//指定和数据库表中的cust_address列对应
                    private String custAddress;
                    @Column(name="cust_phone")//指定和数据库表中的cust_phone列对应
                    private String custPhone;
                    
                    @OneToMany(targetEntity=LinkMan.class,mappedBy="customer")
                    private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);
                    
                    public Long getCustId() {
                        return custId;
                    }
                    public void setCustId(Long custId) {
                        this.custId = custId;
                    }
                    public String getCustName() {
                        return custName;
                    }
                    public void setCustName(String custName) {
                        this.custName = custName;
                    }
                    public String getCustSource() {
                        return custSource;
                    }
                    public void setCustSource(String custSource) {
                        this.custSource = custSource;
                    }
                    public String getCustIndustry() {
                        return custIndustry;
                    }
                    public void setCustIndustry(String custIndustry) {
                        this.custIndustry = custIndustry;
                    }
                    public String getCustLevel() {
                        return custLevel;
                    }
                    public void setCustLevel(String custLevel) {
                        this.custLevel = custLevel;
                    }
                    public String getCustAddress() {
                        return custAddress;
                    }
                    public void setCustAddress(String custAddress) {
                        this.custAddress = custAddress;
                    }
                    public String getCustPhone() {
                        return custPhone;
                    }
                    public void setCustPhone(String custPhone) {
                        this.custPhone = custPhone;
                    }
                    public Set<LinkMan> getLinkmans() {
                        return linkmans;
                    }
                    public void setLinkmans(Set<LinkMan> linkmans) {
                        this.linkmans = linkmans;
                    }
                    @Override
                    public String toString() {
                        return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
                                + ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
                                + ", custPhone=" + custPhone + "]";
                    }
                }
                3.1.2.2联系人配置
                /**
                 * 联系人的实体类(数据模型)
                */
                @Entity
                @Table(name="cst_linkman")
                public class LinkMan implements Serializable {
                    @Id
                    @GeneratedValue(strategy=GenerationType.IDENTITY)
                    @Column(name="lkm_id")
                    private Long lkmId;
                    @Column(name="lkm_name")
                    private String lkmName;
                    @Column(name="lkm_gender")
                    private String lkmGender;
                    @Column(name="lkm_phone")
                    private String lkmPhone;
                    @Column(name="lkm_mobile")
                    private String lkmMobile;
                    @Column(name="lkm_email")
                    private String lkmEmail;
                    @Column(name="lkm_position")
                    private String lkmPosition;
                    @Column(name="lkm_memo")
                    private String lkmMemo;
    
                    //多对一关系映射:多个联系人对应客户
                    @ManyToOne(targetEntity=Customer.class)
                    @JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
                    private Customer customer;//用它的主键,对应联系人表中的外键
                    
                    public Long getLkmId() {
                        return lkmId;
                    }
                    public void setLkmId(Long lkmId) {
                        this.lkmId = lkmId;
                    }
                    public String getLkmName() {
                        return lkmName;
                    }
                    public void setLkmName(String lkmName) {
                        this.lkmName = lkmName;
                    }
                    public String getLkmGender() {
                        return lkmGender;
                    }
                    public void setLkmGender(String lkmGender) {
                        this.lkmGender = lkmGender;
                    }
                    public String getLkmPhone() {
                        return lkmPhone;
                    }
                    public void setLkmPhone(String lkmPhone) {
                        this.lkmPhone = lkmPhone;
                    }
                    public String getLkmMobile() {
                        return lkmMobile;
                    }
                    public void setLkmMobile(String lkmMobile) {
                        this.lkmMobile = lkmMobile;
                    }
                    public String getLkmEmail() {
                        return lkmEmail;
                    }
                    public void setLkmEmail(String lkmEmail) {
                        this.lkmEmail = lkmEmail;
                    }
                    public String getLkmPosition() {
                        return lkmPosition;
                    }
                    public void setLkmPosition(String lkmPosition) {
                        this.lkmPosition = lkmPosition;
                    }
                    public String getLkmMemo() {
                        return lkmMemo;
                    }
                    public void setLkmMemo(String lkmMemo) {
                        this.lkmMemo = lkmMemo;
                    }    
                    public Customer getCustomer() {
                        return customer;
                    }
                    public void setCustomer(Customer customer) {
                        this.customer = customer;
                    }
                    @Override
                    public String toString() {
                        return "LinkMan [lkmId=" + lkmId + ", lkmName=" + lkmName + ", lkmGender=" + lkmGender + ", lkmPhone="
                                + lkmPhone + ", lkmMobile=" + lkmMobile + ", lkmEmail=" + lkmEmail + ", lkmPosition=" + lkmPosition
                                + ", lkmMemo=" + lkmMemo + "]";
                    }
                }
                3.2多对多关系映射
                3.2.1常用注解:
                3.2.1.1@ManyToMany
                作用:
                    用于映射多对多关系
                属性:
                    cascade:配置级联操作。
                    fetch:配置是否采用延迟加载。
                    targetEntity:配置目标的实体类。映射多对多的时候不用写。
                3.2.1.2@JoinTable
                作用:
                    针对中间表的配置
                属性:
                    name:配置中间表的名称
                    joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段                          
                    inverseJoinColumn:中间表的外键字段关联对方表的主键字段
                        
                3.2.1.3@JoinColumn
                作用:
                    用于定义主键字段和外键字段的对应关系。
                属性:
                    name:指定外键字段的名称
                    referencedColumnName:指定引用主表的主键字段名称
                    unique:是否唯一。默认值不唯一
                    nullable:是否允许为空。默认值允许。
                    insertable:是否允许插入。默认值允许。
                    updatable:是否允许更新。默认值允许。
                    columnDefinition:列的定义信息。
                    
                3.2.2配置代码
                3.2.2.1用户配置
                /**
                 * 用户的数据模型
                */
                @Entity
                @Table(name="sys_user")
                public class SysUser implements Serializable {
                    
                    @Id
                    @GeneratedValue(strategy=GenerationType.IDENTITY)
                    @Column(name="user_id")
                    private Long userId;
                    @Column(name="user_code")
                    private String userCode;
                    @Column(name="user_name")
                    private String userName;
                    @Column(name="user_password")
                    private String userPassword;
                    @Column(name="user_state")
                    private String userState;
                    
                    //多对多关系映射
                    @ManyToMany(mappedBy="users")
                    private Set<SysRole> roles = new HashSet<SysRole>(0);
                    
                    public Long getUserId() {
                        return userId;
                    }
                    public void setUserId(Long userId) {
                        this.userId = userId;
                    }
                    public String getUserCode() {
                        return userCode;
                    }
                    public void setUserCode(String userCode) {
                        this.userCode = userCode;
                    }
                    public String getUserName() {
                        return userName;
                    }
                    public void setUserName(String userName) {
                        this.userName = userName;
                    }
                    public String getUserPassword() {
                        return userPassword;
                    }
                    public void setUserPassword(String userPassword) {
                        this.userPassword = userPassword;
                    }
                    public String getUserState() {
                        return userState;
                    }
                    public void setUserState(String userState) {
                        this.userState = userState;
                    }
                    public Set<SysRole> getRoles() {
                        return roles;
                    }
                    public void setRoles(Set<SysRole> roles) {
                        this.roles = roles;
                    }
                    @Override
                    public String toString() {
                        return "SysUser [userId=" + userId + ", userCode=" + userCode + ", userName=" + userName + ", userPassword="
                                + userPassword + ", userState=" + userState + "]";
                    }
                }
    
    
                3.2.2.2角色配置
                /**
                 * 角色的数据模型
                */
                @Entity
                @Table(name="sys_role")
                public class SysRole implements Serializable {
                    
                    @Id
                    @GeneratedValue(strategy=GenerationType.IDENTITY)
                    @Column(name="role_id")
                    private Long roleId;
                    @Column(name="role_name")
                    private String roleName;
                    @Column(name="role_memo")
                    private String roleMemo;
                    
                    //多对多关系映射
                    @ManyToMany
                    @JoinTable(name="user_role_rel",//中间表的名称
                              //中间表user_role_rel字段关联sys_role表的主键字段role_id
                    joinColumns={@JoinColumn(name="role_id",referencedColumnName="role_id")},
                              //中间表user_role_rel的字段关联sys_user表的主键user_id
                    inverseJoinColumns={@JoinColumn(name="user_id",referencedColumnName="user_id")}
                    )
                    private Set<SysUser> users = new HashSet<SysUser>(0);
                    
                    
                    public Long getRoleId() {
                        return roleId;
                    }
                    public void setRoleId(Long roleId) {
                        this.roleId = roleId;
                    }
                    public String getRoleName() {
                        return roleName;
                    }
                    public void setRoleName(String roleName) {
                        this.roleName = roleName;
                    }
                    public String getRoleMemo() {
                        return roleMemo;
                    }
                    public void setRoleMemo(String roleMemo) {
                        this.roleMemo = roleMemo;
                    }
                    public Set<SysUser> getUsers() {
                        return users;
                    }
                    public void setUsers(Set<SysUser> users) {
                        this.users = users;
                    }
                    @Override
                    public String toString() {
                        return "SysRole [roleId=" + roleId + ", roleName=" + roleName + ", roleMemo=" + roleMemo + "]";
                    }
                    
                    
                }
    
    
                第4章JPA的多表操作
                4.1一对多关系的增删改操作
                4.1.1保存操作
                保存原则:先保存主表,再保存从表。
                    /**
                     * 保存操作
                     * 需求:
                     *     保存一个客户和一个联系人
                     * 要求:
                     *     创建一个客户对象和一个联系人对象
                     *  建立客户和联系人之间关联关系(双向一对多的关联关系)
                     *  先保存客户,再保存联系人
                     */
                    @Test
                    public void test1(){
                        //创建客户和联系人对象
                        Customer c = new Customer();//瞬时态
                        c.setCustName("TBD云集中心");
                        c.setCustLevel("VIP客户");
                        c.setCustSource("网络");
                        c.setCustIndustry("商业办公");
                        c.setCustAddress("昌平区北七家镇");
                        c.setCustPhone("010-84389340");
                        
                        LinkMan l = new LinkMan();//瞬时态
                        l.setLkmName("TBD联系人");
                        l.setLkmGender("male");
                        l.setLkmMobile("13811111111");
                        l.setLkmPhone("010-34785348");
                        l.setLkmEmail("98354834@qq.com");
                        l.setLkmPosition("老师");
                        l.setLkmMemo("还行吧");
    
                        //建立他们的双向一对多关联关系
                        l.setCustomer(c);
                        c.getLinkmans().add(l);
                        //获取JPA操作对照
                        EntityManager em = JPAUtil.getEntityManager();
                        //获取JPA事务对象
                        EntityTransaction tx= em.getTransaction();
                            //开启事务
                            tx.begin();
                        //按照要求:先保存客户,再保存联系人(此时符合保存原则:先保存主表,再保存从表)
                        em.persist(c);
                        em.persist(l);        
                        tx.commit();
                    }
    
                JPA注解的配置方式:不涉及多一条update语句的问题
                4.1.2删除操作
                    /**
                     * 删除操作
                     *     删除从表数据:可以随时任意删除。
                     *     删除主表数据:
                     *         有从表数据引用
                     *             1、不能删除
                     *             2、如果还想删除,使用级联删除
                     *         没有从表数据引用:随便删
                     * 
                     * 在实际开发中,级联删除请慎用!(在一对多的情况下)
                     */
                    @Test
                    public void test3(){
                        //获取JPA操作对照
                        EntityManager em = JPAUtil.getEntityManager();
                        //获取JPA事务对象
                        EntityTransaction tx= em.getTransaction();
                            //开启事务
                            tx.begin();
                        //查询id为1的客户
                        Customer c1 = em.find(Customer.class, 2L);
                        //删除id为1的客户
                        em.remove(c1);
                        tx.commit();
                    }
    
                级联删除的配置:
                @OneToMany(targetEntity=LinkMan.class,mappedBy="customer",cascade=CascadeType.ALL) //用CascadeType.REMOVE也可以
                private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);
                4.2多对多关系的增删操作
                4.2.1保存操作
                    /**
                     * 需求:
                     *     保存用户和角色
                     * 要求:
                     *     创建2个用户和3个角色
                     *     让1号用户具有1号和2号角色(双向的)
                     *     让2号用户具有2号和3号角色(双向的)
                     *  保存用户和角色
                     */
                    @Test
                    public void test1(){
                        //创建对象
                        SysUser u1 = new SysUser();
                        u1.setUserName("用户1");
                        SysUser u2 = new SysUser();
                        u2.setUserName("用户2");
                        
                        SysRole r1 = new SysRole();
                        r1.setRoleName("角色1");
                        SysRole r2 = new SysRole();
                        r2.setRoleName("角色2");
                        SysRole r3 = new SysRole();
                        r3.setRoleName("角色3");
                        
                        //建立关联关系
                        u1.getRoles().add(r1);
                        u1.getRoles().add(r2);
                        r1.getUsers().add(u1);
                        r2.getUsers().add(u1);
                        
                        u2.getRoles().add(r2);
                        u2.getRoles().add(r3);
                        r2.getUsers().add(u2);
                        r3.getUsers().add(u2);
                        
                        //获取JPA操作对照
                        EntityManager em = JPAUtil.getEntityManager();
                        //获取JPA事务对象
                        EntityTransaction tx= em.getTransaction();
                            //开启事务
                            tx.begin();
                        em.persist(u1);
                        em.persist(u2);
                        em.persist(r1);
                        em.persist(r2);
                        em.persist(r3);
                        tx.commit();
                    }
    
                JPA注解的配置方式:不涉及保存失败的问题:
                4.2.2删除操作
                    /**
                     * 删除操作
                     *     在多对多的删除时,双向级联删除根本不能配置
                     * 禁用
                     *    如果配了的话,如果数据之间有相互引用关系,可能会清空所有数据
                     */
                    @Test
                    public void test2(){
                        //获取JPA操作对照
                        EntityManager em = JPAUtil.getEntityManager();
                        //获取JPA事务对象
                        EntityTransaction tx= em.getTransaction();
                            //开启事务
                            tx.begin();
                        SysUser u1 = em.find(SysUser.class,3L);
                        em.remove(u1);
                        tx.commit();
                    }
    
                在多对多映射配置中不能出现双向级联删除的配置,无论注解还是XML配置
            
            5.2JPA和hibernate中操作数据的方法对照
                操作    Hibernate中的方法    JPA中的方法    说明
                保存操作    save(Object entity)    persist(Object entity)    共同点:都是把临时态对象转成了持久态。
                区别:
                提供者不一样:
                    save方法是hibernate提供的。
                    persist方法是JPA规范提供的。
                在没有事务的情况下:
                    save会去数据库中保存,hibernate提供了一个内置的事务来执行。
                    persist什么都不会做。
                更新操作    update (Object entity)    merge (Object entity)    Hibernate和jpa都可以利用快照机制,不调用任何方法去更新。
                Update方法在更新时,如果遇到一级缓存已经包含了一个相同OID的对象会报错。merge则可以执行成功。
                删除操作    delete (Object entity)    remove (Object entity)    都是删除一个实体
                查询一个操作    get (Class clazz,Serializable id)
                load(Class clazz,Serializable id)    find(Class clazz,Object id)
                getReerence(Class clazz,Object id)    get和find都是立即加载。load和getReference一样都是延迟加载。
                查询所有操作    Query:使用HQL语句查询    Query:使用JPQL查询    查询语句的形式不一样。
                查询返回唯一结果操作    uniqueResult()    getSingleResult()    查询都是返回一个唯一的结果。
    
            JPA一对多的注解配置:
                案例:
                    // ps: jpa提供的注解都在:javax.persistence包下
                    @Entity
                    @Table(name="cst_customer")
                    public  class Customer
                    {
                        @Id
                        @Column(name="cust_id")
                        @GeneratedValue(strategy=GenerationType.IDENTITY)
                        private Long cust_id; // '客户编号(主键)',
                        
                        @Column(name="cust_name")
                        private String cust_name; // '客户名称(公司名称)',
                        
                        @Column(name="cust_source")
                        private String cust_source; // '客户信息来源',
                        
                        @Column(name="cust_industry")
                        private String cust_industry; // '客户所属行业',
                        
                        @Column(name="cust_level")
                        private String cust_level; // '客户级别',
                        
                        @Column(name="cust_address")
                        private String cust_address; // '客户联系地址',
                        
                        @Column(name="cust_phone")
                        private String cust_phone; // '客户联系电话
                        
                        // 有多的一方的集合
                        /*targetEntity:对方的类型
                         * mappedBy:自己在对方里的属性名称   (mappedBy写在哪方,哪方意味着放弃外键的维护)
                         * 
                         * */
                        @OneToMany(targetEntity=LinkMan.class,mappedBy="customer",cascade=CascadeType.REMOVE)
                        private Set<LinkMan> linkmans=new HashSet();
            
                        @Entity
                        @Table(name="cst_linkman")
                        public class LinkMan 
                        {
                            @Id
                            @Column(name="lkm_id")
                            @GeneratedValue(strategy=GenerationType.IDENTITY)
                            private Long lkm_id;// '联系人编号(主键)',
                            
                            @Column(name="lkm_name")
                            private String lkm_name;// '联系人姓名',
                            
                            @Column(name="lkm_gender")
                            private String lkm_gender;// '联系人性别',
                            
                            @Column(name="lkm_phone")
                            private String lkm_phone;// '联系人办公电话',
                            
                            @Column(name="lkm_mobile")
                            private String lkm_mobile;// '联系人手机',
                            
                            @Column(name="lkm_email")
                            private String lkm_email;// '联系人邮箱',
                            
                            @Column(name="lkm_qq")
                            private String lkm_qq;// '联系人qq',
                            
                            @Column(name="lkm_position")
                            private String lkm_position;// '联系人职位',
                            
                            @Column(name="lkm_memo")
                            private String lkm_memo;// '联系人备注', 
                            
                            // 有一的一方的对象 PERSIST
                            @ManyToOne(targetEntity=Customer.class,cascade=CascadeType.PERSIST)
                            /*name:代表着外键字段的名称*/
                            /*referencedColumnName:指向的主键字段的命名称*/
                            @JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
                            private Customer customer;
            
                多表对多表的注解配置:
                        @Entity
                        @Table(name="sys_user")
                        public class User 
                        {
                            @Id
                            @Column(name="user_id")
                            @GeneratedValue(strategy=GenerationType.IDENTITY)
                            private Long user_id;// '用户id',
                            @Column(name="user_code")
                            private String user_code;// '用户账号',
                            @Column(name="user_name")
                            private String user_name;// '用户名称',
                            @Column(name="user_password")
                            private String user_password;// '用户密码',
                            @Column(name="user_state")
                            private String user_state;// '1:正常,0:暂停',
                            
                            // 有角色的集合
                            /*targetEntity:对方的类型
                             * 
                             * 
                             * */
                            @ManyToMany(targetEntity=Role.class,cascade=CascadeType.ALL)
                            /*name: 中间表的名称
                            joinColumns:自己在中间表的一些配置
                            inverseJoinColumns:对方在中间表的一些配置*/
                            @JoinTable(name="sys_user_role",
                            joinColumns={
                                        /*name:自己在中间表的外键字段名称
                                        referencedColumnName:指向自己的主键字段名*/
                                @JoinColumn(name="user_id",referencedColumnName="user_id")    
                            },
                            inverseJoinColumns={
                                        /*name:对方在中间表的外键字段名称
                                        referencedColumnName:指向的对方的主键字段名称*/
                                    @JoinColumn(name="role_id",referencedColumnName="role_id")
                            })
                            private Set<Role> roles=new HashSet();
            
                        @Entity
                        @Table(name="sys_role")
                        public class Role 
                        {
                            @Id
                            @Column(name="role_id")
                            @GeneratedValue(strategy=GenerationType.IDENTITY)
                            private Long role_id;// 主键id
                            
                            @Column(name="role_name")
                            private String role_name;// '角色名称',
                            @Column(name="role_memo")
                            private String role_memo;// '备注',
                            
                            // 有用户的集合
                            /*targetEntity:对方的类型
                             * mappedBy:自己在对方的属性名
                             * */
                            @ManyToMany(targetEntity=User.class,mappedBy="roles")
                            private Set<User> users=new HashSet();
            
                JPA需要在项目src下新建一个META-INF文件夹在文件夹里面配置以下信息:
                    例如 :
                        <?xml version="1.0" encoding="UTF-8"?>
                        <persistence xmlns="http://java.sun.com/xml/ns/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">
                                <!-- ps:当前根目录下必须得有一个持久化单元(至少要有一个数据库的连接信息配置) -->
                                <persistence-unit name="aaa">
                                            <!-- 数据库的连接信息 -->
                                            <properties>
                                                    <!-- 必选5项 -->
                                                <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
                                                <property name="hibernate.connection.url" value="jdbc:mysql:///hibernate3"></property>
                                                <property name="hibernate.connection.username" value="root"></property>
                                                <property name="hibernate.connection.password" value="1234"></property>
                                                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property>    
                                                
                                                    <!-- 可选的 -->    
                                                <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"></property>
                                                <property name="hibernate.show_sql" value="true"></property>
                                                <property name="hibernate.format_sql" value="true"></property>
                                                <property name="hibernate.hbm2ddl.auto" value="update"></property>
                                                    
                                            </properties>
                                </persistence-unit>
                        </persistence>
            JPA单表操作 :
                例如 :
                    package cn.baidu.demo;
    
                    public class Demo1 
                    {
                        @Test //需求:保存一个客户
                        public void t1()
                        {
                            // 加载配置文件--返回一个类似Sessionfactory的对象
                            EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");
                            // 类似session
                            EntityManager em = factory.createEntityManager();
                            // 获取事务
                            EntityTransaction tx = em.getTransaction(); // 事务未开启
                            // 开启事务
                            tx.begin();
                            
                            // 保存操作
                            Customer ct = new Customer();
                            ct.setCust_name("李冰冰");
                            em.persist(ct); // 类似save()
                            
                            
                            // 手动提交
                            tx.commit();
                            
                            // 释放资源
                            em.close();
                            
                        }
                        
                        @Test //查询1
                        public void t2()
                        {
                            EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");
                            EntityManager em = factory.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 查询
                            Customer ct = em.find(Customer.class, 1L); // 立即加载  类似get()
                            System.out.println(ct);
                            tx.commit();
                            em.close();
                        }
                        
                        @Test //查询2
                        public void t3()
                        {
                            EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");
                            EntityManager em = factory.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 查询2
                            Customer ct = em.getReference(Customer.class, 1L); //延迟加载  类似load()
                            System.out.println(ct);
                            tx.commit();
                            em.close();
                        }
                        
                        
                        @Test //修改
                        public void t4()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 修改
                            Customer ct = em.find(Customer.class, 1L);
                            ct.setCust_name("rose");
                            em.merge(ct);  //类似update
                            
                            tx.commit();
                            em.close();
                        }
                        
                        @Test //修改 jpa支持一级缓存?  支持
                        public void t5()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 修改
                            Customer ct = em.find(Customer.class, 1L);
                            ct.setCust_name("rose123");
                        
                            
                            tx.commit();
                            em.close();
                        }
                        
                        
                        @Test //删除 
                        public void t6()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            //删除
                            Customer ct = em.find(Customer.class, 1L);
                            em.remove(ct);  // 类似之前的delete()
                        
                            
                            tx.commit();
                            em.close();
                        }
                        
                        
                        /// jpa的批量查询方式
                                // 类似咱们之前学习的query方式
                                // 1 qr.getResultList();        //类似之前的 qr.list()
                                // 2 hibernate对于占位符?是从0开始  jpa是从1开始
                                // 3  聚合    qr.getSingleResult();  //类似之前的  qr.uniqueResult(); 
                        
                        @Test
                        public void t7()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 全查
                            Query qr = em.createQuery("from Customer");
                            List<Customer> list = qr.getResultList();  //类似之前的 qr.list()
                            for (Customer customer : list) {
                                System.out.println(customer);
                            }
                            
                            tx.commit();
                            em.close();
                        }
                        
                        
                        @Test
                        public void t8()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 条件
                            Query qr = em.createQuery("from Customer where cust_name like ?");
                            qr.setParameter(1, "b%"); // 注意:hibernate对于占位符?是从0开始  jpa是从1开始
                            
                            List<Customer> list = qr.getResultList();
                            for (Customer customer : list) {
                                System.out.println(customer);
                            }
                            tx.commit();
                            em.close();
                        }
                        
                        
                        @Test
                        public void t9()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 分页
                            Query qr = em.createQuery("from Customer");
                            qr.setFirstResult(1);  
                            qr.setMaxResults(3);
                            
                            List<Customer> list = qr.getResultList();
                            for (Customer customer : list) {
                                System.out.println(customer);
                            }
                            tx.commit();
                            em.close();
                        }
                        
                        
                        @Test
                        public void t10()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 单列
                            Query qr = em.createQuery("select cust_name from Customer");
                            List<Object> list = qr.getResultList();
                            for (Object object : list) {
                                System.out.println(object);
                            }
                            tx.commit();
                            em.close();
                        }
                        
                        @Test
                        public void t11()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 多列
                            Query qr = em.createQuery("select cust_id,cust_name from Customer");
                            List<Object[]> list = qr.getResultList();
                            for (Object[] object : list) {
                                System.out.println(Arrays.toString(object));
                            }
                            tx.commit();
                            em.close();
                        }
                        
                        @Test
                        public void t12()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 投影
                            Query qr = em.createQuery("select new Customer(cust_id,cust_name) from Customer");
                            List<Customer> list = qr.getResultList();
                            for (Customer customer : list) {
                                System.out.println(customer);
                            }
                            tx.commit();
                            em.close();
                        }
                        
                        
                        @Test
                        public void t13()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 排序
                            Query qr = em.createQuery("from Customer order by cust_id desc");
                            List<Customer> list = qr.getResultList();
                            for (Customer customer : list) {
                                System.out.println(customer);
                            }
                            tx.commit();
                            em.close();
                        }
                        
                        @Test
                        public void t14()
                        {
                            EntityManager em = JPAutils.createEntityManager();
                            EntityTransaction tx = em.getTransaction();
                            tx.begin();
                            
                            // 聚合
                            Query qr = em.createQuery("select avg(cust_id) from Customer");
                            Object obj = qr.getSingleResult(); 
                            System.out.println(obj);
                            tx.commit();
                            em.close();
                        }
                    }
    
            JPA一对多表的操作 :
                /*
            一对多的操作*/
            public class Demo2 
            {
                @Test  // 保存一的客户3个联系人
                public void t1()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    Customer ct = new Customer();
                    ct.setCust_name("马总");
                    LinkMan l1 = new LinkMan();
                    l1.setLkm_name("大秘");
                    LinkMan l2 = new LinkMan();
                    l2.setLkm_name("中秘");
                    LinkMan l3 = new LinkMan();
                    l3.setLkm_name("小秘");
                    
                    // 双向关联
                    ct.getLinkmans().add(l1);
                    ct.getLinkmans().add(l2);
                    ct.getLinkmans().add(l3);
                    l1.setCustomer(ct);
                    l2.setCustomer(ct);
                    l3.setCustomer(ct);
                    
                    //保存
                    em.persist(ct);
                    em.persist(l1);
                    em.persist(l2);
                    em.persist(l3);
                    tx.commit();
                    em.close();
                }
                
                
                @Test  // 级联保存 (保存客户的同时把关联的联系人给保存了)
                            // jpa的注解里面  @OneToMany  添加属性cascade=CascadeType.PERSIST
                public void t2()  // 根据一的一方保存多的一方的数据(掌握)
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    Customer ct = new Customer();
                    ct.setCust_name("马总");
                    LinkMan l1 = new LinkMan();
                    l1.setLkm_name("大秘");
                    LinkMan l2 = new LinkMan();
                    l2.setLkm_name("中秘");
                    LinkMan l3 = new LinkMan();
                    l3.setLkm_name("小秘");
                    
                    // 双向关联
                    ct.getLinkmans().add(l1);
                    ct.getLinkmans().add(l2);
                    ct.getLinkmans().add(l3);
                    l1.setCustomer(ct);
                    l2.setCustomer(ct);
                    l3.setCustomer(ct);
                    
                    //保存
                    em.persist(ct);
                    /*em.persist(l1);
                    em.persist(l2);
                    em.persist(l3);*/
                    tx.commit();
                    em.close();
                }
                
                
                @Test  // 级联保存 (保存联系人的同时把关联的客户给保存了)
                // jpa的注解里面 @ManyToOne  添加属性cascade=CascadeType.PERSIST
                public void t3() // 根据多的一方保存一的一方的数据(不常用)
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    Customer ct = new Customer();
                    ct.setCust_name("马总");
                    LinkMan l1 = new LinkMan();
                    l1.setLkm_name("大秘");
                    LinkMan l2 = new LinkMan();
                    l2.setLkm_name("中秘");
                    LinkMan l3 = new LinkMan();
                    l3.setLkm_name("小秘");
                    
                    // 双向关联
                    ct.getLinkmans().add(l1);
                    ct.getLinkmans().add(l2);
                    ct.getLinkmans().add(l3);
                    l1.setCustomer(ct);
                    l2.setCustomer(ct);
                    l3.setCustomer(ct);
                    
                    //保存
                    /*em.persist(ct);*/
                    em.persist(l1);
                    em.persist(l2);
                    em.persist(l3);
                    tx.commit();
                    em.close();
                }
                
                  
                @Test  // 普通删除
                public void  t4()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    
                    Customer ct = em.find(Customer.class, 4L);
                    em.remove(ct);
                    tx.commit();
                    em.close();
                }
                
                
                @Test  // 级联删除
                // jpa的注解里面 @OneToMany  添加属性cascade=CascadeType.REMOVE (All)
                public void  t5()  //根据一的一方删除关联的多的一方的所有数据(掌握)
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    
                    Customer ct = em.find(Customer.class, 4L);
                    em.remove(ct);
                    tx.commit();
                    em.close();
                }
                
            }
            
            JPA多表对多表的操作 :
                package cn.baidu.demo;
    
            import javax.persistence.CascadeType;
            import javax.persistence.EntityManager;
            import javax.persistence.EntityTransaction;
            import javax.persistence.ManyToMany;
    
            import org.junit.Test;
    
            import cn.baidu.domain.Role;
            import cn.baidu.domain.User;
            import cn.baidu.utils.JPAutils;
    
            /*
            多对多的操作*/
            public class Demo3 
            {
                @Test  //普通保存  保存2个用户 3个角色
                public void t1()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    
                    User user1 = new User();
                    user1.setUser_name("jack");
                    User user2 = new User();
                    user2.setUser_name("rose");
                    
                    Role r1 = new Role();
                    r1.setRole_name("员工");
                    Role r2 = new Role();
                    r2.setRole_name("班主任");
                    Role r3 = new Role();
                    r3.setRole_name("助教");
                    
                    // 双向关联
                    user1.getRoles().add(r1);
                    user1.getRoles().add(r3);
                    user2.getRoles().add(r1);
                    user2.getRoles().add(r2);
                    
                    r1.getUsers().add(user1);
                    r1.getUsers().add(user2);
                    r2.getUsers().add(user2);
                    r3.getUsers().add(user1);
                    
                    // 保存
                    em.persist(user1);
                    em.persist(user2);
                    em.persist(r1);
                    em.persist(r2);
                    em.persist(r3);
    
                    tx.commit();
                    em.close();    
                }
                
                // jpa多对多的级联操作
                    // 级联保存: 保存用户的同时把关联的角色给保存了(不用)
                        // @ManyToMany 添加cascade=cascade=CascadeType.PERSIST
                @Test
                public  void t2()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    User user1 = new User();
                    user1.setUser_name("jack");
                    User user2 = new User();
                    user2.setUser_name("rose");
                    
                    Role r1 = new Role();
                    r1.setRole_name("员工");
                    Role r2 = new Role();
                    r2.setRole_name("班主任");
                    Role r3 = new Role();
                    r3.setRole_name("助教");
                    
                    // 双向关联
                    user1.getRoles().add(r1);
                    user1.getRoles().add(r3);
                    user2.getRoles().add(r1);
                    user2.getRoles().add(r2);
                    
                    r1.getUsers().add(user1);
                    r1.getUsers().add(user2);
                    r2.getUsers().add(user2);
                    r3.getUsers().add(user1);
                    
                    // 保存
                    em.persist(user1);
                    em.persist(user2);
                    /*em.persist(r1);
                    em.persist(r2);
                    em.persist(r3);*/
                    
                    tx.commit();
                    em.close();
                }
                
                @Test  // 普通删除(常用)
                public void t3()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    
                    User user = em.find(User.class, 1L);
                    em.remove(user);
                    tx.commit();
                    em.close();
                }
                
                @Test  // 级联删除(避免去使用)
                public void t4()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    
                    User user = em.find(User.class, 2L);
                    em.remove(user);
                    tx.commit();
                    em.close();
                }
                
                
                // jpa的用户角色分配
                        // 添加角色
                        // 删除角色
                        // 修改角色
                @Test
                public void t5()
                {
                    EntityManager em = JPAutils.createEntityManager();
                    EntityTransaction tx = em.getTransaction();
                    tx.begin();
                    // 获取用户
                    User user = em.find(User.class, 3L);
                    // 获取班主任
                    Role rl = em.find(Role.class, 6L);
                    //给用户添加
                    user.getRoles().add(rl);
                    tx.commit();
                    em.close();
                }
                
                
            }
    
            总结: 
        JPA的作用?
            给所有的orm框架提供了一套接口
        好处: 所有的ORM框架只要实现了这个JPA接口,用来操作数据库数据的方式和方法以及注解都一致了
    
    
        jpa的环境搭建: 在hibernate的环境基础上多加一个包--hibernate-entitymanager-5.0.7.Final.jar
    
    
        单表的映射
            @Entity  实体类
            @Table(name="cst_customer")  与表的映射
            @Id   指定OID属性
            @Column(name="cust_id") 指定映射的字段
            @GeneratedValue(strategy=GenerationType.IDENTITY)  指定主键的生成策略
    
        crud:
            persist()
                ----保存
    
            find()  : 立即加载
            getReference():延迟加载
                -----单条数据的oid查询
    
            merge()
                ---修改
    
            
            remove()
                ---删除
    
        
        批量查询:
              类似之前的query方式
    
    
        一对多:
            一: @OneToMany(targetEntity=LinkMan.class,mappedBy="customer")
            多: @ManyToOne(targetEntity=LinkMan.class)
                一对多的关系配置:
                    @JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
    
    
        多对多:
            多(被动): @ManyToMany(targetEntity=User.class,mappedBy="roles")
            多(主动): @ManyToMany(targetEntity=Role.class)
                 多对多的关系配置:
                    @JoinTable(name="中间表的名称",joinColumns="自己在中间表的配置(数组)"
                    inverseJoinColumns="对方在中间表的配置(数组)")
    
    
        级联:
            cascade=CascadeType.ALL  做级联保存以及级联删除
            cascade=CascadeType.PERSIST 只做级联保存
            cascade=CascadeType.REMOVE 只做级联删除
  • 相关阅读:
    Hadoop启动脚本分析
    java基础-Idea开发工具介绍
    Hadoop集群-HDFS集群中大数据运维常用的命令总结
    Hadoop部署方式-高可用集群部署(High Availability)
    Hadoop部署方式-完全分布式(Fully-Distributed Mode)
    Hadoop部署方式-伪分布式(Pseudo-Distributed Mode)
    Hadoop部署方式-本地模式(Local (Standalone) Mode)
    Hadoop基础原理
    Java基础-DBCP连接池(BasicDataSource类)详解
    nc命令的常用参数介绍
  • 原文地址:https://www.cnblogs.com/haizai/p/11484973.html
Copyright © 2020-2023  润新知