第一個demo





Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與數據庫表建立映射關係,是一個全自動的orm框架,hibernate可以自動生成SQL語句,自動執行,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。

一:去官網http://hibernate.org/orm/releases/下載一個Hibernate的包,選擇自己的需要的版本。

二:在myEclipse裏創建一個java工程。

三:將下載的hibernate的包required文件中的jar包都拷貝到項目工程的lib文件夾下

      選中項目右鍵–>Build Path–>Add External Jars–>選擇存放hibernate jar 包的路徑–>選擇jar包

package org.test.entity;


public class User {
private int id;
private String uname;
private int age;
private String sex;
private String city;
public int getId() {
return id; }
public void setId(int id) {
this.id = id;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;

}


//重寫Object類下的toString()方法
public String toString(){
return “User [id=”+id+”,uname=”+uname+”,age=”+age+”,sex=”+sex+”,city=”+city+”]”;
}
}

編寫映射文件User.hbm.xml

       實體類User目前還不具備持久化操作的能力,而Hibernate需要知道實體類User映射到數據庫 Hibernate中的哪個表,以及類中的哪個屬性對應數據庫表中的哪一個字段,這些都需要在映射文件中配置。

      在實體類User所在的包中,創建一個名稱爲User.hbm.xml的映射文件,在該文件中定義了實體類User的屬性是如何映射到user表的列上的。

我們可以下載好hibernate需要的映射文件導入到工程中去,除此之外,通常myEclipse會自己附帶hibernate,所以這裏記錄一下如何直接在myEclipse中創建hbm.xml映射文件。

1.右鍵點擊工程new彈出New框在框中選擇XML(Basic Templates)。下一步後在.xml前加上hbm,整個文件出來之後就是“.hbm.xml”爲後綴的文件,然後next


2.選擇第一個單選框,點擊next


3.選擇第二項,然後找到我們要用的dtd,點擊next,會出來一個界面,不用管它直接點擊finish


4.然後User.hbm.xml映射文件就建好了

<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd” >
<hibernate-mapping>
<!– name代表實體類名 ,table代表表名 –>
<class name=”org.test.entity.User” table=”user”>
<!– name=id代表user類中屬性   column=id代表的是table表中的字段–>
      <id name=”id” column=”id”>
      <generator class=”native”/><!– 主鍵生成策略 –>
      </id>
      <!– 其他屬性使用property標籤來映射 –>
<property name=”uname” column=”uname” type=”string”/>
<property name=”age” column=”age” type=”int”/>
<property name=”sex” column=”sex” type=”string”/>
<property name=”city” column=”city” type=”string”/>


</class>
</hibernate-mapping>

 第七步:編寫核心配置文件hibernate.cfg.xml

  Hibernate的映射文件反映了持久化類和數據庫表的映射信息,

  而Hibernate的配置文件則主要用來配置數據庫連接以及Hibernate運行時所需要的各個屬性的值.

從下載解壓的文件夾中選擇project文件夾下的etc文件夾,打開文件夾找到hibernate.cfg.xml拖拽到項目的src目錄下,根據需要修改相應配置信息

myEclipse連接數據庫,可以用jdbc接口,也有另一種不用jdbc的方法:

1.window–>Open Perspctive–>MyEclipse Database Explorer–>OK


2.左側空白處右鍵–>New–>輸入相關信息

 在Driver name填寫鏈接數據庫的名稱(這個可由自己喜好填寫,建議最好和所做項目名稱相關便於使用時查找)
Connection URL用於填寫連接要使用mysql數據庫的地址(jdbc:>[<:3306>]/<dbname>),其中localhost表示的是連接本地數據庫的意思,3306是表示連接mysql數據庫的端口號(不同的數據庫端口號也不相同),
User name 填寫數據庫用戶名mysql默認的是root
Password填寫訪問mysql數據庫時的你所設置的訪問密碼。
點擊Add JARs添加myeclipse連接mysql數據庫的驅動文件,在這裏添加的是mysql-connector-java-5.1.46-bin版本(可以在網上搜索下載)


3.點擊Test Driver測試是否配置成功,輸入訪問數據庫密碼。


注:

      但是在測試時,出現瞭如下的錯誤,使用驅動程序執行數據庫登陸時出現錯誤,經過檢查和上網查詢發現是導入自己下載的數據庫jar包時,驅動文件放在了中文目錄,更改了存放目錄後錯誤解決。


因此存放驅動的文件最好是英文目錄,在測試時確定mysql數據庫已經打開,服務已經打開,否則測試會報錯

測試成功後界面如下:


hibernate.cfg.xml

<!–
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html&gt;.
  –>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd“>
<hibernate-configuration>
<session-factory>
<property name=”show_sql”>true</property>
<property name=”hibernate.dialect”>org.hibernate.dialect.MySQL5Dialect</property>
<property name=”hibernate.connection.driver_class”>com.mysql.jdbc.Driver</property>
<property name=”hibernate.connection.url”>jdbc:mysql://localhost:3306/hibernate</property>
<property name=”hibernate.connection.username”>root</property>
<property name=”hibernate.connection.password”></property>
    <property name=”format_sql”>true</property>

<mapping resource=”org/test/entity/User.hbm.xml”/>
</session-factory>
</hibernate-configuration>


第八步:編寫測試類,進行測

  在項目中src下新建一個org.test.demo的包,然後再包內建立一個名爲UserTest.java的文件,該文件是用來測試的類文件。

