hibernate4

来源:互联网 发布:java处理xml 编辑:程序博客网 时间:2024/05/22 23:22

1:Hibernate是一个对象关系映射(ORM)框架,对jdbc进行了轻量级的对象封装,将pojo和数据表建立映射,是一个全自动的ORM框架,可以自动生成sql语句,自动执行。

既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。

Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
      1:CMP (Container Managed Persistence,容器管理的持久性,服务器负责处理数据库访问) 
2:ejb和hibernate都是反映对数据库的映射和操作,只不过ejb是重量级的,hibernate是轻量级的。不过ejb自主性比较高,可以更强的覆盖业务逻辑那块,划分的更细致,另外,还兼顾一定的spring那类的功能。ejb所谓重量级,是说更适合做银行项目,移动电信的项目,它对于这类的大项目,可以把步骤,操作做的更细,而且在分布上,对struts等一类的结合比hibernate更灵活一些。hibernate相对来讲,更适合做网站类项目,应用简单灵活。不过对于银行这类的项目弱点
    3:引用传递:两个指向一个对象
                值传递:一个变量接受一个值

2:hibernate的环境搭建

         1:下载hibernate文件包,创建项目,导入需求(require)包

 

                  

----------------------------------------------------------------------------

 

         2:创建hibernate.cfg.xml配置文件(注意约束文件地址的缘由)

 

         <!DOCTYPEhibernate-configurationPUBLIC

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

       <!-- hibernate.connection.driver_class中的hibernatehibernate项目中可以省略 -->

       <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

       <!-- ///自动访问本地的数据库,默认端口没变的情况下可以这么写 -->

       <propertyname="hibernate.connection.url">jdbc:mysql:///hibernate</property>

       <propertyname="hibernate.connection.username">root</property>

       <propertyname="hibernate.connection.password">root</property>

      

       <!-- 添加额外的属性显示sql语句并格式化-->

       <propertyname="show_sql">true</property>

       <propertyname="format_sql">true</property>

      

       <!-- 引入hibernateORM文件 -->

       <!--

           ORM:对象关系映射(Object Relational Mapping

           1:对象名称映射表名

           2:对象的属性名映射字段名

           3:对象的类型映射字段兼容类型

        -->

       <mappingresource="com/hb/demo/pojo/BookInfo.hbm.xml"/>

       <mappingresource="com/hb/demo/pojo/TypeInfo.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

         ----------------------------------------------------------------------------

 

         3:创建两个pojo实体BookInfo、TypeInfo

                  private IntegerbookId;

        private StringbookName;

        private StringbookAuthor;

        private FloatbookPrice;

        private DatebookPublishDate;

        private TypeInfo type;

 

       private IntegertypeId;

        private String typeName;

----------------------------------------------------------------------------

 

    4:创建两个实体的BookInfo.hbm.xml、TypeInfo.hbm.xml映射配置(统一注意约束)

<!DOCTYPEhibernate-mappingPUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mappingpackage="com.hb.demo.pojo">

    <!--

       字段和表名不区分大小写

       属性要区分大小写

    -->

    <classname="TypeInfo"table="TypeInfo">

      

       <!-- 配置主键 -->

       <idname="typeId"type="java.lang.Integer">

           <columnname="typeId"sql-type="int"/>

           <!--

              主键生成策略

              1native               根据hibernate提供对应数据的方言来生成id

              2increment,identity   mysql/sqlserver

              3sequence              oracle

              4assigned             需要手动制定主键的值

           -->

           <generatorclass="native"/>

       </id>

      

       <!-- 配置属性类型可自动识别,mybatis也一致-->

       <propertyname="typeName"column="typeName"/>

    </class>

</hibernate-mapping>

 

----------------------------------------------------------------------------

    <!DOCTYPEhibernate-mappingPUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mappingpackage="com.hb.demo.pojo">

    <classname="BookInfo"table="BookInfo">

       <idname="bookId"column="bookId">

           <generatorclass="native"/>

       </id>

      

       <!--

           有三种书写方式

           column可省略

       -->

       <propertyname="bookName">

           <columnname="bookName" />

       </property>

      

       <propertyname="bookAuthor"column="bookAuthor"/>

      

       <propertyname="bookPrice"/>

       <propertyname="bookPublishDate"/>

      

       <!-- 配置多对一 -->

       <!--

           name       属性被设置为在父类中定义的变量

           class      关联的类的名字

           culumn-name   数据库中的BookInfotypeId字段名称

       -->

       <many-to-onename="type"class="TypeInfo">

           <!-- 数据库中的BookInfotypeId字段名称 -->

           <columnname="typeId"/>

       </many-to-one>

    </class>

</hibernate-mapping>

 

----------------------------------------------------------------------------

 

5:简单测试

public class TestHibernateDev {

    private static SessionFactory sessionFactory;

    private static final String FILE_PATH="/hibernate.cfg.xml";

    private Sessionsession;

   

    static{

       //1:加载hibernate的配置文件

       Configurationcfg= newConfiguration().configure(FILE_PATH);

      

       //2:hibernate4以下版本,5以上版本

       //sessionFactory = cfg.buildSessionFactory();

      

       //3:   4版本

           //1:注册一个创建SessionFactory对象的服务对象ServiceRegistry

       ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();

           //2:构建SessionFactory对象

       sessionFactory=cfg.buildSessionFactory(serviceRegistry);

    }

 

//断言测试,判断对象是否存在

@Test

    public void testSessionFactory(){

       System.out.println(sessionFactory);

       //断言(可使用包静态导入)

       Assert.assertNotNull(sessionFactory);

}

 

    //获取SessionFactory中的Session对象

    @Before

    public void getSession(){

       System.out.println("执行测试方法之前执行");

       session = sessionFactory.openSession();

    }

 

    @Test

    public void testSession(){

       System.out.println(session);

    }

 

    @After

    public void closeSession(){

       System.out.println("执行测试方法之后执行");

       if(session.isConnected()){

           session.close();

           session = null;

       }

    }  

}

----------------------------------------------------------------------------

6:测试添加对象的方法

/**

     * 测试添加对象的方法

     * 2017413

     * void

     * saveObject

     */

    @Test

    public void saveObject(){

       // 创建一个TypeInfo对象

       TypeInfotypeInfo= newTypeInfo();

       typeInfo.setTypeName("漫画");

       typeInfo.setTypeId(32);

      

       // 定义事务对象的句柄

       Transactiontx = null;

      

       try {

           //开启事务对象

           tx = session.beginTransaction();

          

           // 返回当前新增数据对应的主键值

           /*Serializable result = session.save(typeInfo);*/

          

           // 根据对象session中存储的oid存在,进行修改,只设置名称进行新增;

           /*session.saveOrUpdate(typeInfo);*/

          

           // 先判断是否存在oid,存在:detached entity passedto persist;只有在事务中执行,才能打印sql语句,没有id时,直接添加

           session.persist(typeInfo);

          

           tx.commit();

          

//System.out.println(result);

       }catch(Exceptione) {

           e.printStackTrace();

          

           if(tx !=null){

              // 回滚事务

              tx.rollback();

           }

       }

    }

----------------------------------------------------------------------------

 

/**

     * 测试修改的方式

     * 2017413

     * void

     * updateObject

     */

    @Test

    public void updateObject(){

       // 创建一个TypeInfo对象

       TypeInfotypeInfo= newTypeInfo();

       typeInfo.setTypeName("文学");

       typeInfo.setTypeId(34);

      

       // 定义事务对象的句柄

       Transactiontx = null;

      

       try {

           tx = session.beginTransaction();

          

           //1:推荐

//         session.update(typeInfo);

          

           //2:必须设置typeId

//         session.saveOrUpdate(typeInfo);

          

           //3:   1:查询数据存在后,所有字段都相同时,不会更新,

           //     2:发现typeId不存在时,实行增加(typeId可加可不加)

           //     3:typeId存在时,名字不同时,实行修改

           session.merge(typeInfo);

          

           tx.commit();

       }catch(Exceptione) {

           e.printStackTrace();

          

           if(tx !=null){

              // 回滚事务

              tx.rollback();

           }

       }

    }

----------------------------------------------------------------------------

/**

     * 测试删除的方式

     * 只能通过主键删除对象

     * 2017413

     * void

     * updateObject

     */

    @Test

    public void deleteObject(){

       // 创建一个TypeInfo对象

       TypeInfotypeInfo= newTypeInfo();

       typeInfo.setTypeId(33);

      

       // 定义事务对象的句柄

       Transactiontx = null;

      

       try {

           tx = session.beginTransaction();

          

           //必须typeId存在,否则会报错

           session.delete(typeInfo);

          

           tx.commit();

       }catch(Exceptione) {

           e.printStackTrace();

          

           if(tx !=null){

              // 回滚事务

              tx.rollback();

           }

       }

    }

----------------------------------------------------------------------------

3:hibernate的三种状态


    ////////////////对象的三种状态(瞬时,持久,游离)//////////////////////

    // 1:瞬时:与session没有关联,hibernate监控不到对象的状态

   

    // 2:持久:与session有关联,事务未提交,当对象的内容发生变化时,hibernate可以监控到

   

    // 3:游离(删除|托管):与session没有关联;游离对象在数据库中可能还存在一条与它对应的记录,hibernate检测不了对象的状态

    @Test

    public void testState(){

       TypeInfotypeInfo= newTypeInfo();//瞬时态

      

       typeInfo.setTypeName("xxx");

      

       Transactiontx = null;

      

       try {

           tx = session.beginTransaction();

          

           // 判断oid是否存在:存在就报错,不存在更新,没有id时,直接添加

           session.persist(typeInfo);//提交事务对象变为持久状态

           typeInfo.setTypeName("aaa");

          

           tx.commit();

          

           /*// 会打印修改语句

           typeInfo.setTypeName("bbb");

          

           //如果一个对象以及是持久化状态了,那么此时对该对象进行各种修改,

            * 或者调用多次updatesave方法时,hibernate都不会发送sql语句,

            * 只有当事物提交的时候,此时hibernate才会拿当前这个对象与之前保存在session中的持久化对象进行比较,

            * 如果不相同就发送一条updatesql语句,否则就不会发送update语句

          

           //删除后,不会打印修改和删除语句

           session.delete(typeInfo);*/

          

           session.close();//关闭session后变为游离状态(托管对象)

           System.out.println(typeInfo.getTypeName());

          

           typeInfo.setTypeName("ccccccccc");

           session = sessionFactory.openSession();

          

           /*// 不能对托管对象进行持久化操作

           session.persist(typeInfo);*/

          

           session = sessionFactory.openSession();

           tx = session.beginTransaction();

          

           //sava可以将托管对象转换为持久对象

           session.save(typeInfo);

           tx.commit();

       }catch(Exceptione) {

           if(tx !=null){

              tx.rollback();

           }

       }

    }

----------------------------------------------------------------------------

4:使用hibernate插件搭建环境

    1:使用link安装插件方式

1.   在eclipse目录创建myplugins和links


2.   将插件的两个文件复制到myplugins中


3.   在links创建配置文件,以.link结尾,名字可任意

配置内容:

Path=myplugins的目录(path=D:\\eclipse\\myplugins)

 

       2:使用插件工具生成hibernate.cfg.xml配置文件


          

              1:添加额外属性

                  <propertyname="show_sql">true</property>

                  <propertyname="format_sql">true</property>

 

              2:引入hibernate的ORM文件

<mappingresource="com/hb/demo/pojo/BookInfo.hbm.xml"/>

                  <mappingresource="com/hb/demo/pojo/TypeInfo.hbm.xml"/>

 

              3:配置正向生成数据库中的表      

update:每次访问的时候会检测如果存在就不更新

                  create:每次访问都会删除重新生成语句(需要修改数据库的时候使用)

                 

 <property name="hbm2ddl.auto">update</property>

 

       3:创建BookInfo和TyperInfo实体,再使用插件工具通过实体生成


          

           注意两个小细节

              1:将所有的列表格式化

<column name="BOOK_ID" />

              2:将修改生成主键策略

                  <generatorclass="native" />

 

5:创建一个sessionFactory工具类,

           1:保证一个数据库对应一个sessionFactory

           2:保证同一个客户端用户使用同一个session对象

 

public class HibernateSessionFactory {

    private static SessionFactory sessionFactory;

 

    // 使用本地线程对象管理session对象

    private final staticThreadLocal<Session>threadLocal =newThreadLocal<Session>();

 

    // 保证满足第一个条件

    static {

       buildSessionFactory();

    }

 

    /**

     * 定义构建SessionFactory对象的方法 2017414

     *

     * @return SessionFactory buildSessionFactory

     */

    public static void buildSessionFactory() {

       // 判断SessionFactory是否为空

       if (sessionFactory==null){

           Configurationcfg= newConfiguration().configure();

           ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties())

                  .build();

           sessionFactory=cfg.buildSessionFactory(serviceRegistry);

       }

    }

 

    /**

     * 定义获取session的方法

     * 2017414

     * @return

     * Session

     * getSession

     */

    public static Session getSession() {

       // 从本地线程中获取Session对象

       Sessionsession= threadLocal.get();

 

       // 判断sessionnull需要把创建的session对象方法放到本地线程中

       if (session ==null) {

           // 判断sessionFactory为空

           if(sessionFactory==null){

              buildSessionFactory();

           }

          

           session = sessionFactory.openSession();

 

           // 设置到本地线程中

           threadLocal.set(session);

       }

       returnsession;

    }

   

    public static void closeSession(){

       Sessionsession= threadLocal.get();

      

       if(session.isConnected()&&session!=null){

           session.close();

           session = null;

           threadLocal.set(null);

       }

    }

}

 

       简单的创建一个测试类,创建一个实例

       publicclass TestUtil {

        public static void main(String[] args) {

           System.out.println(HibernateSessionFactory.getSession());

            }

}

 

