Hibernate框架的入门级学习运用

Hibernate

简介

什么是框架

编程框架指的是实现了某应用领域通用完备功能的底层服务。使用这种框架的编程人员可以在一个通用功能已经实现的基础上开始具体的系统开发。框架提供了所有应用期望的默认行为的类集合。具体的应用通过重写子类(该子类属于框架的默认行为)或组装对象来支持应用专用的行为。

编程框架强调的是软件的设计重用性和系统的可扩充性,以缩短大型应用软件系统的开发周期,提高开发质量。

总之一句话,框架是帮我简化了很多基础代码,只需要程序员按照框架的规则写少量主要代码就可以实现相应功能的一个代码集合,简化开发。

什么是hibernate

Hibernate是一个开放源代码的轻量级的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JavaEE架构中取代CMP,完成数据持久化的重任。

轻量级的意思就是只需要导入支持该框架的少量架包就可以使用。

语言特点

  • 将对数据库的操作转换为对Java对象的操作,从而简化开发。通过修改一个“持久化”对象的属性从而修改数据库表中对应的记录数据。
  • 提供线程和进程两个级别的缓存提升应用程序性能。
  • 有丰富的映射方式将Java对象之间的关系转换为数据库表之间的关系。
  • 屏蔽不同数据库实现之间的差异。在Hibernate中只需要通过“方言”的形式指定当前使用的数据库,就可以根据底层数据库的实际情况生成适合的SQL语句。
  • 非侵入式:Hibernate不要求持久化类实现任何接口或继承任何类,POJO即可。

ORM思想

对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。

对象[Object] 编程语言实体类对象

关系[ Relational] 关系数据库表

映射[Mapping] 两者的一个对应关系

这是一种简化数据库操作的开发手段和思想,很多的框架中都采用了这种映射思想。

持久化思想

持久化是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存)。

持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。

持久化是将程序数据在持久状态和瞬时状态间转换的机制。

JDBC就是一种持久化机制。文件IO也是一种持久化机制。

hibernate入门

搭建环境

在使用hibernate开发的时候可以使用HibernateTools工具来帮助简化开放,可以自动生成配置文件等,相当方便,但是这个插件和编程工具的版本有着较大相关性,要求版本对应,主要是eclipse。

插件可以去官网下载后在编程软件内手动安装也可以直接在编程软件内通过链接安装,这里我们不采用插件,就不做过多赘述。

1.百度搜索hibetnate找到官网下载架包,下载的是ORM项目

官网链接:http://hibernate.org/

image-20210410110608948

点击红框位置就会弹出相应的版本号,选中其中一个点击

image-20210410123303331

进入页面以后往下滑就可以看到如图界面,点击红框位置就可以下载相应版本的orm

image-20210410123407844

要是想下载较老版本的就上滑点击如下图所示位置

image-20210410123802349

image-20210410123840985

下载之后就会得到一个压缩包,将压缩包解压以后得到如下目录文件。

image-20210410124112982

点击其中的lib包,然后点击required

image-20210410124241989

其中就是我们使用hibernate所需要的主要jar包

image-20210410124344545

但是不要忘记,在将所有jar复制到项目的lib文件夹的时候需要加一个数据库的驱动架包

接下来就是在你的编程软件中新建一个项目,把各种jar包往里面添加,建立路径。

这里我用的是2020.9的eclipse软件来演示。

但需要记住的是,当jdk到jdk9,和以上版本,其中的javax.xml.bind包没有了,需要自己往里面导入,

所以这里还需导入另外的四个包才能正确的运行起来。

如果你建的是Maven项目就直接去maven仓库中找到这四个架包链接放到pom.xml中下载

javax.xml.bind jaxb-api 2.3.0 com.sun.xml.bind jaxb-impl 2.3.0 com.sun.xml.bind jaxb-core 2.3.0 javax.activation activation 1.1.1

如果不是的话就需要手动下载导入这四个架包,同样也是在maven中来下。

具体如何下载,点击链接查看

https://editor.csdn.net/md/?articleId=115677042

第一个项目