package org.test.demo;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.test.entity.User;


public class UserTest {


  //定義變量


    Configuration config;


    SessionFactory sessionFactory;


    Session session;


    Transaction transaction;


    //before表示在方法執行前執行


    @Before


    public void SetUp()


    {


      //1.加載hibernate.cfg.xml配置


      config=new Configuration().configure();


      //2.獲取SessionFactory


      sessionFactory= config.buildSessionFactory();  


     //3.獲得一個session


      session=sessionFactory.openSession();


      //4.開始事務


      transaction=session.beginTransaction();


    }


    //添加操作


    @Test


    public void insert()


    {    


      //5.操作


      User user=new User();


     // user.setId(1);


      user.setUname(“zhangsan”);


      user.setAge(20);


      user.setSex(“m”);


      user.setCity(“guangzhou”);


      session.save(user);


    }


    //刪除操作


   
@Test
     public void delete()


     {


        //先查詢


        User user=(User)session.get(User.class,1);


        //再刪除
      if(user!=null)
      {
        session.delete(user);
      }
     }


    //查詢操作


   
@Test
    public void select()


    {


    User user=(User)session.get(User.class, 1);


        System.out.println(user);   


    }


    //更新操作
@Test
    public void update()


    {    


    User user=new User();


      //user.setId(1);


      user.setUname(“zhangsan”);


      user.setAge(20);


      user.setSex(“m”);


      //修改地址爲beijing


      user.setCity(“beijing”);


      //存在就更新,不存在就執行插入操作


      session.saveOrUpdate(user);


    }


    //After表示在方法執行結束後執行
@After
    public void closeTransaction()


    {


      //6.提交事務


      transaction.commit();


      //7.關閉資源


      session.close();


      sessionFactory.close();


    }


}




使用單元測試框架JUnit4進行單元測試,不需要main方法,就可以直接對類中的方法進行測試。@Test是用來測試的註解。


進度條 爲綠色表明運行結果正確,如果爲紅色則表示有錯誤。在數據庫中查詢表數據,結果如圖:


表明user表中數據添加成功。

測試運行select()方法後,控制檯信息如圖:


測試更新方法update()時,結果如圖:


數據庫中表數據爲:


測試刪除方法delete()刪除id爲2後,數據表爲:


測試成功!

當然,在測試過程中,遇到了一些問題,也折騰了很長時間:

1.在測試更新方法update()時:


錯誤信息:javax.persistence.OptimisticLockException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.internal.ExceptionConverterImpl.wrapStaleStateException(ExceptionConverterImpl.java:212)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:86)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1441)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:491)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3201)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2411)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)<br><spanstyle="whitespace:pre;"></span>atorg.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at org.test.demo.UserTest.closeTransaction(UserTest.java:143)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod1.runReflectiveCall(FrameworkMethod.java:47)<br><spanstyle="whitespace:pre;"></span>atorg.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)<br><spanstyle="whitespace:pre;"></span>atorg.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.ParentRunner 3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner1.schedule(ParentRunner.java:63)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.ParentRunner.access 000(ParentRunner.java:53)
at org.junit.runners.ParentRunner2.evaluate(ParentRunner.java:229)<br><span style="white-space:pre;"> </span>at org.junit.runners.ParentRunner.run(ParentRunner.java:309)<br><span style="white-space:pre;"> </span>at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)<br><span style="white-space:pre;"> </span>at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)<br><span style="white-space:pre;"> </span>at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)<br><span style="white-space:pre;"> </span>at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)<br><span style="white-space:pre;"> </span>at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)<br><span style="white-space:pre;"> </span>at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)<br>Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1<br><span style="white-space:pre;"> </span></span></p><p><span style="font-size:14px;">直觀翻譯過來是:批量更新從更新0返回意外的行數;實際的行數0;預期:1</span></p><p><span style="font-size:14px;">這樣的問題,不注意的話也挺無所適從:這個問題是主鍵一開始設置爲自增長,而在我插入數據時又設置了ID值導致的。</span></p><p><span style="font-size:14px;">我的解決方法是插入數據時,不重新設置Id值,數據庫會自動給出一個自增長的id值。</span></p><p><span style="font-size:14px;"><br></span></p><p><span style="font-size:14px;">2.測試刪除方法delete()時,</span></p><p><span style="font-size:14px;"><img src="https://img-blog.csdn.net/20180505233125831?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbmJpdWJpdWJpdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt=""><br></span></p><p><span style="font-size:14px;">錯誤信息:</span></p><p><span style="font-size:14px;">java.lang.IllegalArgumentException: attempt to create delete event with null entity<br><span style="white-space:pre;"> </span>at org.hibernate.event.spi.DeleteEvent.&lt;init&gt;(DeleteEvent.java:31)<br><span style="white-space:pre;"> </span>at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:927)<br><span style="white-space:pre;"> </span>at org.test.demo.UserTest.delete(UserTest.java:91)<br><span style="white-space:pre;"> </span>at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br><span style="white-space:pre;"> </span>at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)<br><span style="white-space:pre;"> </span>at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)<br><span style="white-space:pre;"> </span>at java.lang.reflect.Method.invoke(Method.java:498)<br><span style="white-space:pre;"> </span>at org.junit.runners.model.FrameworkMethod 1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner3.run(ParentRunner.java:238)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.ParentRunner 1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access000(ParentRunner.java:53)<br><spanstyle="whitespace:pre;"></span>atorg.junit.runners.ParentRunner 2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)


     








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章