----------------------------------------------------------------------------

6:四种查询操作

 

1:原生SQL

public classTestNativeQuery {

    @SuppressWarnings("unchecked")

   

    /**

     * 查询所有字段

     * 2017414

     * void

     * testQueryAll

     */

    @Test

    public void testQueryAll() {

       Sessionsession= HibernateSessionFactory.getSession();

 

       // 创建原生SQL查询对象

       SQLQueryquery= session.createSQLQuery("select * from bookInfo");

 

       // 1:得到对象地址

         /*List<?>list = query.list();

         System.out.println(list); */

       // 返回结果:

       // [[Ljava.lang.Object;@4e0ae11f,[Ljava.lang.Object;@238d68ff,

       // [Ljava.lang.Object;@4b86805d,[Ljava.lang.Object;@5852c06f]

        

 

       // 2: 返回对象的键的值

         /*List<Object[]>list = query.list();

         for (Object[] object : list) {System.out.println(object[0]); }*/

       // 返回结果:

       //1

       //2

       //3

       //4

 

       // 3:返回实体对象地址

         List<BookInfo> bookList =query.addEntity(BookInfo.class).list();

         System.out.println(bookList);

       // 返回结果:

       // [com.hb.demo.pojo.BookInfo@4149c063,

       // com.hb.demo.pojo.BookInfo@6c7a164b,

       // com.hb.demo.pojo.BookInfo@4c2bb6e0,

       // com.hb.demo.pojo.BookInfo@3e62d773]

    }

 

    /**

     * 查询单个字段 2017414 voidTestQuerySingle

     */

    @SuppressWarnings("unchecked")

    @Test

    public void TestQuerySingle() {

       Sessionsession= HibernateSessionFactory.getSession();

 

       SQLQueryquery= session.createSQLQuery("select book_name from bookInfo");

 

       // 返回查询单个字段值组成数组

       List<Object>list= query.list();

       System.out.println(list);

 

       // 返回结果:

       // [朝花夕拾,三国演义,葫芦娃,近代史]

    }

 

    /**

     * 查询多个字段

     * 2017414

     * void

     * TestQueryMultiple

     */

    @SuppressWarnings("unchecked")

    @Test

    public void TestQueryMultiple() {

       Sessionsession= HibernateSessionFactory.getSession();

 

       // 1:不加条件的多个字段查询

       /*SQLQuery query = session.createSQLQuery("selectbook_Id,book_Name from bookInfo");

 

       //返回查询多个字段值组成数组集合

       List<Object>list = query.list();

       System.out.println(list);

 

       //返回结果

       //[[Ljava.lang.Object;@78fa769e, [Ljava.lang.Object;@16612a51,

       //[Ljava.lang.Object;@54e041a4, [Ljava.lang.Object;@2c78324b]*/  

      

       // 2:帅选条件的多个字段查询(两种写法)

           // 1:不使用占位符的方式写条件

       SQLQueryquery= session.createSQLQuery("select book_Id,book_Name from bookInfo wherebook_id=?");

      

       // 设置参数

       query.setInteger(0, 2);

      

       List<Object>list= query.list();

       System.out.println(list);

      

       // 返回结果:

       // [[Ljava.lang.Object;@54e041a4]

      

           // 2:使用占位符的方式写条件

       SQLQueryquery1= session.createSQLQuery("select book_Id,book_Name from bookInfo wherebook_id=:bookId");

      

       // 设置参数

       query1.setInteger("bookId",2);

      

       List<Object>list1= query1.list();

       System.out.println(list1);

    }

}

 