新建一个普通java项目就可以,建立一个lib文件夹,将上面所述的jar包往里面导入并建立路径。

然后在src目录下新建一个hibernate的核心配置文件,hibernate.cfg.xml。

这个文件必须有,它是一个核心,并且名字必须叫做hibernate.cfg.xml,而且必须放置在src目录下。

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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>
    
    	<!-- Hibernate 连接数据库的基本信息 -->
    	<property name="connection.username">root</property>
    	<property name="connection.password">123456</property>
    	<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
    	<property name="connection.url">jdbc:mysql://localhost:3306/hibernate5?useSSL=false&amp;serverTimezone=UTC</property>

		<!-- Hibernate 的基本配置 -->
		<!-- Hibernate 使用的数据库方言 -->
		<!-- 数据方言的意思是,这个框架支持了多个数据库类型,不同数据库操作语言是有差异的,你必须指定你使用的数据库是哪一个
		框架才好匹配对应的数据库操作 -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
	
		<!-- 运行时是否打印 SQL语句-->
    	<property name="show_sql">true</property>
    
    	<!-- 运行时是否格式化 SQL 语句-->
    	<property name="format_sql">true</property>
    
    	<!-- 生成数据表的策略 -->
    	<!-- 没有表的话生成表,有表的话更新表 -->
    	<property name="hbm2ddl.auto">update</property>
    	
    	<!-- 将映射配置文件引入hibernate核心配置文件中,应为类加载的时候只会加载核心配置文件
    	想要映射配置文件起作用就要将其引入到核心配置文件中 -->
    	<mapping resource="com/yxs/helloword/Newshbm.xml"/>
    </session-factory>
</hibernate-configuration>

<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

这一部分数据是一个data约束,是必须要有的,那里找呢,

如下:

到我们上面所下的架包解压文件目录中,点击如同所示的project

image-20210410130212942

image-20210410130440904

image-20210410130508515

image-20210410130529495

image-20210410130556309

接着一直往下点直到如图

image-20210410130717020

打开该文件

image-20210410130756116

就是如图所示的信息,下面新建hbm.xml文件的时候,找数据也是同理。

接下来在src目录下建包,在包里新建一个实体类,这是一个标准的实体类,有私有属性,提供了set和get方法,提供有参无参构造

image-20210410131012517

News.java

public class News {
   
	
	private Integer id;
	private String title;
	private String author;
	public News() {
   
		super();
	}
	public News(String title, String author) {
   
		super();
		this.title = title;
		this.author = author;
		
	}
	public Integer getId() {
   
		return id;
	}
	public void setId(Integer id) {
   
		this.id = id;
	}
	public String getTitle() {
   
		return title;
	}
	public void setTitle(String title) {
   
		this.title = title;
	}
	public String getAuthor() {
   
		return author;
	}
	public void setAuthor(String author) {
   
		this.author = author;
	}
	
	@Override
	public String toString() {
   
		return "News [id=" + id + ", title=" + title + ", author=" + author + "]";
	}
	
	

}

接下来在实体类的同一包下面新建一个xml映射文件

名字习惯上用 实体类名+hbm.xml来命名

Newshbm.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 >

<!-- 建立实体类和数据库表的映射文件 -->
<!-- class标签 name属性要填的是全路径下的实体类名 table属性是这个实体类对应数据库中的表的名字
如果表已经创建好了,则需要和数据库中的表的名字一样,如果没有则任意取一个名字,待会数据库就会自动帮我们生成-->
	<class name="com.yxs.helloword.News" table="news">
	
		<!-- 这个id标签是对应着数据库中的主键的字段,也就是要唯一标识的属性 -->
	    <id name="id" column="n_id">
			<!-- generator标签是设置id在数据库中的策略
				native代表的是自动增长 -->
	      <generator class="native"></generator>
	
	    </id>
	     <!-- 实体类中其他对属性应着的数据库中的普通字段 -->
	    <property name="title" column="n_title"></property>
	    <property name="author" column="n_author"></property>
	
	        
	</class>

</hibernate-mapping>

接下来在建一个测试包,里面建立一个测试类用来测试第一个项目

