收藏 分销(赏)

Hibernate入门重点笔记专业资料.doc

上传人:快乐****生活 文档编号:2954263 上传时间:2024-06-12 格式:DOC 页数:76 大小:345.54KB 下载积分:16 金币
下载 相关 举报
Hibernate入门重点笔记专业资料.doc_第1页
第1页 / 共76页
Hibernate入门重点笔记专业资料.doc_第2页
第2页 / 共76页


点击查看更多>>
资源描述
一 、第一种应用实例 1.搭建环境:新建一种名为HibernateDemojava工程,并导入Hibernatejar包,特别要注意除了导入lib下jar包还需导入hibernate3.jar核心jar包。 由于涉及数据库操作,还应导入mysql驱动包。 阐明,如果使用最新hibernate,hibernate开发基本jar包(7个) 来源:hibernate-distribution-3.3.2.GA.zip hibernate3.jar lib\required下所有jar包 2.简述Hibernate作用:ORM:Object Relational Mapping,对象关系映射。将java程序中对象自动持久化到关系数据库中。而Hibernate作用好比就是在java对象与关系数据库之间一座桥梁,它重要负责两者之间映射。在Hibernate内部封装了JDBC技术(但只是一种轻量级封装,因而可以让程序设计人员更以便以面向对象思想操纵数据库),并向外提供API接口。 3.建新一种名为User.java类,即是上面所说java对象。咱们后来称这种类为实体类(或是持久化类),它对象为实体对象(或是持久化对象)。User.java内容如下: package com.asm.hibernate.domain; import java.util.Date; public class User { private int id; private String name; private Date date; 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 Date getDate() { return date; } public void setDate(Date date) { this.date = date; } } 4.编写配备文献:User.hbm.xml。它和User.java放在同一种包下。内容如下: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ""> <hibernate-mapping package="com.asm.hibernate.domain"> <class name="User"> <id name="id"> <generator class="native"/> </id> <property name="name"></property> <property name="date"></property> </class> </hibernate-mapping> 此配备文献,是用来为User.java进行配备,咱们后来称这种文献为实体配备文献(或是持久化类映射文献) <class>用来关联一种java类,注旨在前面根元素下有一种package属性,这样结合这个package和class标签下所指定类名,就共同关联映射了一种java类。 其实可以这样理解,每一种包下均有实体配备文献,而这个配备文献开始根元素package指定了此文献所处位置(或是说它所关联包),根元素下可以有各种<class>标签(查阅dtd文献),它们可以分别来关联包下java类文献。 <class>标签,普通建议至少有两个属性:name属性用来关联一种java类,例如这里关联了User类;table属性用来指定这个类所相应表文献,如果不指定,系统会自动name指定类文献进行关联(例如上面实际是:<class name="User" table="user">) <class>标签下子标签: l <id>子标签实际就是用来映射主键,<id>下name就是用来指java类中id属性,而它可以有一种column属性用来指定表中主键。同步注旨在此标签下有一种<generator class="native"/>标签,它是用来指定主键生成方式。 l <property>子标签,就是用来指定java类属性映射到表中一种字段,默认下此标签没有指定column属性,即是说它会把name所关联属性名作为字段名。 如果不想java类中某些属性映射到表中,只要不用这个标签来关联这些属性即可。 l 总结:上面<class><id><property>name属性都分别指定了java类,java类属性。而table,column是用来指定表,字段名 配备文献:hibernate.cfg.xml。它放在当前项目根目录下。内容如下: <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" ""> <hibernate-configuration> <session-factory name="foo"> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">create</property> <mapping resource="com/asm/hibernate/domain/User.hbm.xml"/> </session-factory> </hibernate-configuration> 主配备文献,完毕了驱动注册,数据库连接,并关联了相应java对象配备文献。 阐明:<mapping>详细指定了关联所有实体配备文献,关于它作用可以注释掉此属性看效果。另通过<property name="hibernate.hbm2ddl.auto">create</property>指定了依照实体配备文献来自动生成表,其中涉及:create/create-drop/update/validate四种可选方式。 5.编写测试类:UserTest.java 内容如下: package com.asm.hibernate.test; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.asm.hibernate.domain.User; public class UserTest { public static void main(String []args){ Configuration cf=new Configuration(); cf.configure(); SessionFactory sf=cf.buildSessionFactory(); Session s=sf.openSession(); Transaction ts=s.beginTransaction();//事务 User user=new User(); user.setName("jack"); user.setDate(new Date()); s.save(user); mit();//提交事务 s.close(); System.out.println("done"); } } 6.分析流程:一方面抛开Transaction tx=s.beginTransaction()和mit(),由于它们是提交事务得。支持提交事务意味着支持数据回滚。阐明,普通状况下,诸多数据库都默认支持提交事务,因此加这两句代码非常必要。 下面详细谈流程: 第一步:获取SessionFactory对象,它会一方面构建一种Configuration对象,此对象调用可以调用configure()和configure(String resource)这两种办法:这两种办法在Configuration中源代码如下: public Configuration configure() throws HibernateException { configure( "/hibernate.cfg.xml" ); return this; } public Configuration configure(String resource) throws HibernateException { log.info( "configuring from resource:" + resource ); InputStream stream = getConfigurationInputStream( resource ); return doConfigure( stream,resource ); } 分析这两个源代码可以懂得:无参调用最后也是调用这个有参数办法,因此咱们也可以直接传参数调用。 当前重点是读配备文献,这个配备文献咱们普通放在eclipsescr根目录下,而当eclipse编译时会自动把这个目录下文献编译到bin目录下,而这个bin目录下是被配备成classpath环境变量,而configure办法就是在classpath环境变量下查找配备文献。 再来分析,无参调用configure办法时,默认是传递hibernate.cfg.xml配备文献,因此只有取名为这个配备文献,才可以调用无参configure办法,如果是其他名字配备文献,则调用含参配备文献,并且这个参数名应为这个配备文献名字。 当读取配备文献后Configuration对象,才是一种真正意义上可操控实例对象。 然后,再用这个对象来构建一种SessionFactory对象。 强调阐明,这一步整个操作最佳是放在类静态代码块中,由于它只在该类被加载时执行一次。 第二步:得到一种Session实例,以进行数据库CRUD操作 第三步:实例化一种java类 第四步:持久化操作 第五步:后续操作:重要是关闭连接 7.实体类定义规则: Domain object(java对象)必要要有构造办法,同步建议有一种id属性,为了赖加载,这个java类声明最佳不用final。 8.开发流程: 官方推荐:先Domain object 再mapping,最后是DB。 惯用开发方式:DB开始,由工具来生成mapping和Domain object。 9.总结基本环节: 环境搭建(导入有关包等) —>实体类及配备文献—>主配备文献(完毕了数据库配备及通过设立属性创立了相应表)—>得到Session测试应用。 二、优化代码 1.为会么要优化 在前面咱们已经懂得,获取SessionFactory对象是一种重复过程。因而咱们可以把这个操作写成一Util类。下面咱们把这一步写成工具类HibernateUtil,内容如下: package com.asm.hibernate.utils; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static SessionFactory sf; private HibernateUtil() { } static { Configuration cf = new Configuration(); cf.configure(); sf = cf.buildSessionFactory(); } public static SessionFactory getSessionFactory() { return sf; } public static Session getSession() { return sf.openSession(); } } 2.优化测试类 下面复制UserTest.java代码改为UserTest2.java并进行修改 修改后内容如下: package com.asm.hibernate.test; import java.util.Date; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import com.asm.hibernate.domain.User; import com.asm.hibernate.utils.HibernateUtil; public class UserTest2 { static void addUser(User user) { Session s = null; Transaction ts = null; try { s = HibernateUtil.getSession(); ts = s.beginTransaction(); s.save(user); mit(); } catch (HibernateException e) { if (ts != null) ts.rollback(); throw e; } finally { if (s != null) s.close(); } } public static void main(String[] args) { User user = new User(); user.setName("richie"); user.setDate(new Date()); addUser(user); } } 阐明,在addUser办法中其实也可以不用catch语句捕获。由于核心关闭连接已在finally实现。上面例子可以作为后来Hibenate操作一种典型模板,只需要修改主办法中内容即可。 3.get办法:可以在UserTest2.java中增长这个办法: static User getUser(int id) { Session s = null; try { s = HibernateUtil.getSession(); return (User) s.get(User.class,id); /* * User user=(User) s.load(User.class,id); * System.out.println("----load----"+user); * System.out.println(user.getName()); * //load只是准备连接到数据库,当增长上面一句操作时表达有真正数据库操作,这时它才会去连接数据库 return user; */ } finally { if (s != null) s.close(); } } 以上代码,实现了数据库查询操作,这里get()办法需要传递两个参数,理解传递参数:由于Session可以管理各种数据库所相应各种实体对象,如果只是传递id将不能正拟定位表,因而必要传递这个实体对象 ,get办法才干去查找这个实体对象所相应数据库中表。 用这个办法得到User对象后,便可以用此对象办法来得到有关属性(也就是数据库表中字段) 4.load()办法,懒加载。 它特点是:只有实际操作才会被加载,且它是生成这个User.java子类,可以从打印成果看出。也正因而,所此前面建议实例类不使用final。强调:如果是懒加载,虽然数据库中查不到数据,上面user对象永远不会为空,由于它内部实现事实上是new了一种User(子)类对象。 下面再在main办法中测试,增长语句如下: User u = getUser(1); System.out.println("id=" + u.getId() + "\t name=" + u.getName()); 5.控制台显示: <property name="show_sql">true</property> 在总配备文献中增长这个属性将会在控制台显示数据库操作“数据库语言”。称这个属性为数据库语言显示。 三 、Session中重要办法 1.保存数据:save,presist 阐明:这两种办法重要区别重要体当前未启动事务时。save办法如果是没启动事务,会执行有关sql语句,随后再回滚。而presist主线就不执行这些sql语句。 2.删除对象:delete 3.更新数据:update 阐明,如果数据库中没有记录将会浮现异常 4.查找数据:get,立即访问数据库 load,返回是代理,不会及时访问数据库。 5.选取操作:saveOrUpdate,merge,依照id和version值来拟定是save还是update。saveOrUpdate办法重要作用:可以把瞬时对象或脱管对象转成持久对象,而不需要详细判断对象是处在瞬时态或是脱管态来选取save或update来让对象变成持久态。只要调用此办法就能由id和version来灵活选取是保存或更新。而merge办法一种对象后,对象仍是脱管态。 5.持久对象:lock,把对象变成持久对象,但不会同步对象状态。 四 、对象三种状态 1.瞬时(transient):数据库中没有数据与之相应,超过作用域会被JVM垃圾回收器回收,普通是new出来且与Session无关系对象。 2.脱管-游离(detached):数据库中有数据与之相应,但当前没有Session与之关联:脱管对象状态发生变化,Hibernate不能检测到。 3.持久(persistent):数据库有数据与之相应,当前与Session关于联,并且有关联Session没关于闭,事务没有提交:持久对象状态发生变化时,在事务提交时会影响到数据库。 理解:与Session与否关联,数据库与否有数据与之相应是判断三种对象状态根据。例如,瞬时状态跟它们均无关;脱管,只是数据库有数据与之相应,失去了Session对它管理;而持久与两者者关于。 从过程中理解三种对象状态:结合前面实例,当咱们User user=new User()一种对象时,它表达创立一种瞬时对象,当调用save(user)办法时,这个对象成为持久对象,直到事务提交,数据库连接关闭。在这期间,如果咱们user.setXXX()时,会对这个持久对象产生影响,最后它也会被提交到数据库,它最后提交是在提交事务时。例如save(user)办法后,跟user.setName("new name");和user.setPassword("new password");这两句,这样它会在提交时务时,采用对数据库更新操作,也就是说数据库连接关闭后,数据库存是“new name”和“new password” 而如果启动了“数据库语言显示”可以发现执行两次操作:一次是save办法插入操作,一次是setXXX后提交事务时更新作(特别阐明,持久对象在发生变化时,例如setXXX办法变化对象内容时,会在最后,即提交事务时统一进行更新操作,而并非每一次变化就执行一次更新,这样可以保证与数据库交互更高效合理)。当执行完save办法后,咱们关闭数据库连接时,这时user对象就是脱管状态,由于它在数据库有数据与之相应 而脱管状态最佳例子是当咱们用get办法得到一种对象并关闭连接时 补充阐明:既然咱们已经懂得了持久对象可以被Hibernate检测到进行更新操作,那么update与否尚有用了?有,例如脱管对象就可以调用update来更新数据库中数据,而调用update()办法后脱管对象又变成了持久对象。 下面是三种对象状态互相转换图例 transient persistent detached sava() saveOrUpdate() new delete() get() load() find() iterate() evict() close() clear() update() saveOrUpdate() lock() garbge() 再谈saveOrUpdate办法:此办法兼具了save和update两种办法。它依照传递参数来选取执行其中一种办法。如果参数对象是瞬时态,则执行save办法,而如果参数对象是脱管态,则执行update办法。最后都是把传递参数对象转成持久态。 如何判断对象状态?重要根据是看:实体对象id(或者version)取值与实体配备文献中<id>元素unsaved-value属性值匹配状况。 只要满足下面任一状况则可以阐明对象处在瞬时态:状况一,实体对象(持久化对象)id取值为null形式(例如int型为0,字串为null)。 状况二,实体对象(持久化对象)id取值与预设unsaved-value属性值不同。 状况三,实体对象(持久化对象)具备versionn属性,并且为null。 状况四,实体对象(持久化对象)version取值与预设unsaved-value属性值不同。 五、完善工具类及HQL QBC初步有关 1.无聊讨论: 在前面咱们写了一种工具类:HibernateUtil。其实咱们还可以把CRUD操作封装到这个工具类中,并把它们都做成静态,这样这个工具类就可以直接调用了。但是这样操作对查询数据也许不是较好,由于它查询方式诸多,除非咱们一一考虑这些也许涉及到查询方式,并能以重载形式进行统一管理。 其实我也试想过把这此数据库操作办法进行二次封装,在工具类写成如下形式: public void operate(int i ){ if(i==1){ 调用更新办法,执行查询操作} if(i==2){ 调用删除办法,执行查询操作} if(i==3){ 调用插入办法,执行查询操作} if(i==4){查询?可指定一种惯用查询办法,但返回值如何解决,因此建议不在此处写查询,可再写一种查询统一操作办法来总括所有查询办法} } 2.HQL作用概述 数据库操作,难点重要集中在查询操作中,而HQL就是专门用来为查询服务。 3.HQL应用环节: 假定咱们已有一种Session对象s >>环节一,获得Query对象:Query query=s.createQuery(“HQL SELECT Sentence”); >>环节二,为参数赋值:query.setXXX(); >>环节三,获得List对象:LIST list=query.list();阐明,除了此办法外,Query接口尚有一种惯用办法uniqueResult,如果明确查询成果只有一种,便选取使用此办法。如果查询成果有各种使用此办法会报异常。 >>环节四,遍历查询成果:即遍历上面list对象。 关于环节二为参数赋值问题:例如环节一中“HQL Sentence”内容为:from User u where u.name=?and u.password=?and ...,如果这里?较少可以setXXX(0,”...”);setXXX(1,”...”);但是如果?较多,就容易把这些设立写错,因此可以采用命令参数方式来决定背面setXXX内容。 例如:from User u where u.name=:uname and u.password=:upass and ... ,这样背面就可以写setXXX(“uname”,”...”); 4.一种细节问题: 在前面咱们实体类为User类,而在实体配备文献中<class name="User">意为它所关联表为user表(没有指定名称table),但如果是oracle数据库,咱们懂得它自身就有一张user表,这样就产生了冲突,如何解决这种冲突?一种办法是设定table属性为新名字(首选办法),另一种办法是加`(数字1前那个符号),即这样<class name="User" table="`user`">写,这样咱们表还是user表。同样如果属性名与数据库中核心字产生这种冲突,也可以按此办法解决。 5.分页技术: query.setFirstResult(200);query.setMaxReslut(10);这两句意思是符合规定语句有诸多条,咱们从第200条取,取出10条。咱们懂得每种数据库分页语句是不同,而Hibernate底层判断使用哪种分页语句就是参照前面配备文献方言属性。 6.QBC条件查询: 与它有关是Criteria Interface,Criterion Interface,Expressson Class。其实它操作和HQL很相似。同样咱们假定已有一种Session对象s. >>环节一,获得Criteria对象:Criteria criteria = s.createCriteria(User.class); >>环节二,封装查询条件为一种Criterion对象:Criterion cr = Expression.eq("name","new name");(阐明Expression继续于org.hibernate.criterion.Restrictions类),因此也可以这样写:Criterion cr=Restrictions.eq("name","new name");Restrictions类中封装查询条件办法均有两个参数:前一种参数是指创立Criteria对象时所使用参数属性名,后一种是要与属性名比较值。例如这里是指User类name属性与否与“new name”相等 >>环节三,获得带查询条件Criteria对象:criteria.add(cr);执行此步才使这个对象具备一种条件限制查询操作。 >>环节四,获得List对象以遍历:List clist = criteria.list();补充阐明:也可以直接返回一种User对象:User user=(User) criteria.uniqueResult(); 特别阐明:Criteria对象也具备分页功能,方式是和上面Query同样 。 六 、基本应用实例:Dao设计 1.总体设计:设计User对象及有关实体配备文献,工具类(得到一种Session对象),UserDao接口(实现此接口即以操作数据库),编写主配备文献,编写测试类。 2.UserDao设计,最初我想打算设计成通用Object操作,日后发现它Session对象操作都要传递一种对象,就设计成如下形式。内容如下: package com.asm.dao; import com.asm.domain.User; public interface UserDao { public void saveUser(User user); public User queryById(int id); public User queryByName(String name); public void update(User user); public void delete(User user); } 按此设计,意思是此类专门针对User对象数据库操作,传递User对象,所后来面它实现类query有关办法可以直接user = (User) s.get(User.class,name);写name为传递参数,而咱们懂得操作是User对象,因此直接可以User.class。 值得一提是,在JDBC操作中,delete,传递id这种值就可以实现删除,而Hibernate删除操作,必要传递一种对象,操作过程就是咱们通过id查出这个对象,再把这个对象传递给删除办法以供删除。而实事上也可以new一种User对象,并设定id,然后再把这个对象传递给删除办法。 但需要特别注意new出对象必要完毕符合咱们通过id查出对象。 3.这个实例参照前面有关,基本可以写出。如下几点需要注意:导包:Hibernate包,数据库包;改写配备文献;查询办法设计;注意事务,特别是“增删改”要注意事务。 七 、关联关系讨论 1.多对一关系映射: 一种部门有可以有各种员工,而一种员工只属于一种部门。从员工角度看,诸多员工会从属一种部门。 现以实例阐明,实例概要:一种部门类,只有id和部门名称两个属性。有一种员工类,有id和员工名称及部门对象三个属性。操作环节如下: >>环节一,建立Depatment.java及实体配备文献: package com.asm.hibernate.domain; public class Department { private int id ; private String name; 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; } } ----同包下实体配备文献:Depart.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ""> <hibernate-mapping package="com.asm.hibernate.domain"> <class name="Department"> <id name="id"> <generator class="native" /> </id> <property name="name"></property> </class> </hibernate-mapping> 以上操作,没什么可多言,和前面配备是同样形式。 >>环节二,Employee.java内容如下及实体配备文献 package com.asm.hibernate.domain; public class Employee { private int id; private String name; private Department depart; 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 Department getDepart() { return depart; } public void setDepart(Department depart) { this.depart = depart; } } ----同包下实体配备文献:Employee.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ""> <hibernate-mapping package="com.asm.hibernate.domain"> <class name="Employee"> <id name="id"> <generator class="native" /> </id> <property name="name"></property> <many-to-one name="depart" column="depart_id" /> </class> </hibernate-mapping> 先来说这个类文献,它一种重要属性就是Department对象,这就是它所关联一种外键,这里咱们只必要记住一点,每个实体类相应于一张表,如果一张表想关联另一张表,则只需要在这张表所相应实体类中引入它想关联表实体类对象。再进行简朴配备即可。再来看配备文献,这里重要看这个<many-to-one name="depart" column="depart_id"></many-to-one>元素,它name属性依然是实体类中属性。column为相应表外键。可以留意下数据库表中有关表。 >>修改主配备文献,增长如下内容以便找到相应实体配备文献。 <mapping resource="com/dep/emp/Employee.hbm.xml"/> <mapping resource="com/dep/emp/Depart.hbm.xml"/> >>环节四,编写测试类。类中省略导入包内容。 package com.asm.hibernate.test; public class ManyToOneTest { public static void main(String[] args) { add(); } static
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服