----------------------------------------------------------------------------

2:HQL测试HQL的查询操作

public classTestHibernateQuery{

   

    /**

     * 查询所有实体对象

     * 2017414

     * void

     * testQueryAll

     */

    @SuppressWarnings("unchecked")

    @Test

    public void testQueryAll(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       // 创建HQL查询对象

       // HQL sql语句的(标准)是关键字全部大写

       Queryquery= session.createQuery("FROM BookInfo");

       System.out.println(query.list());

      

       List<BookInfo>bookList=query.list();

      

       for (BookInfobookInfo :bookList) {

           System.out.println(bookInfo.getType().getTypeName());

       }

      

       // 返回结果:

       // [com.hb.demo.pojo.BookInfo@1787bc24,com.hb.demo.pojo.BookInfo@29a5f4e7,

       // com.hb.demo.pojo.BookInfo@79c97cb,com.hb.demo.pojo.BookInfo@2d9caaeb]

    }

   

    /**

     * 查询单个实体对象

     * 2017414

     * void

     * testQuerySingle

     */

    @SuppressWarnings("unchecked")

    @Test

    public void testQuerySingle(){

       Sessionsession= HibernateSessionFactory.getSession();

        

       Queryquery= session.createQuery("SELECT new BookInfo(bookName) FROM BookInfo");

      

       List<BookInfo>bookList=query.list();

      

       System.out.println(bookList.get(0).getBookName());

       // 返回结果:

       // 朝花夕拾

    }

   

    /**

     * 带条件的查询对象

     * 2017414

     * void

     * testQueryByCount

     */

    @SuppressWarnings("unchecked")

    @Test

    public void testQueryByCount(){

       Sessionsession= HibernateSessionFactory.getSession();

        

       Queryquery= session.createQuery("FROM BookInfo WHERE type.typeId=:typeId");

      

       query.setInteger("typeId",3);

      

       List<BookInfo>bookList=query.list();

       System.out.println(bookList);

      

       // 返回结果:

       // [com.hb.demo.pojo.BookInfo@59d4cd39]

    }

   

    /**

     * 查询单条记录的时候

     * 2017414

     * void

     * testQueryByCount

     */

    @Test

    public void testSingleRecord(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       Queryquery= session.createQuery("FROM BookInfo WHERE bookId=:bookId");

      

       query.setInteger("bookId",3);

      

       BookInfobookInfo= (BookInfo)query.uniqueResult();

      

       System.out.println(bookInfo);

      

       // 返回结果:

       // com.hb.demo.pojo.BookInfo@59d4cd39

    }

   

    /**

     * 查询单条数据

     * 2017414

     * void

     * testSingleRecord

     */

    @Test

    public void testLoad(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       BookInfobookInfo= (BookInfo)session.load(BookInfo.class, 2);

      

       System.out.println(bookInfo);

       HibernateSessionFactory.closeSession();

       // 返回结果:

       // com.hb.demo.pojo.BookInfo@463fd068

    }

   

    /**

     * 查询单条数据

     * 2017414

     * void

     * testGet

     */

    @Test

    public void testGet(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       BookInfobookInfo= (BookInfo)session.get(BookInfo.class, 2);

      

       System.out.println(bookInfo);

       HibernateSessionFactory.closeSession();

       // 返回结果:

       // com.hb.demo.pojo.BookInfo@463fd068

    }

   

    /**

     * 查询单条数据得到TypeInfo的字段

     * 2017414

     * void

     * testGet

     */

    @Test

    public void testGetTypeInfo(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       BookInfobookInfo= (BookInfo)session.get(BookInfo.class, 2);

      

       System.out.println(bookInfo.getType().getTypeName());

       HibernateSessionFactory.closeSession();

       // 返回结果:

       // 小说

    }

   

    /**

     * 测试load() get()两者的结果是否相同

     * 2017414

     * void

     * test

     */

    @Test

    public void test(){

       testLoad();

       testGet();

       // 返回结果:相同

       // 因为查询后oidsession)会放在缓存中,若存在就直接拿

    }

   

    /**

     * 测试分页查询

     * 2017414

     * void

     * testPagination

     */

    @Test

    public void testPagination(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       Queryquery= session.createQuery("FROM BookInfo");

      

       // (当前页-1)*每页数=当前页第一条数据的记录数

       query.setFirstResult(2);//从第2条记录开始

       query.setMaxResults(2);//每页显示2

      

       System.out.println(query.list());

      

       // 返回结果为:

       // [com.hb.demo.pojo.BookInfo@6b6776cb,com.hb.demo.pojo.BookInfo@f14a7d4]

      

       // 查询最新一个对象

       // select * from bookInfo order by book_Iddesclimit 1

 

       // 查询最新一个id

       // select MAX(book_Id) from bookInfo

    }

   

    /**

     * 查询总记录数

     * 2017414

     * void

     * testCount

     */

    @Test

    public void testCount(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       Queryquery= session.createQuery("SELECT count(*) FROM BookInfo");

      

       // 两种取值

       System.out.println(query.list().get(0));

       System.out.println((((Long)query.iterate().next())).intValue());

      

       // 返回结果为:

       // 4

    }

}

 