这里我引入了单元测试

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import com.yxs.helloword.News;

public class SessionTset {
   
	@Test
	public void add() {
   
		//加载核心配置文件
		//默认到src目录下去找hibernate.cfg.xml文件
		Configuration cfg = new Configuration();
		cfg.configure();
		
		/*
		 * 创建SessionFactory对象
		 * 读取核心配置文件信息创建SessionFactory
		 * 根据映射文件信息,在数据库中将对应的表创建出来
		 */
		SessionFactory sFactory = cfg.buildSessionFactory();
		
		//根据SessionFactory创建Session
		//相当于创建了一个数据库连接
		Session seeSession = sFactory.openSession();
		
		//开启事务
		Transaction transaction =seeSession.beginTransaction();
		
		//创建操作逻辑
		//通过操作实体类来操作数据库
		News news = new News("java","狂神");
		
		//将实体类创建的对象添加到连接中,添加到数据库中
		seeSession.save(news);
		
		//提交事务
		transaction.commit();
		
		
		//关闭资源
		seeSession.close();
		sFactory.close();
		
	}

}

记得要在数据库中建立对应的数据库,表就不用建了。

接下来就可以运行测试类,去查看数据库中有没有建立表,表中有没有数据变化。

hbm.xml详解

  1. 他的位置和名字并没有实质的要求
  2. class标签 name属性要填的是全路径下的实体类名 table属性是这个实体类对应数据库中的表的名字,如果表已经创建好了,则需要和数据库中的表的名字一样,如果没有则任意取一个名字,待会数据库就会自动帮我们生成。
  3. 这个id标签是对应着数据库中的主键的字段,也就是要唯一标识的属性
  4. generator标签是设置id在数据库中的策略native代表的是自动增长
  5. property标签实体类中其他对属性应着的数据库中的普通字段,name属性是实体类中的属性名,colum是对应在数据库表中生成的字段名
  6. colum属性可以不写上,默认在数据的表中会生成和实体类名字一样的字段名
  7. id标签,property标签中还有一个type属性,它的作用是设置实体类属性对应在数据中生成字段的数据类型,比如int,varchar等

核心API

Hibernate的API一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。通过这些接口,可以对持久化对象进行存取、事务控制。

Session

Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session

它是一个单线程的对象,不能共性,自己用自己的,相当于connection中的连接

通过调用它的方法来对数据库进行操作

  • sava(添加)
  • update(修改)
  • delete(删除)
  • get(根据id查询)。
SessionFactory

SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。

在核心配置文件中使用update那么在创建该对象的时候被创建的时候就会根据配置文件在数据库中建立一个表。

SessionFactory创建是非常耗资源的,所以一个项目通常只用一个SessionFactory,那我们就可以写一个工具类创建SessionFactory,当我们需要时就可以调用工具类创建,但是工具类需要保证创建一次,需要的时候直接调用就好。

//创建SessionFactory的工厂,一次创建,多次调用

public class FactoryUtil {
   
	
	static Configuration configuration = null;
	static SessionFactory factory = null;
	
	//在静态代码块中创建SessionFactory,只执行一次
	static {
   
		
		configuration = new Configuration().configure();
		
		factory = configuration.buildSessionFactory();
		
	}
	
	public SessionFactory getFactory() {
   
		//调用该方法返回SessionFactory
		return factory;
	}

}
Transaction

Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate 的设计者自己写的底层事务处理代码。 Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction、甚至可以是CORBA 事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。

//开启事务
Transaction transaction =seeSession.beginTransaction();	
//提交事务
transaction.commit();
//回滚
transaction.rollback();

事务的四个特性

原子性:不可分割,一组操作,要成功都成功,要失败都失败

一致性:操作前后数据变化要一致,例如A给B转500,A的钱先减500 ,B的钱再加500,如果数据库中A的钱刚减了500就发生异常,B的500没加上,那总量就少了500.这就操作前后不一致。一致性就是要保证不出现这样的情况。

隔离性:多个事务同时操作同一条记录,它们之间不会产生影响。

持久性::对数据的操作要提交到数据库进行持久化操作。

Query

Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。

Criteria

Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。

