- Hibernate用来干嘛的
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行;简化了dao层的编码工作。 - 开发步骤
- 创建持久化类(与数据库表对应)
- 创建对象-关系映射文件(*.hbm,xml)
- 创建Hibernate配置文件(hibernate.cfg.xml)
- 对数据库增删改查
- 入门例子
1)新建java项目,右击项目名称,新建一个lib包(与src同级目录)。 将\hibernate-tools\hibernate-release-4.3.2.Final\lib\required文件夹下的jar都拷过来,mysql-connector-java-5.1.22-bin.jar数据库连接驱动jar。
2)在src下新建package报名test.helloworld。 - 在这个包下创建Persion类:
package test.helloworld;public class Persion { private int id; private String name; private int age; private String job; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } @Override public String toString() { return "Persion [age=" + age + ", id=" + id + ", job=" + job + ", name=" + name + "]"; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 创建对象-关系映射对象: 实体类与表是一一对应关系,那么就需要在数据库中新增一个表;建表语句(采用数据库自增主键id)
create database hibernate_20171114 default character set utf8;use hibernate_20171114;create table persion( id int primary key auto_increment, name varchar(20), age VARCHAR(20), job VARCHAR(20) );
- 创建对象-关系映射文件,这个配置文件要和实体类在同一个包下,否则在hibernate加载映射文件的时候会找不到。刚开始我以为.hbm.xml文件的名字需要和实体类的名字完全一样,经过测试,发现并不然,只需要在.hbm.xml文件中把实体类与数据库表的关系配置正确,在hibernate.cfg.xml将该映射文件配置正确即可。
为了方便查看,我还是将名字和实体类名字一样,Persion.hbm.xml
- 创建Hibernate配置文件:hibernate.cfg.xml
对于初学可以在\hibernate-tools\hibernate-release-4.3.2.Final\project\etc文件夹下的hibernate.cfg.xml拷贝到项目里来。放置在src目录下,然后添加数据库连接信息,配置映射文件的路径。
注意:映射文件的路径一定要配置正确,我们可以验证一下,按住Ctrl键的同时,将鼠标放在路径字符串下,看看能不能跳转到Persion.hbm.xml文件去,可以的话,就配置没有问题。如下:
- 好了基础的配置工作完成,下面就是编写简单的访问数据库的代码了
在test.helloworld包下,创建一个测试类,用单元测试类或者main方法都可以,我这里分别写了增删改查的四个方法,我们一个一个执行测试,代码如下:
public class test { private static SessionFactory sessionFactory; static { Configuration cfg = new Configuration(); cfg.configure(); sessionFactory = cfg.buildSessionFactory(); } @Test public void testsave(){ Persion persion = new Persion(); persion.setAge(22); persion.setName("码代码滴小仙女"); persion.setJob("码农"); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.save(persion); tx.commit(); session.close(); } @Test public void testupdate(){ Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Persion persion = (Persion) session.get(Persion.class, 1); persion.setName("码代码滴小哥哥"); session.update(persion); tx.commit(); session.close(); } @Test public void testdelete(){ Persion persion = new Persion(); persion.setId(1); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.delete(persion); tx.commit(); session.close(); } @Test public void testget(){ Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Persion persion = (Persion) session.get(Persion.class, 1); System.out.println(persion); tx.commit(); session.close(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
执行第一个方法的时候报错了,错误如下:
WARN: HHH000277: Could not bind factory to JNDIorg.hibernate.engine.jndi.JndiException: Error parsing JNDI name [foo] at org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:141) at org.hibernate.engine.jndi.internal.JndiServiceImpl.bind(JndiServiceImpl.java:157) at org.hibernate.internal.SessionFactoryRegistry.addSessionFactory(SessionFactoryRegistry.java:103) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:497) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928) at test.helloworld.test.<clinit>(test.java:17) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.junit.internal.runners.JUnit4ClassRunner.createTest(JUnit4ClassRunner.java:72) at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:79) at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) 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) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662) at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313) at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350) at javax.naming.InitialContext.getNameParser(InitialContext.java:505) at org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:135) ... 23 more
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
原因是我们在复制过来的hibernate.cfg.xml文件中有一个name=”foo”属性,我们将这个属性去掉,然后再测试,完美通过。
测试第一个testsave方法:
数据库persion 表中新增一条数据:
测试testupdate 方法:
数据库的记录修改为:
测试testget方法,console控制台打印:
Persion [age=22, id=1, job=码农, name=码代码滴小哥哥]
测试testdelete方法:
查看数据库id为1的记录是否已被删,删除则测试成功。
到这里简单的数据库操作就完成。
如果在运行过程中报如下的错
java.lang.ExceptionInInitializerError at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.junit.internal.runners.JUnit4ClassRunner.createTest(JUnit4ClassRunner.java:72) at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:79) at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) 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) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)Caused by: org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xml at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2163) at org.hibernate.cfg.Configuration.configure(Configuration.java:2075) at org.hibernate.cfg.Configuration.configure(Configuration.java:2054) at cn.itcast.a_helloworld.App.<clinit>(App.java:15) ... 17 moreCaused by: org.dom4j.DocumentException: Error on line 1 of document : 前言中不允许有内容。 Nested exception: 前言中不允许有内容。 at org.dom4j.io.SAXReader.read(SAXReader.java:482) at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2155) ... 20 more
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28