----------------------------------------------------------------------------

3:QBC操作

public classTestHibernateCriteria {

   

    /**

     * 查询所有实体对象

     * 2017414

     * void

     * testQueryAll

     */

    @SuppressWarnings("unchecked")

    @Test

    public void testQueryAll(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       List<BookInfo>bookList= (List<BookInfo>)session.createCriteria(BookInfo.class).list();

      

       System.out.println(bookList);

      

       // 返回结果:

       // [com.hb.demo.pojo.BookInfo@74287ea3,com.hb.demo.pojo.BookInfo@a8ef162,

       // com.hb.demo.pojo.BookInfo@7ac296f6,com.hb.demo.pojo.BookInfo@22f59fa]

    }

   

    /**

     * 查询所有对象的某一个字段

     * 2017414

     * void

     * testQueryAll

     */

    @Test

    public void testSingleField(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       Criteriacrt= session.createCriteria(BookInfo.class);

      

       /*crt.setProjection(Projections.id());

      

       System.out.println(crt.list());

       //返回结果:

       //[1, 2, 3, 4]

       */

      

       crt.setProjection(Projections.property("bookName"));

       System.out.println(crt.list());

       // 返回结果:

       // [朝花夕拾,三国演义,葫芦娃,近代史]

    }

   

    /**

     * 查询所有对象的多个字段(根据条件'模糊查询)

     * 2017414

     * void

     * testMultipleField

     */

    @Test

    public void testMultipleField(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       Criteriacrt= session.createCriteria(BookInfo.class);

      

    crt.setProjection(Projections.projectionList().add(Projections.property("bookName")).add(Projections.property("bookAuthor")));

      

       crt.add(Restrictions.eq("bookId",1));

       crt.add(Restrictions.ilike("bookName","", MatchMode.ANYWHERE));

       // ilike 忽略大小写

 

       System.out.println(crt.list());

       System.out.println(crt.uniqueResult());

      

      

       // 返回结果:

       // [[Ljava.lang.Object;@17d919b6]

       // [Ljava.lang.Object;@7283d3eb

    }

}

 

----------------------------------------------------------------------------

4:命名SQL查询

public classTestNamedQuery {

   

    /**

     * 查询所有对象

     * 2017414

     * void

     * testQueryAll

     */

    @Test

    public void testQueryAll(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       Queryquery= session.getNamedQuery("selectAll");

      

       query.setInteger("bookId",2);

      

       System.out.println(query.list());

       // 返回结果

       // [com.hb.demo.pojo.BookInfo@5495333e]

    }

   

    /**

     * 查询所有对象

     * 2017414

     * void

     * testSQLQuery

     */

    @Test

    public void testSQLQuery(){

       Sessionsession= HibernateSessionFactory.getSession();

      

       SQLQueryquery= (SQLQuery)session.getNamedQuery("selectSqlAll");

       query.addEntity(BookInfo.class);

      

       System.out.println(query.list());

       // 返回结果

       // [com.hb.demo.pojo.BookInfo@61eaec38,com.hb.demo.pojo.BookInfo@31920ade,

       // com.hb.demo.pojo.BookInfo@1d483de4,com.hb.demo.pojo.BookInfo@4032d386]

    }

}

 

    一:一对一映射

       1:主键关联

       注意: 1:<one-to-one name="card"class="com.relational.onetoone_primary.IDCard" />  Person.hbm.xml

 

               2:<generatorclass="foreign">  IDcard.hbm.xml

                      <paramname="property">person</param>

                 </generator>

 

              constrained="true"

                IDCard表和Person表存在外键关系

                one-to-one的单向关联中,如果constrained=false,则会在查询时就全部取出来,用left outer join的方式。

                如果constrained=truehibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。

           

                cascade="all"

                all : 所有情况下均进行关联操作。

               none:所有情况下均不进行关联操作。这是默认值。

               save-update:在执行save/update/saveOrUpdate时进行关联操作。

               delete:在执行delete时进行关联操作。

              3:<one-to-onename="person" class="com.relational.onetoone_primary.Person"cascade="all" constrained="true" />

          

        2:外键关联

默认情况下,把被关联实体主键字段作为关联字段。

有了property-ref,就可以通过它指定被关联实体主键以外的字段作为关联字段。

property-ref="person" card表和person表建立外键关系

          注意:1:<one-to-onename="card" class="com.relational.onetoone_foreign.IDCard"property-ref="person" />Person.hbm.xml

               2:<many-to-one name="person"class="com.relational.onetoone_foreign.Person"unique="true">    IDcard.hbm.xml

                       <columnname="person_id" unique="true" />

                  </many-to-one>

       

    二:多对一映射

       注意:  1:  privateInteger deptId;

                  privateString deptName;

                  privateSet<Emp> emps = newHashSet<Emp>();

                 

              2:  private Integer empId;

                  privateString empName;

                  privateDept dept;

              

              Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,

              但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。

              3:  <set name="emps"inverse="true">

                      <key>

                          <columnname="DEPT_ID" />

                      </key>

                      <one-to-manyclass="Emp" />

                   </set>

              

               join方式,主体对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询

               4:  <many-to-onename="dept" class="Dept" fetch="join">

                      <columnname="DEPT_ID" />

                  </many-to-one>

   

    三:多对多映射

       注意: 1: privateInteger stuId;

                  privateString stuname;

                  privateSet teas = new HashSet(0);

                 

              2: private Integer teaId;

                  privateString teaname;

                  privateSet stus = new HashSet(0);

                 

              3: <set name="teas"table="TEA_STU" inverse="false" lazy="true">

                       <key>

                           <columnname="STU_ID" />

                       </key>

                       <many-to-manyclass="com.relational.manytomany.Tea">

                           <columnname="TEA_ID" />

                       </many-to-many>

                   </set>

                  

               4:<set name="stus" table="TEA_STU"inverse="false" lazy="true">

                       <key>

                           <columnname="TEA_ID" />

                       </key>

                       <many-to-manyclass="com.relational.manytomany.Stu">

                           <columnname="STU_ID" />

                       </many-to-many>

                   </set>

                  

    四:JPA注解映射

              1: @Table(name = "dpetInfo") // 指定数据中生成表名

                  @Entity(name="DeptInfo")// 指定对象查询过程中使用对象名

                  publicclass Dept {

                     privateInteger deptId;

                     privateString deptName;

                     privateSet<Emp> emps = newHashSet<Emp>();

                    

                     @Id

                     @GeneratedValue(strategy=GenerationType.AUTO)

                     publicInteger getDeptId() {

                         returndeptId;

                     }

                     publicvoid setDeptId(Integer deptId) {

                         this.deptId= deptId;

                     }

                    

                     @Column(name="dname")

                     publicString getDeptName() {

                         returndeptName;

                     }

                    

                     publicvoid setDeptName(String deptName) {

                         this.deptName= deptName;

                     }

                    

                     @OneToMany(mappedBy="dept")

                     publicSet<Emp> getEmps() {

                         returnemps;

                     }

                    

                     publicvoid setEmps(Set<Emp> emps) {

                         this.emps= emps;

                     }

                  }

                 

                  表名一样,只配一个entity即可

                  2: @Entity

                     publicclass Emp {

                         privateInteger empId;

                         privateString empName;

                         privateDept dept;

                        

                         @Id

                         @Column(name= "emp_id")

                         @GeneratedValue(strategy=GenerationType.AUTO)

                         publicInteger getEmpId() {

                            returnempId;

                         }

                        

                         publicvoid setEmpId(Integer empId) {

                            this.empId= empId;

                         }

                        

                         当属性名和列名相同时,@Column()可省略

                         publicString getEmpName() {

                            returnempName;

                         }

                        

                         publicvoid setEmpName(String empName) {

                            this.empName= empName;

                         }

                        

                         @ManyToOne

                         @JoinColumn(name="dept_id")

                         publicDept getDept() {

                            returndept;

                         }

                        

                         publicvoid setDept(Dept dept) {

                            this.dept= dept;

                         }

                     }