Configuration

Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration 类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对象。

解决编写xml文件没有提示的问题

本身在我们编写hibernate.cfg.xml和hbm.xml文件的时候就导入了约束,约束是网络地址的,按道理能联网就可以有提示,如果没有,我们还可以使用本地导入提示,具体如下

image-20210410145354384

点击进入XML Catalog 对User Specified Entries 进行编辑,点击Add

image-20210410145555199

image-20210410145944358

这里填入的名字是什么,例如给hibernate.cfg.xml添加提示,这里就是该配置文件头部的

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

这行代码,如果是给hbm.xml添加提示这里就是hbm.xml文件头部的这行数据

http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd

之后点击File System…选择这两个文件

image-20210410150502908

是不是对这两个文件特别熟悉,没错就是上面我们将加入约束的时候找的那个文件,所以找这两个文件的路径就不多说了。

选中打开,接着点击应用就完工了。为了保险,重启eclipse。

如果还是不行,建议导入hibernatetool插件,导入该插件之后,即使你没有引入本地约束,同样有提示。

实体类编写规范

1. 要求实体类必须有自己的私有属性
2. 每个私有属性必须有自己的get和set方法
3. 私有属性中必须有一个属性是一个唯一表示的值,即这个属性的值必须唯一不能相同,一般用id,与数据库中的主    键字段相对应
4. 建议不使用基本数据类型,而使用基本类型的包装类

为什么使用包装类,因为包装类使用起来更规范,比如显示学生分数,使用int型,学生考0分和缺考都显示0,没有区分,如果使用Integer类型,缺考可以用null表示。

Hibernate主键生成策略

hibernate要求实体类中有属性是值唯一的,来与数据库中的主键字段相对应

主键可以有不同的生成策略

1、assigned
主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。与Hibernate和底层数据库都无关,可以跨数据库。在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免。

“ud”是自定义的策略名,人为起的名字,后面均用“ud”表示。

特点:可以跨数据库,人为控制主键生成,应尽量避免。

2、increment
由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。

Hibernate调用org.hibernate.id.IncrementGenerator类里面的generate()方法,使用select max(idColumnName) from tableName语句获取主键最大值。该方法被声明成了synchronized,所以在一个独立的Java虚拟机内部是没有问题的,然而,在多个JVM同时并发访问数据库select max时就可能取出相同的值,再insert就会发生Dumplicate entry的错误。所以只能有一个Hibernate应用进程访问数据库,否则就可能产生主键冲突,所以不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

官方文档:只有在没有其他进程往同一张表中插入数据时才能使用,在集群下不要使用。

特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

3、hilo
hilo(高低位方式high low)是hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。保存hi值的表至少有一条记录(只与第一条记录有关),否则会出现错误。可以跨数据库。

hilo生成器生成主键的过程(以hibernate_unique_key表,next_hi列为例):

  1. 获得hi值:读取并记录数据库的hibernate_unique_key表中next_hi字段的值,数据库中此字段值加1保存。

  2. 获得lo值:从0到max_lo循环取值,差值为1,当值为max_lo值时,重新获取hi值,然后lo值继续从0到max_lo循环。

  3. 根据公式 hi * (max_lo + 1) + lo计算生成主键值。

注意:当hi值是0的时候,那么第一个值不是0*(max_lo+1)+0=0,而是lo跳过0从1开始,直接是1、2、3……

那max_lo配置多大合适呢?

这要根据具体情况而定,如果系统一般不重启,而且需要用此表建立大量的主键,可以吧max_lo配置大一点,这样可以减少读取数据表的次数,提高效率;反之,如果服务器经常重启,可以吧max_lo配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。

特点:跨数据库,hilo算法生成的标志只能在一个数据库中保证唯一。

4、seqhilo
与hilo类似,通过hi/lo算法实现的主键生成机制,只是将hilo中的数据表换成了序列sequence,需要数据库中先创建sequence,适用于支持sequence的数据库,如Oracle。

特点:与hilo类似,只能在支持序列的数据库中使用。
5、sequence
采用数据库提供的sequence机制生成主键,需要数据库支持sequence。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence。MySQL这种不支持sequence的数据库则不行(可以使用identity)。

