温馨提示
如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。
这篇文章是整合之前所写的六篇文章,即“javaweb学习笔记之Hibernate ”一系列的文章( 一,二,三,四,五)为一篇,同时加入了jdbc的使用介绍,很适合做为入门学习资料。
目录:
Hibernate概述及ORM
先了解JDBC的使用
下载Hibernate
eclipse安装Hibernate tool插件
添加junit4单元测试
一个简单的Hibernate应用实例
Session详解
Session核心方法的使用注意事项
单向多对一及双向一对多
Hibernate概述及ORM
1
概述
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用
2
ORM
orm即object/Relational Minping,对象关系映射。简单的说就是将数据库表与java类映射,数据库表中的列及类型对应java类中的属性及类型的映射。
先了解JDBC的使用
JDBC是Java平台规范的一部分,提供了一套标准的Java API,供Java程序访问不同的数据源。具体的实现交给各个厂商完成,所以使用jdbc操作mysql数据库,我们要先下载mysql的jdbc驱动。
mysql的jdbc下载
选zip的下载,点击右侧download按钮进入下载页面。
点击"no thanks,just start my download."开始下载。
下载完成后解压缩,获取到jar包。
项目中配置jdbc
将下载解压缩后获取到的jdbc驱动程序jar包拷贝到项目的webcontent/web-inf/lib目录下。
右键项目,选中properties,在弹出的窗口中选中java build path,然后点击右侧add jars按钮,找到刚拷贝到项目中的jar包。
添加完成后点击窗口右下角的apply and colse(应用和关闭)。这样就可以在项目中加载mysql的jdbc驱动了。
jdbc的使用
推荐JDBC快速入门教程:http://www.yiibai.com/jdbc/jdbc_quick_guide.html
总结JDBC使用步骤:
加载JDBC驱动程序,使用Class.forName("com.mysql.jdbc.Driver") 加载mysql的jdbc驱动程序,成功加载后,会将Driver类的实例注册到DriverManager类中。
提供JDBC连接的URL,MySql的连接URL: jdbc:mysql: //localhost:3306/databasename。
创建数据库的连接,使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。
创建一个Statement。执行静态SQL语句,通常通过Statement实例实现; 执行动态SQL语句,通常通过PreparedStatement实例实现; 执行数据库存储过程,通常通过CallableStatement实例实现。
执行sql语句。Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate 和execute。
处理结果。执行更新返回的是本次操作影响到的记录数,执行查询返回的结果是一个ResultSet对象。
释放资源。
一个简单的实例之数据准备
数据准备,使用mysqlworkbench创建一个名为jsp_db的数据库,并创建一个用户表(tab_user)和一个用户地址表(tab_address)。
用户表包含字段:
id,类型为无符号整型,不能为空,自增长。
name,类型为可变长度字符串,用户名,不能为空,默认为''。
password,类型为可变长度字符串,密码,不能为空,默认''。
email,类型为可变长度字符串,邮箱,不能为空,默认''。
使用InnoDB,默认字符编码为utf8。
用户地址表:
id,类型为无符号整型,不能为空,自增长。
city,类型为可变长度字符串,城市,不能为空,默认为''。
countries,类型为可变长度字符串,国家,不能为空,默认''。
user_id,类型为无符号整型,用户的id,不能为空。
使用InnoDB,默认字符编码为utf8。
分别向两个表中插入两条数据
一个简单的实例之mvc框架实现
数据库链接配置文件:dbconfig.properties
数据库链接工厂类:ConnectFactory
模型层:
1.创建一个抽象类,抽取出公共属性,id和数据库中的表名称。
2.UserBean模型,对应数据库中的tab_user表
3.AddressBean模型,对应数据库中的tab_address表
dao(业务)层
1.定义接口
2.接口的实现
视图层:
运行结果:
下载hibernate
官网url:http://hibernate.org/orm/downloads/
点击downloads,再点击中间的绿色按钮,ok,就可以下载了,没有比这更简单的了。下载完成后解压得到以下目录:
Eclipse安装Hibernate tool插件
安装Hibernate tool插件可以方便书写Hibernate配置文件和*.hbm.xml关系映射文件,在新建xml文件时会生成一些默认代码,不用每次都打一大串,同时还有代码提示功能,提高工作效率。
在eclipse中安装Hibernate tool步骤:
在eclipse菜单中选择Help->Install New Software,弹出安装插件的窗口:
在Work with:后面输入http://download.jboss.org/jbosstools/updates/stable/kepler/,然后敲击回车键,这时下面的框框内就会搜索出很多这个地址下面可以加载的插件,然后我们只要选中Hibernate Tools就行。选Jboos Web and Java EE Development下面的Hibernate Tools,然后点击Next按钮。
安装完成后重启eclipse生效。这时右键工程项目new->other如果出现Hibernate则安装成功。
设置代码提示。一般来说安装完Hibernate插件,使用new->other->Hibernate->cfg.xml|hbm.xml创建文件就可以正常使用Hibernate的代码提示了。
如果看不到代码提示,那就手动配置一下。 依次选中window->Preferences->xml->xml catalog:
如果看不到图中标蓝色的两项(hc是hibernate配置文件代码提示的插件,hm是hbm.xml关系映射文件的代码提示插件。)那么就需要点击右侧的add按钮手动添加了。
只说cfg.xml代码提示的配置,关系映射文件配置步骤相同。(这里需要用到hibernate-release-5.2.11.Final中的文件,前面已经说怎么下载了,没下载的到官网下载即可,下载完成后解压。)
首先打开新建的cfg.xml文件,复制dtd的url,图中的是:http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd
依次选中window->Preferences->xml->xml catalog->add。
在file system选中hibernate-configuration-3.0.dtd文件的路径(/hibernate-release-5.2.11.Final/project/hibernate-core/src/main/resources/org/hibernate/);
key type选择uri,key中输入之前复制的url(
补充
Hibernate tool插件的安装
补充一下Hibernate tool插件的安装方法,前面说的方法可能会出现一些问题。这是官网推荐的下载方法。打开hibrenate官网。
点击导航栏的tools,再点击downloads,进入到如下界面。
点击右下方的download按钮,进入到如下界面。
底下提示有:在eclipse中点击help->Eclipse Marketplace...
You can also view the installation page on the Eclipse Marketplace.你能在Eclipse Marketplace上查看安装页面。
说话说重点,好吧下面就是介绍使用Eclipse Marketplace下载安装hibernate tool。
打开eclipse,点击help->Eclipse Marketplace:
进入到如下页面:
在find中输入jboss tool回车,搜索到的是jboss tool最新版本4.5.0,然后点击jboss tool项的右下角的 installed按钮进入到安装页面。
因为我们只需要hibernate tool,所以去掉所有的勾,再选择hibernate tool项,点击finish就可以了。等待安装完成后会提示要重启,点击重启后生效。
添加junit4单元测试
右键项目名称->选择Preferences->java build path->add library
在add library窗口中选择junit,点击next。
选择junit4,点击finish。
此时项目的目录中会多出一个junit4的lib.
新建一个测试类测试junit4是能正常使用。
查看运行状态:
*还有一种方法就是直接下载junit4的jar,在项目的根目录下新建一个libs目录,将junit4.jar包扔进libs目录下,选中该jar包再右键build path->add build path就ok了。
一个简单的Hibernate应用实例
1
导入工程所需Hibernate的jar包
Hibernate5.x一共提供了10个jar包,简单介绍一下这十个jar包:
hibernate-core-5.2.11.Final.jar#Hibernate核心包
hibernate-commons-annotations-5.0.1.Final.jar#注解包,r如果项目中使用注解代替关系映射文件,那么必须要导入该jar包。
hibernate-jpa-2.1-api-1.0.0.Final.jar#jpa2.1接口库
antlr-2.7.7.jar#Hibernate利用它将hql转换为sql
classmate-1.3.0.jar#这个我就不知道了
dom4j-1.6.1.jar#解析xml配置文件和xml配置文件
jandex-2.0.3.Final.jar#用来索引annotations的
javassist-3.20.0-GA.jar#实现po字节码的动态生成
jboss-logging-3.3.0.Final.jar#日记服务通用库
jboss-transaction-api_1.2_spec-1.0.1.Final.jar#JTA规范包
这十个jar包所在的路径是:
/hibernate-release-5.2.11.Final/lib/required/
在工程根目录下新建一个libs目录,将这十个jar包全部拷贝到该目录下,然后全选中这些jar包,右键->Build Path->add to build path。
现在还缺少一个jar包,那就是jdbc的jar包,我使用的是mysql数据库,mysql提供的jdbc最新版本是5.1。
将mysql-connector-java-5.1.43-bin.jar包拷贝到工程的libs目录下,同样的,选中mysql-connector-java-5.1.43-bin.jar右键->Build Path->add to build path。
这样就把工程所需的jar包都导入到项目中了。
hibernate从其配置文件中读取和数据库连接的有关信息,这个文件应该位于应用的classpath下。
右键项目下的src目录,new->other:
基本配置信息如下:
1. 配置链接数据库的基本信息:
2.配置hibrenate的基本信息:
hibrenate所使用的数据库方言, InnoDB支持事务,当需要使用支持事务的数据库方言,并且使用了mysql5.5及以上版本时,需要将数据库方言配置为MySQL5InnoDBDialect:dialect
执行数据库操作时是否在控制台显示sql语句:show_sql
是否格式化sql语句显示,默认false时,控制台输出的sql语句是一行,不便于阅读,所以如果设置show_sql为true,最好设置一下format_sql为true
指定自动生成数据表的策略: update: 如果数据库中没有对应的数据表,hibernate会为我们在数据库自动生成数据表的策略 如果数据库中存在对应的数据表,但是hbm.xml文件的属性改变,hibernate会自动在数据表中插入一个列,但不影响已有的列:hbm2ddl.auto
拓展:
hbm2ddl.auto,该属性可取值有4个:
create,会根据.hbm.xml关系映射文件来生产数据库表,但是每次运行都会删除上一次应用运行时创建的表,重新生成表。就算表结构没有变化也会重新生成表。
create-drop,会根据.hbm.xml关系映射文件来生产数据库表,但是SessionFactory一关闭,表就会自动删除。
update,会根据.hbm.xml关系映射文件来生产数据库表,如果.hbm.xml文件和数据库中对应的数据表的表结构不同,hibernate将更新数据表结构,但不会删除已有的行和列,如果数据库中未存在该表,则会创建表。
validate,会和数据库中的表进行比较,若.hbm.xml文件中的列在数据表中不存在,则抛出异常。
3
创建数据库表对应的java类(model)
必须提供一个无参数的构造函数
如果要序列化保存就需要实现Serializable接口
以一个用户表为例,用户表结构如下:
对应的java类(由于所有的数据表都有着同一类型的列id,为了方便不用每个java类都写一次id属性和id的get,set方法,将抽象出一个共同的类IdBean):
IdBean.java
UserBean.java:
4
编写model的映射文件
以UserBean为例:
class配置java类与哪个数据表进行映射,name属性知道java类类名(包含包名),table属性指定数据表的表名。
id配置表的主键信息,name属性配置java类中的主键名(OID),column配置对应的数据库的列名,type配置java类中该属性的类型。
:指定主键的生成方式为native,即使用数据库底层的生成方式,比如mysql默认使用自增长方法。
property配置java类属性与数据库表列的映射。
最后还需要在hibernate.cfg.xml文件中指定该文件的路径,使用mapping标签,resource指定hbm.xml文件的路径:
5
hibernate操作数据库的基本步骤
获取SessionFactory实例
获取一个Session
执行操作,比如执行一个保存操作
1).开启事务
2).执行保存操作,此时未提交到数据库
3).提交事务,将更改提交至数据库
4).如果出错则回滚事务
关闭Session
关闭SessionFactory
新建一个HibernateManager类,封装步骤1,2,4,5:
编写一个测试类,UserBeanTest:
执行保存一个用户信息的操作:
右键选中该方法,run->junit run,查看控制台输出的sql语句:
最后查看数据库表中是否成功插入了该条记录:
到此,一个简单的应用实例就介绍完了。
Session详解
Session接口是hibernate向应用程序提供的操纵数据库的最主要的接口,是应用程序与数据库之间交互操作的一个单线程对象,是bibernate运作的中心,所有持久化对象必须在session的管理下才可以进行持久化操作,它提供了基本的操作方法:
保存(sava()):把对象永久保存到数据库中;
更新(update()):更新数据库中记录(对象)的信息;
删除(delete()):从数据库中删除一条记录(对象);
查询:根据特定的条件,把符合条件的一个货多个记录加载到内存中;
加载java对象(load()):根据特定的oid(表的主键),把一个对象从数据库加载到内存中。
笔记
NO.1
为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号,在关系数据库中称之为主键,而在对象术语中,则称之为对象标识object idebtifier-OID.)
Session具有一个缓存,属于一级缓存,位于缓存中的对象称为持久化对象。它和数据库中的相关纪录对应,Session能够在某个时间点,按照缓存中对象的变化来执行相关的sql语句,来同步更新
数据库,这一过程被称为刷新缓存(flush)。
1
对象的四种状态
站在持久化的角度,Hibernate把对象分为四种状态:
持久化状态:oid不为null,位于session缓存中,若在数据库中已经有和其对应的记录,持久化对象和数据库中相关记录对应。sesseion在flush缓存时,会根据持久化对象的属性变化,来同步跟新数据库。
临时状态:(在使用代理主键的情况下)oid通常为null,不处于session的缓存中,且在据库中没有对应的记录。
游离状态:oid不为null,不再处于session缓存中。一般情况下,游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与之对应的记录。
删除状态:在数据库中没有和其oid对应的记录,不在处于session缓存中。一般情况下,应用程序不该再使用被删除的对象。
Session的特定方法能使对象从一个状态转换到另一个状态:
使用get(),load(),Query.list()等方法时,查询出来或加载的所有对象都处于持久化状态.使用 new语句创建出来的对象处理临时状态,例如Student st = new Student();
处于临时状态的对象,调用sava(),savaOrUpdate(),persist()等方法之后将转变为持久化状态;
处于持久化状态的对象,调用session.close(),clear()方法后对象将转变为游离状态;
处于游离状态的对象,调用update(),savaOrUpdate()方法后对象将转变为持久化状态;
处于临时状态,持久化状态,游离状态的对象,调用delete()之后对象都转变为删除状态。
2
Session的缓存
Session缓存的优点:减少hibernate应用程序访问数据库的频率。
Session在以下时间点会刷新缓存(提交更改带数据库):
显示调用Session的flush()方法;
当应用程序调用transaction的commit()方法的时候,该方法先flush,然后再向数据库提交事务;
当应用程序执行一些查询操作时,如果session缓存中持久化对象的属性已经发生了变化,会先flush()缓存,以保证查询结果能够反映持久化对象的最新状态。
笔记
NO.2
transavtion的commit()方法和session的flush方法的区别:flush执行一系列sql语句,但不提交事务;commit方法先调用flush()方法,然后提交事务。
Session没有结束生命周期或没有清理缓存则存放在它的缓存中的对象也不会结束生命周期,即使没有引用也不会被java的垃圾回收机制回收。
session缓存-调用get方法获取到的对象会缓存在内存中
来看一段程序:
这段程序中获取了同一条数据库记录的UserBean对象,查看控制台输出:
可见,程序中调用了两次session的get方法,但是由于要获取的记录的OID相同,hibernate并没有执行两次数据库操作。第一次执行数据库查询操作后,将记录保存在了session的缓存中,第二次执行会先从缓存中查找,如果找不到才到数据库中查找。此时该对象(记录)处于持久化状态。
session缓存-修改持久化对象的属性会同步都数据库中
下面的列子是没有开启事务的:
在测试之前查看数据库中当前记录的对应要操作的列的值:
执行完成后,此时控制台只输出了一个查询语句,再看数据库中相应记录的列的值也并没有改变。
然后我们再加上获取session绑定的事务代码看看:
运行结果还是跟上门一样,说明在session关闭时并不会主动提交事务,需要我们手动提交。
再看:
ok,这时候再运行单元测试实例测试该方法:
控制台输出了一条update的sql语句,再看数据库中相应记录列的值也更改了,说明更改持久化对象的属性在提交事务时,会将更改更新到数据库中。
session缓存-使用flush可能执行sql语句并自动提交事务
获取session绑定的事务,但是不调用commit()方法,改成调用session的flush方法。(Hibernate版本5.2.11)
运行程序并查看控制台输出与数据库表相应记录的列的变化:
控制台输出了一条更新语句,并且数据库中相应记录的列的值也改变了。说明,使用flush可能执行sql语句并自动提交事务,为什么说是可能,因为如果属性值与持久化对象中属性值比较没有变化时,并不会执行数据库更新操作。
不改变上面的代码,再运行一次,查看控制台输出:
可见,并没有输出更新的sql语句,且数据库中记录的值也并没有改变。
session缓存-执行sql操作会先进行flush操作
执行sql操作会先进行flush操作,以保证得到的记录数据是最新的。按照上面的例子,稍微改一下,在修改属性值之后不调用flush方法也不调用commit方法,而是执行一条查询语句,看看在查询语句之前输出什么:
我在最后一行打了个断点调试,看执行到断点时控制台都输出了什么:
可以看到,再执行查询语句之前执行了一条更新语句,再看数据库中相应记录是否已经更改:
session缓存-sava操作会立即执行一条insert语句
若记录的id是由底层数据库使用自增方式生成的(即hbm.xml文件的id的generator属性设置为native),则在调用sava方法时,就会立即发送insert语句,因为sava方法后,必须保证对象的id是存在的。
代码验证:
完全不写事务的提交代码,只调用了sava方法,看控制台输出:
控制台输出了一条inset语句,再看数据库是否已经保存到记录:
果然,数据库中新增了一条记录。
session缓存-refresh方法会强制发送select语句
refresh()方法会强制发送select语句,以使session缓存中对象的状态和数据表中对应记录保持一致。
上面代码中我在refresh这一行下了断点,然后调试运行,当运行到断点处时,我到数据库中更新了一下对应 记录的nickname列的值。
然后继续断点处运行,最终控制台输出:
可见,控制台一共输出了两条查询语句和user状态的两次打印,并且发现了user对象的nickname属性的值已经改变。【关于设置hibernate数据库的隔离级别,发现并没起作用(hibernate5.2.11版本)。】
扩展知识
数据库的隔离级别
可以查看百度文档,将的很详细,这里就截几张图,就不打字了:https://wenku.baidu.com/view/d85da90e91c69ec3d5bbfd0a79563c1ec5dad7ba.html
session缓存-clear清理缓存
调用session的clear方法会情况当前session的所有缓存,前面说过get方法当session缓存中没有相应对象时会执行一条数据库查询语句,那么就把前面测试get方法的代码该一下,再get之后调用clear方法清空缓存,在调用一次get方法获取相同记录,验证是否执行了两次数据库查询操作。
控制台的确输出了两条查询语句。
Session核心方法的使用注意事项
1
persist方法和sava方法的区别
在调用persist方法之前,若对象已经有oid了,则persist方法不会执行inset语句,而是抛出一个异常,而sava方法会判断oid对应数据表中是否相应的记录,如果没有则会执行insert语句,并且oid也会重新分配,根据配置文件中id的生成规则,比如自增。
2
load方法与get方法的区别
get是立即检索,load是延迟检索,执行get方法会立即加载对象,执行load方法若不使用该对象,则不会执行查询操作只返回一个代理对象;若数据表中没有对应的记录,get返回null,而load抛出异常。
在初始化代理对象之前关闭session,在使用代理对象时,load方法懒加载就会抛出异常,
如:User user = session.load(User.class,1);
session.close();
使用load懒加载对象时,若数据表中没有对应数据,session也没有被关闭,在用到对象的时,load会抛出异常。
3
savaOrUpdate方法
savaOrUpdate方法,同时包含了sava方法update方法。
若对象处于游离状态,则调用savaOrUpdate方法时只执行update()方法;
若对象处于临时状态,则调用savaOrUpdate方法时只执行sava()方法;
若oid不为null且数据库表中也没有和其对应的记录时,则会抛出一个异常。
4
work接口
使用session.doWork方法可以直接通过jdbc来访问数据库。hibrenate提供了一个Work接口,通过实现该接口,实现execute方法获取jdbc的Connection对象来执行对数据库的访问操作。
例:
Work work = new Work(){
@Override
public void execute(Connect connection) throws SQLException{
//通过jdbc 执行数据库操作
}
}
session.doWork(work);
5
hibernate与触发器协同工作
问题1:
Session的update()会执行数据库语句,当执行session.update时会激发触发的
执行,无论游离对象属性是否发生改变都会执行update语句,而update语句会激发数据库中相应的触发器。
解决办法:
在映射文件的class元素中设置select-before-update属性,当session的update或savaOrUpdate方法更新一个游离对象时,会先执行 select语句,获取当前游离对象在数据库中的最新数据,只有在不一致的情况下才会执行update语句,这样就不会盲目的执行update方法而盲目的激发触发器了。
问题2:
触发器时session的缓存中的持久化对象与数据中对应的数据不一致,因为触发器运行在数据库中,它执行的操作session并不知道,也就无法保持与数据库中记录一致性。
解决办法:
在执行session的相关操作之后,可能激发了触发器,也就是session更新数据库对应的记录之后可能数据库又更新了该记录或某些表的记录,这时就需要刷新session的缓存,调用session的reflush方法即可,强制使session缓存中的对象刷新。(flush方法是将session缓存中的对象更新到数据库,reflesh方法是强制session从新从数据库中加载持久化对象)
单向多对一及双向一对多
1
单向多对一
在hibernate映射文件中使用many-to-one属性配置多对一的关联关系,其中many-to-one又包含几个常用的属性:
name,指定多(many)对一(one)中一(one)的一端的java类的属性名;
class,指定多(many)对一(one)中一(one)的一端的java类的类名;
column,指定多(many)对一(one)中一(one)的一端对应数据表中的列名。
举个常见的例子:淘宝买过东西都应该知道,用户购买一件商品首先是用户挑选想买的商品,然后下单,下单完成后才到支付环节。这里的用户下单应对应两个数据表,一个是用户表(user),另一个则是订单表(orders),那么用户与订单之间的关联关系就是一对多的关系,反过来订单与用户的关系就是多对一。
定义一个UserBean类和一个Orders类,都继承至IdBean类。IdBean是为简化数据表中共同列而抽象出来的类,因为每个表都有一个id主键,这样的好处是不用重复为每个java bean类都写一次id。
IdBean类:
UserBean类:
Orders类:
UserBean对应的hibernate关系映射文件:
Orders对应的hibernate关系映射文件:
编写一个测试类,测试单向多对一关联关系的保存和查询:
创建两个订单和一个用户,将订单关联给用户,然后保存到数据库中,查看数据库表中数据是否保存成功,观察控制台中输出的sql语句。
注意,需要手动提交事务hibernate才会维护数据表的关联关系。
先保存用户对象再保存订单对象:hibernate只执行3条insert语句。
先保存订单对象再保存用户对象:hibernate先执行3条insert语句再执行2条update语句,因为先保存订单的时候,关联的user对象还没有保存,处于临时状态的user并没有oid,此时订单的insert语句插入的订单的user_id为null值。orders要维护关联关系就必须要在user转变为持久化状态时更新自身的user_id列的值。
2
双向一对多
将上面的例子中的UserBean修改成User类并添加Set属性,并在User的关系映射文件中添加set属性。
set的常用属性:
name,映射 一(one)对多(many)的那个set类型的集合属性;
table,set中的元素对应的记录放在哪一个数据表中,该值需要和多对一的多的一方的那个表的表名一致;
inverse,指定由哪一方来维护关联关系,设置为true表示该表放弃维护关联关系。通常在一的一方的关系映射文件中设置set的inverse属性为true,以指定由多的一方来维护关联关系。
在一对多中,如果要一(one)的一方去维护关联关系,就会使在插入或是删除一(one)的一方时去update多(many)的一方的每一个与这个一(one)的对象有关系的对象。 而如果让多(many)的一方去维护关系时就不会有update操作,因为关系就是在多(many)的一方的对象中的,直接插入或是删除多(many)的一方的对象就行了。
User类:
User类对应的hibernate关系映射文件:
测试双向一对多关联关系的查询,更新和删除:
注意:对于指定双向一对多关联关系的数据表且指定一的一方放弃维护关联关系,如果对一(one)的一方执行删除操作会抛出异常,只能对多(many)的一方执行删除操作。
领取专属 10元无门槛券
私享最新 技术干货