上一篇
Hibernate初体验及简单错误排除
- 行业动态
- 2025-05-10
- 9
Hibernate初体验需配置环境、映射实体、执行CRUD操作,常见错误如配置、映射、Session问题,可通过查日志、
Hibernate初体验及简单错误排除
Hibernate简介与核心概念
Hibernate是一个基于Java的对象关系映射(ORM)框架,它通过将Java对象与数据库表建立映射关系,简化了数据库操作,开发者无需直接编写SQL语句,而是通过操作对象实现数据的增删改查,其核心概念包括:
概念 | 说明 |
---|---|
Session | 类似于JDBC的Connection,用于管理一次数据库对话,支持事务操作。 |
SessionFactory | 线程安全的工厂类,用于创建Session实例,通常应用中只需创建一个。 |
Entity | 标注为@Entity 的Java类,与数据库表一一对应。 |
Mapping | 通过XML或注解定义对象与表的映射关系(如字段与列的对应)。 |
HQL(Hibernate Query Language) | 面向对象的查询语言,语法类似SQL,但操作对象而非表。 |
环境搭建与基础配置
添加依赖
以Maven项目为例,需在pom.xml
中引入Hibernate核心依赖:<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.15.Final</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency>
配置
hibernate.cfg.xml
在src/main/resources
目录下创建配置文件:<hibernate-configuration> <session-factory> <!-数据库连接 --> <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <!-方言与自动建表 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-显示SQL日志 --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <!-映射实体类 --> <mapping class="com.example.entity.User"/> </session-factory> </hibernate-configuration>
创建实体类与映射
定义一个User
实体:@Entity @Table(name = "t_user") // 指定表名(可选) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键 private Long id; @Column(name = "username", length = 50) // 指定列名与长度 private String username; @Column(name = "age") private Integer age; // Getter/Setter省略 }
基础CRUD操作
初始化SessionFactory
private static SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
保存数据(Insert)
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); User user = new User(); user.setUsername("John"); user.setAge(25); session.save(user); // 生成INSERT语句 tx.commit(); session.close();
查询数据(Select)
- HQL查询
String hql = "FROM User WHERE age > :age"; Query<User> query = session.createQuery(hql, User.class); query.setParameter("age", 20); List<User> users = query.list();
- Criteria查询
CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaQuery<User> cq = cb.createQuery(User.class); Root<User> root = cq.from(User.class); cq.select(root).where(cb.greaterThan(root.get("age"), 20)); List<User> users = session.createQuery(cq).getResultList();
- HQL查询
更新与删除(Update/Delete)
User user = session.get(User.class, 1L); // 查询主键为1的记录 user.setAge(30); session.update(user); // 生成UPDATE语句 session.delete(user); // 生成DELETE语句
常见错误与解决方案
错误现象 | 可能原因 | 解决方案 |
---|---|---|
Could not find a specification for + entityClass.getName() | 未在配置文件中声明实体类映射 | 在hibernate.cfg.xml 中添加<mapping class="com.example.entity.User"/> |
No CurrentSessionContext available! | Session未绑定到线程或事务范围 | 启用current_session_context_class 配置:<property name="hibernate.current_session_context_class">thread</property> |
Identifier of an instance of ... was altered from ... to ... | 主键字段被修改 | 确保实体类的@Id 字段不会被业务逻辑修改,或手动维护主键一致性 |
NonUniqueObjectException | 重复插入相同主键的实体 | 检查@GeneratedValue 策略或手动设置唯一主键 |
LazyInitializationException | Session关闭后访问懒加载属性 | 在事务范围内操作,或启用hibernate.enable_lazy_load_no_trans=true (慎用) |
实战案例:整合Spring(可选)
若结合Spring框架,可通过LocalSessionFactoryBean
管理SessionFactory,并通过@Transactional
注解简化事务控制。
@Service public class UserService { @Autowired private SessionFactory sessionFactory; public void saveUser(User user) { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.save(user); tx.commit(); session.close(); } }
相关问答FAQs
Q1:为什么执行session.save(user)
后,数据库未插入数据?
A1:可能原因包括:
- 事务未提交(需调用
tx.commit()
); hibernate.hbm2ddl.auto
配置为validate
或none
,且表不存在;- 实体类未正确映射(如缺少
@Entity
注解或主键未定义)。
Q2:如何避免NonUniqueObjectException
?
A2:常见场景是多次合并同一持久化对象,解决方案:
- 确保每个实体有唯一主键;
- 避免重复调用
session.save(user)
或session.merge(user)
; - 使用
session.saveOrUpdate(user)
统一处理新增