Hibernate生成主键时,查找sequence并赋给主键值,主键值由数据库生成,Hibernate不负责维护,使用时必须先创建一个sequence,如果不指定sequence名称,则使用Hibernate默认的sequence,名称为hibernate_sequence,前提要在数据库中创建该sequence。

特点:只能在支持序列的数据库中使用,如Oracle。

6、identity
identity由底层数据库生成标识符。identity是由数据库自己生成的,但这个主键必须设置为自增长,使用identity的前提条件是底层数据库支持自动增长字段类型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle这类没有自增字段的则不支持。

特点:只能用在支持自动增长的字段数据库中使用,如MySQL。

7、native
native由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强。如果能支持identity则使用identity,如果支持sequence则使用sequence。

注意:如果Hibernate自动选择sequence或者hilo,则所有的表的主键都会从Hibernate默认的sequence或hilo表中取。并且,有的数据库对于默认情况主键生成测试的支持,效率并不是很高。

特点:根据数据库自动选择,项目中如果用到多个数据库时,可以使用这种方式,使用时需要设置表的自增字段或建立序列,建立表等。

8、uuid
UUID:Universally Unique Identifier,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。

Hibernate在保存对象时,生成一个UUID字符串作为主键,保证了唯一性,但其并无任何业务逻辑意义,只能作为主键,唯一缺点长度较大,32位(Hibernate将UUID中间的“-”删除了)的字符串,占用存储空间大,但是有两个很重要的优点,Hibernate在维护主键时,不用去数据库查询,从而提高效率,而且它是跨数据库的,以后切换数据库极其方便。

使用时实体类中的对应主键的属性是字符串类型。

特点:uuid长度大,占用空间大,跨数据库,不用访问数据库就生成主键值,所以效率高且能保证唯一性,移植非常方便,推荐使用。

9、guid
GUID:Globally Unique Identifier全球唯一标识符,也称作 UUID,是一个128位长的数字,用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成GUID。从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义上)3240年不重复。

Hibernate在维护主键时,先查询数据库,获得一个uuid字符串,该字符串就是主键值,该值唯一,缺点长度较大,支持数据库有限,优点同uuid,跨数据库,但是仍然需要访问数据库。

注意:长度因数据库不同而不同

MySQL中使用select uuid()语句获得的为36位(包含标准格式的“-”)

Oracle中,使用select rawtohex(sys_guid()) from dual语句获得的为32位(不包含“-”)

特点:需要数据库支持查询uuid,生成时需要查询数据库,效率没有uuid高,推荐使用uuid。

10、foreign
使用另外一个相关联的对象的主键作为该对象主键。主要用于一对一关系中。

该例使用domain.User的主键作为本类映射的主键。

特点:很少使用,大多用在一对一关系中。

11、select
使用触发器生成主键,主要用于早期的数据库主键生成机制,能用到的地方非常少。

这里主要使用的native和uuid这两个生成策略,native可以跨平台,自动帮你匹配数据库类型的自增关键字。

实现crud操作

添加数据

添加数据,入门项目已经演示

根据id查询
public void get() {
   
		
		//调用工具类创建sessionFactory
		SessionFactory sessionFactory = FactoryUtil.getFactory();
		
		//创建Session
		Session session = sessionFactory.openSession();
		
		//开启事务
		
		Transaction transaction = session.beginTransaction();
		
		//操作查询
		//get()根据id进行查询,第一参数是实体类.class,第二个参数是id的值
		//返回值是一个实体类对象
		News news = session.get(News.class, 1);
		
		//输出实体类看看
		System.out.println(news.toString());
		
		//提交事务
		transaction.commit();
		
		//关闭session
		session.close();
		//这里使用工具类创建SessionFactory之后就不能关了,只创建一次,关了下一个没得用了
	}

修改操作
public void testUpdate() {
   
		//调用工具类创建sessionFactory
				SessionFactory sessionFactory = FactoryUtil.getFactory();
				
				//创建Session
				Session session = sessionFactory.openSession()<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值