7:一对一映射

sessionFactory        util工具类

public classHibernateUtil {

    private static SessionFactory sessionFactory;

    // 使用本地线程对象管理Session对象

    private final staticThreadLocal<Session>threadLocal =newThreadLocal<Session>();

   

    // 保证满足第一个条件

    static {

       buildSessionFactory();

    }

   

    /**

     * 定义构建SessionFactory对象的方法

     */

    private static void buildSessionFactory() {

       // 判断sessionFactory是否为空

       if ( sessionFactory==  null ) {

           Configurationcfg= newConfiguration().configure();

           ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();

           sessionFactory=cfg.buildSessionFactory(serviceRegistry);

       }

    }

   

    /**

     * 定义获取Session对象的方法

     */

    public static Session getSession() {

       // 从本地线程中获取Session对象

       Sessionsession= threadLocal.get();

      

       // 判断sessionnull需要把创建Session对象放到本地线程对象中

       if ( session == null ) {

           if (sessionFactory==null){

              buildSessionFactory();

           }

           session = sessionFactory.openSession();

           // 设置到本地线程中

           threadLocal.set(session);

       }

      

       returnsession;

    }

   

    /**

     * 定义关闭Session的方法

     */

    public static void closeSession() {

       // 从本地线程中获取Session对象

       Sessionsession= threadLocal.get();

      

       if (session !=null &&session.isConnected()) {

           session.close();

           session = null;

           threadLocal.set(null);

       }

    }

}

 

 

1:外键共享

 

a:hibernate.cfg.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPEhibernate-configurationPUBLIC

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

        <!-- 关联一对一映射文件 -->

       <!--  <mapping resource="com/relational/onetoone_primary/Person.hbm.xml"/>

        <mapping resource="com/relational/onetoone_primary/IDCard.hbm.xml"/>

   </session-factory>

</hibernate-configuration>

 

b:创建实体:

    private Integerid;

    private Stringnumber;

    private Person person;

 

    private Integerid;

    private Stringname;

    private IDCard card;

 

c:配置实体映射文件

    Person.hbm.xml

<hibernate-mapping>

   <classname="com.relational.onetoone_primary.Person"table="PERSON">

        <idname="id"type="java.lang.Integer">

            <columnname="ID"/>

            <generatorclass="native"/>

        </id>

        <propertyname="name"type="java.lang.String">

            <columnname="NAME"/>

        </property>

        <one-to-onename="card"class="com.relational.onetoone_primary.IDCard"/>

   </class>

</hibernate-mapping>

 

    IDCard.hbm.xml

<hibernate-mapping>

   <classname="com.relational.onetoone_primary.IDCard"table="IDCARD">

        <idname="id"type="java.lang.Integer">

            <columnname="ID"/>

            <!-- IDCARD中主键的值由Person表的主键值提供 -->

            <generatorclass="foreign">

                <paramname="property">person</param>

            </generator>

        </id>

        <propertyname="number"type="java.lang.String">

            <columnname="NUMBER"/>

        </property>

        <!--

            constrained="true"IDCard表和Person表存在外键关系(设置cascade="all"级联后,只需要设置调用副表的添加方法session.save(card);即可)

         -->

        <one-to-onename="person"class="com.relational.onetoone_primary.Person"cascade="all"constrained="true"/>

   </class>

</hibernate-mapping>

 

d: TestRelational测试

public classTestRelational {

   

    @Test

    public void testOneToOne() {

       System.out.println(HibernateUtil.getSession());

    }

   

    @Test

    public void testAdd() {

       Sessionsession= HibernateUtil.getSession();

       // 创建一个人

       Personperson= newPerson();

       person.setName("张文娜1");

       // 创建一个身份证对象

       IDCardcard= newIDCard();

       card.setNumber("500335198810167423");

       // 设置关系

       person.setCard(card);

       card.setPerson(person);

      

       // 开启事务

       session.beginTransaction();

       // 保存操作

       session.save(card);

       session.getTransaction().commit();

    }

   

    @Test

    public void testQuery() {

       Sessionsession= HibernateUtil.getSession();

       //(注意两种查询存在的区别)懒加载

       //1:如果查询子表的字段时,不会去查询副表

       //2:如果查询父表的字段,那么也会关联查询所有的子表信息

       Personperson= (Person) session.load(Person.class, 2);

       System.out.println(person.getName()+"--"+person.getCard().getNumber());

      

       IDCardcard=  (IDCard) session.load(IDCard.class, 1);

       System.out.println(card.getNumber()+"---"+card.getPerson().getName());

    }

}

 

2:外键关联

 

a: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

        <!-- 关联一对一映射文件 -->

        <mapping resource="com/relational/onetoone_foreign/Person.hbm.xml"/>

        <mapping resource="com/relational/onetoone_foreign/IDCard.hbm.xml"/>-->

   </session-factory>

</hibernate-configuration>

 

b:创建实体:

    private Integerid;

    private Stringnumber;

    private Person person;

 

    private Integerid;

    private Stringname;

    private IDCard card;

 

c:配置实体映射文件

    Person.hbm.xml

<hibernate-mapping>

   <classname="com.relational.onetoone_foreign.Person"table="PERSON1">

        <idname="id"type="java.lang.Integer">

            <columnname="ID"/>

            <generatorclass="native"/>

        </id>

        <propertyname="name"type="java.lang.String">

            <columnname="NAME"/>

        </property>

        <!--

            property-ref="person"card表和person表建立外键关系

         -->

        <one-to-onename="card"class="com.relational.onetoone_foreign.IDCard"property-ref="person"/>

   </class>

</hibernate-mapping>

 

    IDCard.hbm.xml

<hibernate-mapping>

   <classname="com.relational.onetoone_foreign.IDCard"table="IDCARD1">

        <idname="id"type="java.lang.Integer">

            <columnname="ID"/>

            <generatorclass="native"/>

        </id>

        <propertyname="number"type="java.lang.String">

            <columnname="NUMBER"/>

        </property>

        <many-to-onename="person"class="com.relational.onetoone_foreign.Person"unique="true">

            <columnname="person_id"unique="true"/>

        </many-to-one>

   </class>

</hibernate-mapping>

 

d: TestRelational测试

public classTestRelational {

   

    @Test

    public void testOneToOne() {

       System.out.println(HibernateUtil.getSession());

    }

   

    @Test

    public void testAdd() {

       Sessionsession= HibernateUtil.getSession();

       // 创建一个人

        Person person = new Person();

       person.setName("张文娜1");

       // 创建一个身份证对象

       IDCardcard= newIDCard();

       card.setNumber("500335198810167423");

       // 设置关系

       person.setCard(card);

       card.setPerson(person);

      

       // 开启事务

       session.beginTransaction();

       // 保存操作

        session.save(person);

       session.save(card);

       session.getTransaction().commit();

    }

   

    @Test

    public void testQuery() {

       Sessionsession= HibernateUtil.getSession();

      

       Personperson= (Person) session.load(Person.class, 1);

       System.out.println(person.getName()+"--"+person.getCard().getNumber());

      

       IDCardcard=  (IDCard) session.load(IDCard.class, 1);

       System.out.println(card.getNumber()+"---"+card.getPerson().getName());

    }

}

 

----------------------------------------------------------------------------

8:多对一映射

a: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

<!-- 关联多对一映射文件 -->

        <mapping resource="com/relational/onetomany/Dept.hbm.xml"/>

        <mapping resource="com/relational/onetomany/Emp.hbm.xml"/>

   </session-factory>

</hibernate-configuration>

 

b:创建Dept、Emp实体

    private IntegerdeptId;

    private StringdeptName;

    private Set<Emp> emps = new HashSet<Emp>();

 

    private IntegerempId;

    private StringempName;

    private Dept dept;

 

c: 配置实体映射文件

Dept.hbm.xml

<hibernate-mappingpackage="com.relational.onetomany">

   <classname="Dept"table="dept">

        <idname="deptId"type="java.lang.Integer">

            <columnname="DEPT_ID"/>

            <generatorclass="native"/>

        </id>

        <propertyname="deptName"type="java.lang.String">

            <columnname="DEPT_NAME"/>

        </property>

        <setname="emps"inverse="true">

            <key>

                <columnname="DEPT_ID"/>

            </key>

            <one-to-manyclass="Emp"/>

        </set>

   </class>

</hibernate-mapping>

 

    Emp.hbm.xml

<hibernate-mappingpackage="com.relational.onetomany">

   <classname="Emp"table="emp"catalog="hibernate">

        <idname="empId"type="java.lang.Integer">

            <columnname="EMP_ID"/>

            <generatorclass="native"/>

        </id>

        <many-to-onename="dept"class="Dept"fetch="join">

            <columnname="DEPT_ID"/>

        </many-to-one>

        <propertyname="empName"type="java.lang.String">

            <columnname="EMP_NAME"/>

        </property>

   </class>

</hibernate-mapping>

 

d: TestRelational测试

public classTestRelational {

   

    @Test

    public void testManyToOne() {

       System.out.println(HibernateUtil.getSession());

    }

   

    @Test

    public void testAdd() {

       Sessionsession= HibernateUtil.getSession();

       // 创建一个部门

       Deptdept= newDept();

       dept.setDeptName("开发部");

       // 创建2个员工

       Empemp1= newEmp();

       emp1.setEmpName("张三");

       Empemp2= newEmp();

       emp2.setEmpName("王五");

       // 设置关系

       emp1.setDept(dept);

       emp2.setDept(dept);

       // 开启事务

       session.beginTransaction();

       session.save(dept);

       session.save(emp1);

       session.save(emp2);

       session.getTransaction().commit();

    }

   

    @Test

    public void query() {

       Sessionsession= HibernateUtil.getSession();

       Deptdept= (Dept) session.get(Dept.class, 2);

       System.out.println(dept.getDeptName());

       System.out.println(dept.getEmps());

    }

}

 

----------------------------------------------------------------------------

9:多对多映射

a: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

<!-- 关联多对一映射文件 -->

       <mapping resource="com/relational/manytomany/Stu.hbm.xml"/>

       <mappingresource="com/relational/manytomany/Tea.hbm.xml"/>   

</session-factory>

</hibernate-configuration>

 

b:创建Stu、Tea实体

    private IntegerstuId;

    private Stringstuname;

    private Setteas =new HashSet(0);

    public Stu() {

    }

    public Stu(Teatea, Stringstuname, Setteas) {

       this.stuname =stuname;

       this.teas =teas;

    }

 

    private IntegerteaId;

    private Stringteaname;

    private Setstus =new HashSet(0);

    public Tea() {

    }

    public Tea(Stustu, Stringteaname, Setstus) {

       this.teaname =teaname;

       this.stus =stus;

    }

c: 配置实体映射文件

Stu.hbm.xml

<hibernate-mapping>

   <classname="com.relational.manytomany.Stu"table="STU">

        <idname="stuId"type="java.lang.Integer">

            <columnname="STUID"/>

            <generatorclass="native"/>

        </id>

        <propertyname="stuname"type="java.lang.String">

            <columnname="STUNAME"/>

        </property>

        <setname="teas"table="TEA_STU"inverse="false"lazy="true">

            <key>

                <columnname="STU_ID"/>

            </key>

            <many-to-manyclass="com.relational.manytomany.Tea">

                <columnname="TEA_ID"/>

            </many-to-many>

        </set>

   </class>

</hibernate-mapping>

 

    Tea.hbm.xml

<hibernate-mapping>

   <classname="com.relational.manytomany.Tea"table="TEA">

        <idname="teaId"type="java.lang.Integer">

            <columnname="TEAID"/>

            <generatorclass="native"/>

        </id>

        <propertyname="teaname"type="java.lang.String">

            <columnname="TEANAME"/>

        </property>

        <setname="stus"table="TEA_STU"inverse="false"lazy="true">

            <key>

                <columnname="TEA_ID"/>

            </key>

            <many-to-manyclass="com.relational.manytomany.Stu">

                <columnname="STU_ID"/>

            </many-to-many>

        </set>

   </class>

</hibernate-mapping>

d: TestRelational测试

public classTestRelational {

   

    @Test

    public void testManyToMany() {

       System.out.println(HibernateUtil.getSession());

    }

   

   

}

----------------------------------------------------------------------------

10:JPA注解实现多对一映射

 

a: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

 

        <mappingclass="com.relational.jpa.Dept"/>

        <mappingclass="com.relational.jpa.Emp"/>

   </session-factory>

</hibernate-configuration>

 

b:两个实体的注解

Dept

@Table(name= "dpetInfo") // 指定数据中生成表名

@Entity(name="DeptInfo")//指定对象查询过程中使用对象名

public classDept {

    private IntegerdeptId;

    private StringdeptName;

    private Set<Emp>emps =new HashSet<Emp>();

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getDeptId() {

       returndeptId;

    }

    public void setDeptId(Integer deptId) {

       this.deptId =deptId;

    }

   

    @Column(name="dname")

    public String getDeptName() {

       returndeptName;

    }

   

    public void setDeptName(String deptName) {

       this.deptName =deptName;

    }

   

    @OneToMany(mappedBy="dept")

    public Set<Emp>getEmps() {

       returnemps;

    }

   

    public void setEmps(Set<Emp> emps) {

       this.emps =emps;

    }

}

 

Emp

@Entity

public classEmp {

   

   

    private IntegerempId;

    private StringempName;

    private Deptdept;

   

    @Id

    @Column(name = "emp_id")

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getEmpId() {

       returnempId;

    }

   

    public void setEmpId(Integer empId) {

       this.empId =empId;

    }

   

    public String getEmpName() {

       returnempName;

    }

   

    public void setEmpName(String empName) {

       this.empName =empName;

    }

   

    @ManyToOne

    @JoinColumn(name="dept_id")

    public Dept getDept() {

       returndept;

    }

   

    public void setDept(Dept dept) {

       this.dept =dept;

    }

   

   

}

 

c: TestRelational测试

public classTestRelational {

   

    @Test

    public voidtestManyToOneInjection() {

       System.out.println(HibernateUtil.getSession());

    }

}


 

----------------------------------------------------------------------------

11:缓存(懒加载、一级缓存、二级缓存)

HibernateUtil

/**

 * 1、保证一个数据库对应一个SessionFactory对象

 * 2、保证在同一客户端用户使用同一个Session对象

 * @author Administrator

 *

 */

public classHibernateUtil{

    private static SessionFactory sessionFactory;

    // 使用本地线程对象管理Session对象

    private final staticThreadLocal<Session>threadLocal =newThreadLocal<Session>();

   

    // 保证满足第一个条件

    static {

       buildSessionFactory();

    }

   

    /**

     * 定义构建SessionFactory对象的方法

     */

    private static void buildSessionFactory() {

       // 判断sessionFactory是否为空

       if ( sessionFactory==  null ) {

           Configurationcfg= newConfiguration().configure();

           ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();

           sessionFactory=cfg.buildSessionFactory(serviceRegistry);

       }

    }

   

    /**

     * 定义获取Session对象的方法

     */

    public static Session getSession() {

       // 从本地线程中获取Session对象

       Sessionsession= threadLocal.get();

      

       // 判断sessionnull需要把创建Session对象放到本地线程对象中

       if ( session == null ) {

           if (sessionFactory==null){

              buildSessionFactory();

           }

           session = sessionFactory.openSession();

           // 设置到本地线程中

           threadLocal.set(session);

       }

      

       returnsession;

    }

   

    /**

     * 定义关闭Session的方法

     */

    public static void closeSession() {

       // 从本地线程中获取Session对象

       Sessionsession= threadLocal.get();

      

       if (session !=null &&session.isConnected()) {

           session.close();

           session = null;

           threadLocal.set(null);

       }

    }

}

 

1:懒加载

a: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1?userUnicode=true&characterEncoding=utf-8</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

        <mappingclass="com.hb.demo.pojo.CarInfo"/>

        <mappingclass="com.hb.demo.pojo.TypeInfo"/>

   </session-factory>

</hibernate-configuration>

 

b: TypeInfo

@Table(name= "typeInfo") // 指定数据中生成表名

@Entity(name="TypeInfo")//指定对象查询过程中使用对象名

public classTypeInfo implements Serializable{

 

    /**

     *

     */

    private static final long serialVersionUID= 1L;

   

    private IntegertypeId;

    private StringtypeName;

    private Set<CarInfo>cars =new HashSet<>();

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getTypeId() {

       returntypeId;

    }

    public void setTypeId(Integer typeId) {

       this.typeId =typeId;

    }

    public String getTypeName() {

       returntypeName;

    }

    public void setTypeName(String typeName) {

       this.typeName =typeName;

    }

   

    @OneToMany(mappedBy="type")

    public Set<CarInfo>getCars() {

       returncars;

    }

    public voidsetCars(Set<CarInfo> cars) {

       this.cars =cars;

    }

}

 

c: CarInfo

@Entity

public classCarInfo implementsSerializable{

 

    /**

     *

     */

    private static final long serialVersionUID= 1L;

    private Integerid;

    private Stringname;

    private Stringcolor;

    private TypeInfotype;

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getId() {

       returnid;

    }

    public void setId(Integer id) {

       this.id =id;

    }

    public String getName() {

       returnname;

    }

    public void setName(String name) {

       this.name =name;

    }

    public String getColor() {

       returncolor;

    }

    public void setColor(String color) {

       this.color =color;

    }

   

    @ManyToOne(fetch = FetchType.LAZY)

    @JoinColumn(name="type_id")

    public TypeInfo getType() {

       returntype;

    }

    public void setType(TypeInfo type) {

       this.type =type;

    }

}

 

d: TestLazy

/**

 * 延迟加载:需要使用对象的时候才会通过数据库生成的代理查询数据

 * load :  支持懒加载的

 * get  :  不支持懒加载,及时加载

 * @authorliang

 *

 */

public classTestLazy {

 

    @Test

    public voidtestManyToOneInjection() {

       System.out.println(HibernateUtil.getSession());

    }

 

    /*@Test

    publicvoid testAdd() {

       TypeInfoinfo1 = new TypeInfo();

       info1.setTypeName("手动挡");

       TypeInfoinfo2 = new TypeInfo();

       info2.setTypeName("自动挡");

       TypeInfoinfo3 = new TypeInfo();

       info3.setTypeName("全自动挡");

 

       try{

           Sessionsession = HibernateUtil.getSession();

 

           session.beginTransaction();

 

           session.persist(info1);

           session.persist(info2);

           session.persist(info3);

 

           session.getTransaction().commit();

       }catch (Exception e) {

       }

    }*/

   

    @Test

    public void testGet(){

       Sessionsession= HibernateUtil.getSession();

       CarInfocarInfo= (CarInfo)session.get(CarInfo.class, 2);//打印sql语句

//     HibernateUtil.closeSession();

       System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());

    }

   

    @Test

    public void testLoad(){

       Sessionsession= HibernateUtil.getSession();

       CarInfocarInfo= (CarInfo)session.load(CarInfo.class, 2);

//     HibernateUtil.closeSession();

       System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());//打印sql语句

    }

}

 

    2:一级缓存

a: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

        <mappingclass="com.hb.demo.pojo.CarInfo"/>

        <mappingclass="com.hb.demo.pojo.TypeInfo"/>

   </session-factory>

</hibernate-configuration>

 

b: TypeInfo

@Table(name= "typeInfo") // 指定数据中生成表名

@Entity(name="TypeInfo")//指定对象查询过程中使用对象名

public classTypeInfo implements Serializable{

 

    /**

     *

     */

    private static final long serialVersionUID= 1L;

   

    private IntegertypeId;

    private StringtypeName;

    private Set<CarInfo>cars =new HashSet<>();

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getTypeId() {

       returntypeId;

    }

    public void setTypeId(Integer typeId) {

       this.typeId =typeId;

    }

    public String getTypeName() {

       returntypeName;

    }

    public void setTypeName(String typeName) {

       this.typeName =typeName;

    }

   

    @OneToMany(mappedBy="type")

    public Set<CarInfo>getCars() {

       returncars;

    }

    public voidsetCars(Set<CarInfo> cars) {

       this.cars =cars;

    }

}

 

C: CarInfo

@Entity

public classCarInfo implements Serializable{

 

    /**

     *

     */

    private static final long serialVersionUID= 1L;

    private Integerid;

    private Stringname;

    private Stringcolor;

    private TypeInfotype;

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getId() {

       returnid;

    }

    public void setId(Integer id) {

       this.id =id;

    }

    public String getName() {

       returnname;

    }

    public void setName(String name) {

       this.name =name;

    }

    public String getColor() {

       returncolor;

    }

    public void setColor(String color) {

       this.color =color;

    }

   

    @ManyToOne(fetch = FetchType.EAGER)

    @JoinColumn(name="type_id")

    public TypeInfo getType() {

       returntype;

    }

    public void setType(TypeInfo type) {

       this.type =type;

    }

}

 

d: TestCache

/**

 * 一级缓存:

 * 1:Session级缓存

 * 2:不同session之间不能实现共享

 * 3:不可卸载的,Hibernate自带的

 *

 * 缺点:命中率低

 *

 * 解释:  1:如果查询的数据所对应的oidsession中存在,就使用session缓存中的对象

 *         2:如果不存在,从数据库中进行查询

 * @authorliang

 *

 */

public classTestCache {

 

    @Test

    public voidtestManyToOneInjection() {

       System.out.println(HibernateUtil.getSession());

    }

   

    /*@Test

    publicvoid testGet(){

       Sessionsession = HibernateUtil.getSession();

       CarInfocarInfo = (CarInfo) session.get(CarInfo.class, 2);//打印sql语句

//     HibernateUtil.closeSession();

       System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());

    }

   

    @Test

    publicvoid testLoad(){

       Sessionsession = HibernateUtil.getSession();

       CarInfocarInfo = (CarInfo) session.load(CarInfo.class, 2);//打印sql语句

//     HibernateUtil.closeSession();

       System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());

    }*/

   

    // 三种清空session方式

    @Test

    public void testFirstCache(){

       Sessionsession= HibernateUtil.getSession();

       CarInfocarInfo1= (CarInfo)session.get(CarInfo.class, 3);

       session.clear();//清空session中所有的缓存

       CarInfocarInfo2= (CarInfo)session.get(CarInfo.class, 3);

       session.evict(carInfo2);//清空session中指定的缓存对象

       CarInfocarInfo3= (CarInfo)session.get(CarInfo.class, 3);

//     session.close();

       System.out.println(carInfo1.getName()+""+carInfo1.getType().getTypeName());

       System.out.println(carInfo2.getName()+""+carInfo2.getType().getTypeName());

        System.out.println(carInfo3.getName()+""+carInfo3.getType().getTypeName());

    }

   

    @SuppressWarnings("unchecked")

    @Test

    public void testFirstCache1(){

       Sessionsession= HibernateUtil.getSession();

       List<CarInfo>list1= session.createCriteria(CarInfo.class).list();

       List<CarInfo>list2= session.createCriteria(CarInfo.class).list();

       List<CarInfo>list3= session.createCriteria(CarInfo.class).list();

      

       System.out.println(list1);

       System.out.println(list2);

       System.out.println(list3);

    }

}

 

    3:二级缓存

a:导入ehcache必备的包

 

B: hibernate.cfg.xml

<hibernate-configuration>

   <session-factory>

        <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <propertyname="hibernate.connection.password">root</property>

        <propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>

        <propertyname="hibernate.connection.username">root</property>

        <!-- 配置数据的方言 -->

        <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

       

        <!-- 配置额外属性 -->

        <propertyname="format_sql">true</property>

        <propertyname="show_sql">true</property>

        <!-- 配置正向生成数据中的表 -->

        <propertyname="hbm2ddl.auto">update</property>

       

        <!-- 配置二级缓存高速缓存提供类 -->

        <propertyname="hibernate.cache.region.factory_class">

            org.hibernate.cache.ehcache.EhCacheRegionFactory

        </property>

       

        <!-- 开启二级缓存 -->

        <propertyname="hibernate.cache.use_second_level_cache">true</property>

       

        <!-- 开启查询缓存 -->

        <propertyname="hibernate.cache.use_query_cache">true</property>

       

        <mappingclass="com.hb.demo.pojo.CarInfo"/>

        <mappingclass="com.hb.demo.pojo.TypeInfo"/>

   </session-factory>

</hibernate-configuration>

 

C: TypeInfo

@Table(name= "typeInfo") // 指定数据中生成表名

@Entity(name="TypeInfo")//指定对象查询过程中使用对象名

@Cache(usage= CacheConcurrencyStrategy.READ_ONLY)//配置缓存策略

public classTypeInfo implements Serializable{

 

    /**

     *

     */

    private static final long serialVersionUID= 1L;

   

    private IntegertypeId;

    private StringtypeName;

    private Set<CarInfo>cars =new HashSet<>();

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getTypeId() {

       returntypeId;

    }

    public void setTypeId(Integer typeId) {

       this.typeId =typeId;

    }

    public String getTypeName() {

       returntypeName;

    }

    public void setTypeName(String typeName) {

       this.typeName =typeName;

    }

   

    @OneToMany(mappedBy="type")

    public Set<CarInfo>getCars() {

       returncars;

    }

    public voidsetCars(Set<CarInfo> cars) {

       this.cars =cars;

    }  

}

 

D: CarInfo

@Entity

@Cache(usage= CacheConcurrencyStrategy.READ_ONLY)//配置缓存策略

public classCarInfo implements Serializable{

 

    /**

     *

     */

    private static final long serialVersionUID= 1L;

    private Integerid;

    private Stringname;

    private Stringcolor;

    private TypeInfotype;

   

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    public Integer getId() {

       returnid;

    }

    public void setId(Integer id) {

       this.id =id;

    }

    public String getName() {

       returnname;

    }

    public void setName(String name) {

       this.name =name;

    }

    public String getColor() {

       returncolor;

    }

    public void setColor(String color) {

       this.color =color;

    }

   

    @ManyToOne

    @JoinColumn(name="type_id")

    public TypeInfo getType() {

       returntype;

    }

    public void setType(TypeInfo type) {

       this.type =type;

    }

}

 

E: TestSecondCache

/**

 * 二级缓存:

 * 1sessionFactory缓存

 * 2:插拔式缓存

 * 3:修改少,不是重要数据

 *

 * 二级缓存配置步骤

 * 1:使用EhCache插件

 * 2: resource里面添加ehcache.xml配置文件

 * 3:在hibernate的配置文件中配置缓存类提供类

 *     a:开启二级缓存

 *     b:开启查询缓存

 * 4:配置缓存策略

 * @authorliang

 *

 */

public classTestSecondCache{

 

    @Test

    public voidtestManyToOneInjection() {

       System.out.println(HibernateUtil.getSession());

    }

   

    @SuppressWarnings("unchecked")

    @Test

    public void testSecondCache(){

       Sessionsession1= HibernateUtil.getSession();

       List<CarInfo>list1= session1.createCriteria(CarInfo.class).setCacheable(true).list();

       HibernateUtil.closeSession();

       Sessionsession2= HibernateUtil.getSession();

       List<CarInfo>list2= session2.createCriteria(CarInfo.class).setCacheable(true).list();

       HibernateUtil.closeSession();

       Sessionsession3= HibernateUtil.getSession();

       List<CarInfo>list3= session3.createCriteria(CarInfo.class).setCacheable(true).list();

       HibernateUtil.closeSession();

      

       System.out.println(list1);

       System.out.println(list2);

       System.out.println(list3);

    }

   

    @SuppressWarnings("unchecked")

    @Test

    public void testSecondCache1(){

       Sessionsession1= HibernateUtil.getSession();

       List<CarInfo>list1= session1.createQuery("FROM CarInfo").setCacheable(true).list();

      

       System.out.println(list1);

    }

}

0 0
原创粉丝点击