关于java–Hibernate合并丢失数据和java合并方法的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于c#–EFvsNhibernate合并断开的对象图、HibernateHibe
关于java – Hibernate合并丢失数据和java合并方法的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于c# – EF vs Nhibernate合并断开的对象图、Hibernate HibernateSessionFactory.java、Hibernate 学习笔记(一)—— Hibernate 概述和使用 Hibernate 进行简单的增删改查操作、Hibernate 第一天(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)等相关知识的信息别忘了在本站进行查找喔。
本文目录一览:- java – Hibernate合并丢失数据(java合并方法)
- c# – EF vs Nhibernate合并断开的对象图
- Hibernate HibernateSessionFactory.java
- Hibernate 学习笔记(一)—— Hibernate 概述和使用 Hibernate 进行简单的增删改查操作
- Hibernate 第一天(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)
java – Hibernate合并丢失数据(java合并方法)
有问题的类的结构如下:
Project --> CaseWorkerA --|> CaseWorker --|> User
所以基本上我有一个Project类,它包含对CaseWorkerA的引用,CaseWorkerA是CaseWorker的子类,它也是User的子类.
在代码中:
public class Project { [...] private CaseWorkerA caseWorkerA; @ManyToOne(fetch = FetchType.EAGER) @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.PERSIST,org.hibernate.annotations.CascadeType.REFRESH,org.hibernate.annotations.CascadeType.MERGE }) @JoinColumn(name = "CaseWorker_A") public CaseWorkerA getCaseWorkerA() { return caseWorkerA; } }
然后我们有User-hierarchy:
public class User { [...] } public class CaseWorker extends User { private CaseWorkerStatus status; @Enumerated(EnumType.STRING) public CaseWorkerStatus getStatus() { return status; } [...] } public class CaseWorkerA extends CaseWorker { [...] }
然后,在Dao类中有一个方法用于存储项目:
public class ProjectDao { [...] public Project saveUpdateProject(final Project project) { if (project.getId() == null) { getSession(false).save(project); } else { project = (Project) getSession(false).merge(project); } getHibernateTemplate().flush(); return project; } }
现在,问题如下:
Dao方法接收数据库中存在的项目.此项目连接到CaseWorkerA,其状态为CaseWorkerStatus.ACTIVE(在数据库和incomming对象中).但在合并之后,案件工作者的状态变为空.
我真的不明白这是怎么可能的,因为数据库中的值是相同的,就像要存储的对象一样,我希望它在合并后保持不变.
(此字段的数据库中没有触发器..)
(我将尝试更改dao-method以使用saveOrUpdate,但即使这将解决问题,我仍然非常想知道是什么原因造成的).
更新:
所以我摆弄了调试器,发现了以下内容:当我查询有问题的CaseWorker的会话时,它出现了它的状态字段集(实际上,返回的对象正是连接到Project的对象).
执行saveOrUpdate,然后执行get,导致CaseWorker设置了status-field.所以它似乎是合并方法的一个问题..
解决方法
码:
public class Project { private User changedBy; @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.MERGE }) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "changed_by") public User getChangedBy() { return this.changedBy; } [...] }
设置为changedBy的用户从数据库中检索如下:
public class UserDao { public User getUser(final String userName) { return (User) getSession(false).createquery("from User u where u.loginName = :username").setParameter("username",userName).uniqueResult(); } }
显然,即使最终检索的用户是一个CaseWorker,也不会检索与CaseWorker相关的字段.
无论如何,删除了不成功的级联,这一切都很好:)
c# – EF vs Nhibernate合并断开的对象图
之前我使用过NHIbernate,我喜欢从MS中获得ORM的想法,到目前为止它一直很棒 – 直到我开始制作复杂的物体.
我的项目层次如下:
Azure WCF角色 – 使用EF Code First处理DAL.
带有Knockout的MVC 4的Azure WebSite角色 – 处理客户端.
(我为未来创建了WCFRole,我们需要从不同平台访问服务)
以下是我遇到的最基本的EF Code First设计:
– 我只在服务和网站之间传输DTO,并制作了一个通用的映射器来映射内部DTO(如果存在的话).
– 我有一个City表和一个带有City Property的地址对象(我们需要City作为特殊功能的属性,而不仅仅是名称)
客户端知道城市列表,并返回一个包含现有城市的新地址
当我尝试添加新地址时,使用旧现有数据创建一个新城市,我已经知道这是因为EF不知道如何合并断开连接的对象以及我读取的不支持任何合并abitiy,简单不太舒服的解决方案就是管理对象状态 – 将City对象状态更改为Unchanged.
但是使用大型复杂数据库设计来处理这个问题听起来很糟糕
我的问题 –
处理此问题的最佳做法/简便方法是什么?
我想过一些解决方案 – 覆盖SaveChanges方法遍历所有对象,如果ID不是null / 0 /其他一些约定将其从Added更改为Unchanged – 这个解决方案可以完成吗?
我的第二个问题 –
因为我对NHibernate(连接对象)有很多经验 – 我想知道NHibernate对此有何看法?我在某处读到NHibernate确实具有重新连接断开的复杂对象的AutoMagic Merge功能,这是真的吗?我的基本断开连接的地址 – >城市设计是否可以与AutoMagic Merge一起开箱即用?
使用它的后果是什么?
非常感谢 :)
更新:该问题的简化代码.
public class Address { public int ID { get; set; } public virtual City City { get; set; } } public class City { public int ID { get; set; } public string Name { get; set; } public virtual Zone Zone { get; set; } } public class MyContext : DbContext { public MyContext() : base("TransportService") { } public virtual DbSet<City> Cities { get; set; } public virtual DbSet<Address> Addresses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Address>() .Hasrequired(x => x.City) .WithMany().WillCascadeOnDelete(true); } }
添加新地址:
public void Add(AddressDto address) { using (var context = new MyContext()) { context.Addresses.Add(address.FromDto<Address>()); context.SaveChanges(); } }
“FromDto”是通用的Mapper扩展,它使用所有信息创建新地址,包括City(和City.ID属性)
这将导致创建一个新城市,而不是使用对旧城市的引用.
解决方法
处理多级断开连接的对象,并处理手动重新连接它们是很多工作,并且可能导致非常奇怪和难以处理错误(就像问题中所述的那样,因为它没有合并所以创建了新城市,所以它只是创建了一个新的,即使它有一个ID)
所以现在 – Nhibernate赢得这场战斗,Nhibernate具有自动合并功能,如果断开连接的对象有ID,它会尝试合并它,并且成功(根据我的经验)与EF相比,它可以更多地设置运行,但值得一试.
Hibernate HibernateSessionFactory.java
使用MyEclipse建立Hibernate时自动产生一个HibernateSessionFactory.java文件,这个文件有必要么
我的代码:
Configuration cfg = new Configuration(); cfg.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.getCurrentSession();
Hibernate 学习笔记(一)—— Hibernate 概述和使用 Hibernate 进行简单的增删改查操作
Hibernate是一个开放源代码的对象关系映射框架,它将 POJO与数据库表建立映射关系,Hibernate 可以自动生成SQL语句,自动执行,完成数据持久化的任务,使得我们方便的使用对象编程思维来操纵数据库。 [TOC]
一、Hibernate 概述
Hibernate 的API一共有6个接口,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。通过这些接口,可以对持久化对象进行存取、事务控制。
- **Session:**Session接口负责执行被持久化对象的CRUD操作。但需要注意的是Session对象是非线程安全的。
- **SessionFactory:**SessionFactory接口负责初始化Hibernate,并负责创建Session对象。这里用到了工厂模式。SessionFactory并不是轻量级的,所以在一般情况下,一个项目通常只需要一个SessionFactory对象。
- **Transaction:**Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction、甚至可以是CORBA 事务。
- **Query:**Query接口可以实现对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。
- **Criteria:**Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。
- **Configuration:**Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。
二、创建第一个 Hibernate 项目
2.1、导入 Jar 包
一个简单的 Hibernate 工程共需要两类 Jar 包,一种是 Hibernate 所必须使用的 Jar 包,另外一种是数据库驱动 Jar 包。所需的 Jar 包名称如下:
- Hibernate 必备的 Jar 包
antlr-2.7.7.jar
dom4j-1.6.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar
- 数据库驱动 Jar 包
mysql-connector-java-5.1.47.jar
c3p0-0.9.2.1.jar
hibernate-c3p0-5.0.7.Final.jar
mchange-commons-java-0.2.3.4.jar
2.2、编写实体类
创建用户(User) 实体类,其中包含用户名、密码、昵称、出生日期等基本信息。
package com.hibernate.domain;
import java.util.Date;
public class User {
private Integer uid;
private String username;
private String password;
private String nickname;
private Date birthday;
private String realname;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
@Override
public String toString() {
return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", nickname=" + nickname
+ ", birthday=" + birthday + ", realname=" + realname + "]";
}
}
2.3、编写Hibernate和实体类配置文件
2.3.1、编写 Hibernate 配置文件 —— hibernate.cfg.xml
Hibernate 的配置文件默认编写位置是在工程项目的 src
下,在配置文件中,主要配置 session-factory
,用于创建 Session
对象,以便对 POJO 进行增删改查的操作。
在 session-factory
中,主要配置数据库的配置信息、连接池供应商以及实体类映射文件的位置。
<?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>
<!-- 配置 SessionFactory 用于创建 Session 对象 -->
<session-factory>
<!-- 数据库的配置信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<property name="hibernate.show_sql">true</property>
<!-- <property name="hibernate.format_sql">true</property> -->
<!-- 配置 Hibernate 以何种方式生成DDL语句 update:表示检测实体类的映射配置和数据库表结构是否一致,不一致则自动更新
auto: -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置 Session 绑定本地线程 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 设置连接池供应商 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 配置实体类的映射文件位置 -->
<mapping resource="com/one_to_many/domain/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
2.3.2、编写实体类配置文件 —— User.hbm.xml
实体类映射文件则是编写在与实体类相同的包下面,命名通常以 实体类名称.hbm.xml
为命名规则。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package:配置实体类所在的包名称 -->
<hibernate-mapping package="com.hibernate.domain">
<!--
class标签,对应实体类
name:实体类的名称,如果配有配置package属性,需要写类的绝对路径
table:对应数据库中的表名称
-->
<class name="User" table="tb_user">
<!--
id:数据库表中的主键
id,property
name:实体类的属性名称
column:实体类属性对应数据库表中的列名称
-->
<id name="uid" column="user_id">
<!-- generator:表主键的生成策略 -->
<generator></generator>
</id>
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="nickname" column="nickname"></property>
<property name="birthday" column="birthday"></property>
<property name="realname" column="realname"></property>
</class>
</hibernate-mapping>
2.3.3、编写 Hibernate 工具类,获取 Session 对象
package com.hibernate.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
// 使用静态代码块来创建 SessionFactory 对象,保证单例
private static SessionFactory sessionFactory;
static {
// 创建 Configuration 对象
Configuration cfg = new Configuration();
// 加载 Hibernate 默认配置文件,如果配置文件不在 src 目录下,则需要填写配置文件地址
cfg.configure();
// 根据配置文件,创建 SessionFactory 对象
sessionFactory = cfg.buildSessionFactory();
}
public static Session openSession() {
// 获取 session 对象
return sessionFactory.openSession();
}
public static Session getCurrentSession() {
// 获取与当前线程绑定的 session 对象
return sessionFactory.getCurrentSession();
}
}
2.3.4、测试工具类
package com.hibernate.test;
import org.hibernate.Session;
import org.junit.Test;
import com.hibernate.utils.HibernateUtil;
public class TestHibernateUtil {
@Test
public void test() {
Session session = HibernateUtil.openSession();
}
}
如果测试类运行成功,则在 Hibernate 配置中所连接的数据库中就会出现 tb_user
表。
三、简单的增删改查操作
3.1、保存操作
使用 Hibernate 保存数据,只需要调用 session 的 save() 方法,即可将 POJO 保存到数据库中。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testSave() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
try {
User user = new User();
user.setUsername("martin_depp@126.com");
user.setPassword("martin0319");
user.setNickname("奔跑的小蚂蚁");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("1991-03-19 11:55:00"));
user.setRealname("孟祥杰");
// 调用 session 对象的 save() 实现数据的持久化操作
session.save(user);
} catch (ParseException e) {
e.printStackTrace();
} finally {
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
}
3.2、查找操作
使用 Hibernate 进行查找,只需要调用 session 的get(Class<T> arg0, Serializable arg1)
方法,其中 arg0 表示对应实体类名称,arg1表示主键值,如:查询主键为1的 User 实体对象。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testGet() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
// 此时需要注意所查询实体类主键的类型,如果是Long类型,最好为1L
User user = session.get(User.class, 1);
// 输出结果:
// User [uid=1, username=martin_depp@126.com, password=martin0319, nickname=奔跑的小蚂蚁, birthday=1991-03-19 11:55:00.0, realname=孟祥杰]
System.out.println(user);
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
3.3、更新操作
使用 Hibernate 更新数据,只需要调用 session 的 update() 方法,即可将 POJO 数据更新到数据库中。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testUpdate() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
User user = session.get(User.class, 1);
user.setUsername("mengxiangjie2005@126.com");
session.update(user);
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
3.4、删除操作
使用 Hibernate 保存数据,只需要调用 session 的 delete() 方法,即可将 POJO 从数据库中删除。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testDelete() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
User user = session.get(User.class, 1);
session.delete(user);
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
}
Hibernate 第一天(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)
Hibernate 的入门(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)
以前学习过 Hibernate, 不过学习的不太扎实,做的项目也不太多,好久时间没用,都快忘得差不多了,今天重新学习一下,一步一个脚印的敲每个代码,争取把 Hibernate 彻底学明白。
目录
Hibernate 的入门(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)
1.1 Hibernate 框架的学习路线
1.2 Hibernate 的框架的概述
1.2.1 什么是框架
1.2.2 EE 的经典三层结构
1.3 Hibernate 的概述
1.3.1 什么是 Hibernate
1.3.2 什么是 ORM
1.3.3 为什么要学习 Hibernate
1.4 Hibernate 的入门
1.4.1 Hibernate 的入门
1.5 Hibernate 的常见配置
1.5.1 XML 提示的配置
1.5.2 Hibernate 的映射的配置
1.5.3 Hibernate 的核心的配置
1.6 Hibernate 的核心 API
1.6.1 Hibernate 的 API
源码地址:
1.1 Hibernate 框架的学习路线
第一天:Hibernate 的入门(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)
第二天:Hibernate 的一级缓存、其他的 API
第三天:Hibernate 的一对多配置、Hibernate 的多对多的配置
第四天:Hibernate 的查询方式、抓取策略
1.2 Hibernate 的框架的概述
1.2.1 什么是框架
框架:指的是软件的半成品,已经完成了部分功能。
1.2.2 EE 的经典三层结构
1.3 Hibernate 的概述
1.3.1 什么是 Hibernate
Hibernate:Hibernate 是一个持久层的 ORM 框架。
1.3.2 什么是 ORM
ORM:Object Relational Mapping(对象关系映射)。指的是将一个 Java 中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表。
1.3.3 为什么要学习 Hibernate
1.4 Hibernate 的入门
1.4.1 Hibernate 的入门
1.4.1.1 下载 Hibernate 的开发环境
Hibernate3.x Hibernate4.x Hibernate5.x(我这里使用 5.0.7)
下载地址:https://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/
1.4.1.2 解压 Hibernate
1.documentation :Hibernate 开发的文档
2.lib :Hibernate 开发包
2.1required :Hibernate 开发的必须的依赖包
2.2optional :Hibernate 开发的可选的 jar 包
3.project :Hibernate 提供的项目
1.4.1.3 创建一个项目,引入 jar 包
1. 数据库驱动包,2.Hibernate 开发的必须的 jar 包,3.Hibernate 引入日志记录包 ,4.C3p0 连接池
1.4.1.4 创建表
CREATE TABLE `cst_customer` (
`cust_id` bigint (32) NOT NULL AUTO_INCREMENT COMMENT '' 客户编号 (主键)'',
`cust_name` varchar (32) NOT NULL COMMENT '' 客户名称 (公司名称)'',
`cust_source` varchar (32) DEFAULT NULL COMMENT '' 客户信息来源 '',
`cust_industry` varchar (32) DEFAULT NULL COMMENT '' 客户所属行业 '',
`cust_level` varchar (32) DEFAULT NULL COMMENT '' 客户级别 '',
`cust_phone` varchar (64) DEFAULT NULL COMMENT '' 固定电话 '',
`cust_mobile` varchar (16) DEFAULT NULL COMMENT '' 移动电话 '',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
1.4.1.5 创建实体类
1.4.1.6 创建映射(*****)
映射需要通过 XML 的配置文件来完成,这个配置文件可以任意命名。尽量统一命名规范(类名.hbm.xml)
Customer 映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 建立类与表的映射 -->
<!--
class标签:用来建立类和表的映射
*name属性:类的全路径
*table属性:表名(如果表名和类名一致可忽略)
*catalog属性:数据库名称,可忽略
-->
<class name="top.yangxianyang.demo1.Customer" table="cst_customer">
<!-- 建立类中的属性与表中的主键对应 -->
<!--
id标签:建立类中的属性与表中的主键对应
*name属性:类中的属性名
*column属性:表中字段名(如果类中属性名和表中字段名一致,可省略)
*catalog属性:数据库名称,可忽略
*length属性:字段长度
*type属性:类型。写Java数据类型,Hibernate数据类型(默认),SQL类型
-->
<id name="cust_id" column="cust_id" >
<!-- 主键生成策略 -->
<generator class="native"/>
</id>
<!-- 建立类中的普通的属性和表的字段的对应 -->
<!--
property标签:建立类中的普通的属性和表的字段的对应
*name属性:类中的属性名
*column属性:表中字段名(如果类中属性名和表中字段名一致,可省略)
*length属性:字段长度
*type属性:类型。写Java数据类型,Hibernate数据类型(默认),SQL类型
-->
<property name="cust_name" column="cust_name" length="32" />
<property name="cust_source" column="cust_source" length="32"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
</class>
</hibernate-mapping>
1.4.1.7 创建一个 Hibernate 的核心配置文件(*****)
Hibernate 的核心配置文件的名称: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>
<!-- 连接数据库的基本参数 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///sshstudy</property>
<property name="hibernate.connection.username">yxy</property>
<property name="hibernate.connection.password">123456</property>
<!-- 配置Hibernate的方言:作用,根据配置的方言生成相应的SQL语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置================ -->
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表
none:不使用hibernate的自动建表
create:如果数据库中已经有表,删除原有表,重新创建,如果没有表,新建表。(测试)
create-drop :如果数据库中已经有表,删除原有表,执行操作,删除这个表。如果没有表,新建一个,使用完了删除该表。(测试)
update:如果数据库中有表,使用原有表,如果没有表,创建新表(更新表结构)
validate:如果没有表,不会创建表。只会使用数据库中原有的表。(校验映射和表结构)。
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置C3P0连接池 -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
<!-- 加载映射 -->
<mapping resource="top/yangxianyang/demo1/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
1.4.1.8 编写测试代码(*****)
package top.yangxianyang.demo1;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* Hibernate的入门案例
* @author yxy
*
*/
public class Test1 {
public static void main(String[] args) {
demo1();
}
// 保存客户
public static void demo1() {
// 1.加载Hibernate的核心配置文件
Configuration configuration = new Configuration().configure();
// 2.创建一个SessionFactory对象:类似于JDBC中连接池
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.通过SessionFactory获取到Session对象:类似于JDBC中Connection
Session session = sessionFactory.openSession();
// 4.手动开启事务:
Transaction transaction = session.beginTransaction();
// 5.编写代码
Customer customer = new Customer();
customer.setCust_name("王小红");
session.save(customer);
// 6.事务提交
transaction.commit();
// 7.资源释放
session.close();
sessionFactory.close();
}
}
1.5 Hibernate 的常见配置
1.5.1 XML 提示的配置
1.5.1.1 配置 XML 提示问题
1.5.2 Hibernate 的映射的配置
1.5.2.1 映射的配置
- 【class 标签的配置】
- 标签用来建立类与表的映射关系
- 属性:
- name :类的全路径
- table :表名(类名与表名一致,table 可以省略)
- catalog :数据库名
- 【id 标签的配置】
- 标签用来建立类中的属性与表中的主键的对应关系
- 属性:
- name :类中的属性名
- column :表中的字段名(类中的属性名和表中的字段名如果一致,column 可以省略)
- length :长度
- type :类型
- 【property 标签的配置】
- 标签用来建立类中的普通属性与表的字段的对应关系
- 属性:
- name :类中的属性名
- column :表中的字段名
- length :长度
- type :类型
- not-null :设置非空
- unique :设置唯一
1.5.3 Hibernate 的核心的配置
1.5.3.1 Hibernate 的核心配置方式(了解)
第一种方式: 属性文件的方式
hibernate.properties
hibernate.connection.driver_class=com.mysql.jdbc.Driver
…
hibernate.show_sql=true
属性文件的方式不能引入映射文件(手动编写代码加载映射文件)
第二种方式:XML 文件的方式
hibernate.cfg.xml(推荐)
1.5.3.2 核心的配置
- 必须的配置
- 连接数据库的基本的参数
- 驱动类
- url 路径
- 用户名
- 密码
- 方言
- 连接数据库的基本的参数
- 可选的配置
- 显示 SQL :hibernate.show_sql
- 格式化 SQL :hibernate.format_sql
- 自动建表 :hibernate.hbm2ddl.auto
- none :不使用 hibernate 的自动建表
- create :如果数据库中已经有表,删除原有表,重新创建,如果没有表,新建表。(测试)
- create-drop :如果数据库中已经有表,删除原有表,执行操作,删除这个表。如果没有表,新建一个,使用完了删除该表。(测试)
- update :如果数据库中有表,使用原有表,如果没有表,创建新表(更新表结构)
- validate :如果没有表,不会创建表。只会使用数据库中原有的表。(校验映射和表结构)。
- 映射文件的引入
- 引入映射文件的位置
1.6 Hibernate 的核心 API
1.6.1 Hibernate 的 API
1.6.1.1 Configuration:Hibernate 的配置对象
作用:
加载核心配置文件
1.hibernate.properties
Configuration cfg = new Configuration();
2.hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
1.6.1.2 SessionFactory:Session 工厂
SessionFactory 内部维护了 Hibernate 的连接池和 Hibernate 的二级缓存。是线程安全的对象。一个项目创建一个对象即可。
- 封装工具类
package com.itheima.hibernate.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* Hibernate的工具类
* @author yxy
*
*/
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static{
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
/*
* 提供获得session的方法
*/
public static Session openSession(){
return sf.openSession();
}
}
1.6.1.3 Session:类似 Connection 对象是连接对象
Session 代表的是 Hibernate 与数据库的链接对象。不是线程安全的。与数据库交互桥梁。
- Session 中的 API
- 保存方法:
- Serializable save(Object obj);
- 查询方法:
- T get(Class c,Serializable id);
- T load(Class c,Serializable id);
- get 方法和 load 方法的区别?
- 保存方法:
get 方法
* * 采用的是立即加载,执行到这行代码的时候,就会马上发送 SQL 语句去查询。
* * 查询后返回是真实对象本身。
* * 查询一个找不到的对象的时候,返回 null
load 方法
* * 采用的是延迟加载(lazy 懒加载),执行到这行代码的时候,不会发送 SQL 语句,当真正使用这个对象的时候才会发送 SQL 语句。
* * 查询后返回的是代理对象。javassist-3.18.1-GA.jar 利用 javassist 技术产生的代理。
* * 查询一个找不到的对象的时候,返回 ObjectNotFoundException
- 修改方法
- void update(Object obj);
-
- 删除方法
- void delete(Object obj);
- 删除方法
-
- 保存或更新
- void saveOrUpdate(Object obj)
- 保存或更新
-
- 查询所有
- List createSQLQuery(String sql)
- 查询所有
测试代码:
package top.yangxianyang.demo1;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.hibernate.utils.HibernateUtils;
/**
* Hibernate的工具类的测试
* @author yxy
*
*/
public class TestUtils {
@Test
// 保存客户
public void demo1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_name("王小西");
Serializable id = session.save(customer);
System.out.println(id);
tx.commit();
session.close();
}
@Test
// 查询:
// ***** get方法和load方法的区别
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
/**
* get方法
* * 采用的是立即加载,执行到这行代码的时候,就会马上发送SQL语句去查询。
* * 查询后返回是真实对象本身。
* * 查询一个找不到的对象的时候,返回null
*
* load方法
* * 采用的是延迟加载(lazy懒加载),执行到这行代码的时候,不会发送SQL语句,当真正使用这个对象的时候才会发送SQL语句。
* * 查询后返回的是代理对象。javassist-3.18.1-GA.jar 利用javassist技术产生的代理。
* * 查询一个找不到的对象的时候,返回ObjectNotFoundException
*/
// 使用get方法查询
/*Customer customer = session.get(Customer.class, 1l); // 发送SQL语句
System.out.println(customer);*/
// 使用load方法查询
Customer customer = session.load(Customer.class, 1l);
System.out.println(customer);
tx.commit();
session.close();
}
@Test
// 修改操作
public void demo3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 直接创建对象,进行修改
/*Customer customer = new Customer();
customer.setCust_id(1l);
customer.setCust_name("王聪");
session.update(customer);*/
// 先查询,再修改(推荐)
Customer customer = session.get(Customer.class, 1l);
customer.setCust_name("王小贱");
session.update(customer);
tx.commit();
session.close();
}
@Test
// 删除操作
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 直接创建对象,删除
/* Customer customer = new Customer();
customer.setCust_id(1l);
session.delete(customer);*/
// 先查询再删除(推荐)--级联删除
Customer customer = session.get(Customer.class, 2l);
session.delete(customer);
tx.commit();
session.close();
}
@Test
// 保存或更新
public void demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
/*Customer customer = new Customer();
customer.setCust_name("王凤");
session.saveOrUpdate(customer);*/
Customer customer = new Customer();
customer.setCust_id(3l);
customer.setCust_name("李如花");
session.saveOrUpdate(customer);
tx.commit();
session.close();
}
@Test
// 查询所有
public void demo6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 接收HQL:Hibernate Query Language 面向对象的查询语言
/*Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}*/
// 接收SQL:
SQLQuery query = session.createSQLQuery("select * from cst_customer");
List<Object[]> list = query.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
tx.commit();
session.close();
}
}
1.6.1.4 Transaction:事务对象
Hibernate 中管理事务的对象。
commit();
rollback();
源码地址:
链接:https://pan.baidu.com/s/1cYbNGrbGu3NPOiIPTpzqOw 密码:y8kj
在图书馆看了几个小时终于整完了,基本框架搭建,环境配置成功,配置了 C3P0 连接池,封装了工具类,明天继续。
本文同步分享在 博客 “Albert Yang”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
我们今天的关于java – Hibernate合并丢失数据和java合并方法的分享已经告一段落,感谢您的关注,如果您想了解更多关于c# – EF vs Nhibernate合并断开的对象图、Hibernate HibernateSessionFactory.java、Hibernate 学习笔记(一)—— Hibernate 概述和使用 Hibernate 进行简单的增删改查操作、Hibernate 第一天(Hibernate 的环境搭建、Hibernate 的 API、Hibernate 的 CRUD)的相关信息,请在本站查询。
本文标签: