注意:在从SessionFactory获取Session时,有两种方式,
第一种是:sessionFactory.openSession(),获取一个新的session,这是没有与本地进行绑定的session
第二种是:sessionFactory.getCurrentSession(),获取一个当前线程并与本地进行绑定,类似于银行系统中的转账业务建议使用此方式。但注意这个方法须要在配置文件中进行配置,并且手动启动事务并进行提交,否则会报错。
1、创建一个JAVA项目
2、导入Hibernate的相关JAR包
3、创建数据库:hibernate_test
4、在数据库创建user表
USE `hibernate_test`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(20) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
5、创建User.class实体类
package com.ckinghan.bean;
public class User {
private int id;
private String userName;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", password="
+ password + "]";
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
6、在User.class目录下创建User.hbm.xml的Hibernate的映射文件
<?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="com.ckinghan.bean.User" table="user">
<!-- ID映射的字段 -->
<id name="id" column="id">
<!-- hibernate根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式 -->
<generator class="native"></generator>
</id>
<!-- 实体类中的userName与表中的userName对应 -->
<property name="userName" column="userName"/>
<!-- 实体类中的password与表中的password字段对应 -->
<property name="password" column="password"/>
</class>
</hibernate-mapping>
7、在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 name="foo">
<!-- 配置数据库连接 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_test</property>
<!-- 在控制台显示SQL语句 -->
<property name="show_sql">true</property>
<!-- 格式化SQL语句 -->
<property name="format_sql">true</property>
<!-- 自动创建|更新|验证数据库表结构 -->
<property name="hbm2ddl.auto">update</property>
<!-- 事务自动提交 -->
<property name="hibernate.connection.autocommit">true</property>
<!-- 将获取的当前线程与本地进行绑定,以确认所操作的session是同一个 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 映射文件的地址 -->
<mapping resource="com/ckinghan/bean/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
8、创建测试类
package com.ckinghan.test;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
import com.ckinghan.bean.User;
/**
* hibernate测试类
* @author ckinghan
*/
public class HibernateTest {
/**
* 测试Hibernate的数据存储
* session通过openSession()方法获取,此方法不能保证当前connection唯一
* 在类似于转账之类的业务中,无法使用。
*/
@Test
public void testHibernateSave(){
//1、加载配置文件,如果hibernate的配置文件名是hibernate.cfg.xml,并且放置在src目录下,可以自动加载
Configuration configuration = new Configuration().configure();
//2、通过configuration创建sessionFactory
SessionFactory buildSessionFactory = configuration.buildSessionFactory();
//3、通过sessionFactory创建Session,注意:这里的Session是hibernate下的session
Session openSession = buildSessionFactory.openSession();
//4、使用save保存数据
User user = new User();
user.setPassword("password123");
user.setUserName("userName");
openSession.save(user);
//5、关闭连接
openSession.close();
buildSessionFactory.close();
}
/**
* 测试Hibernate的数据存储
* session通过getCurrentSession()方法获取,此方法可以保证当前connection唯一
* 建议使用,但注意使用getCurrentSession时,。
*/
@Test
public void testHibernateSave1(){
//1、加载配置文件,如果hibernate的配置文件名是hibernate.cfg.xml,并且放置在src目录下,可以自动加载
Configuration configuration = new Configuration().configure();
//2、通过configuration创建sessionFactory
SessionFactory buildSessionFactory = configuration.buildSessionFactory();
/**
* 3、通过sessionFactory创建Session,注意:这里的Session是hibernate下的session
* getCurrentSession();方法,将当前线程与本地进行绑定,可以确保操作的session(connection)不会变,
* 相当于ThreadLocal<connection>,建议使用此方法,但在使用此方法前,必须在hibernate.cfx.xml配置文件
* 中进行以下配置:
* <property name="hibernate.current_session_context_class">thread</property>
* 并且手动启动事务并提交,否则会报错
*/
Session openSession = buildSessionFactory.getCurrentSession();
//开启事务,因为使用了getCurrentSession,这里要手动提交事务
Transaction transaction = openSession.beginTransaction();
//4、使用save保存数据
User user = new User();
user.setPassword("password123");
user.setUserName("userName");
openSession.save(user);
//提交事务
transaction.commit();
//5、关闭连接
/**
* 在commit()时就已经关闭,这里不用重新关闭
* openSession.close();
*/
buildSessionFactory.close();
}
/**
* 查询用户信息
*/
@Test
public void hibernateSelect(){
Configuration configuration = new Configuration().configure();
SessionFactory buildSessionFactory = configuration.buildSessionFactory();
//获取当前事务
Session currentSession = buildSessionFactory.getCurrentSession();
//启动事务
Transaction transaction = currentSession.beginTransaction();
//根据id主键查询数据
Object object = currentSession.get(User.class, 1);
//如果查询出来的数据不为空,说明查询到了数据
if(object != null && !"".equals(object)){
User user = (User) object;
//打印查询出的用户信息
System.out.println(user);
}else{
System.out.println("未查询到用户ID为1的数据");
}
//提交事务
transaction.commit();
//关闭事务
buildSessionFactory.close();
}
/**
* 更新用户信息
*/
@Test
public void hibernateEdit(){
Configuration configuration = new Configuration().configure();
SessionFactory buildSessionFactory = configuration.buildSessionFactory();
//获取当前线程
Session currentSession = buildSessionFactory.getCurrentSession();
//启动事务
Transaction beginTransaction = currentSession.beginTransaction();
//查询用户
Object object = currentSession.get(User.class, 2);
//如果用户存在
if(object != null && !"".equals(object)){
User user = (User) object;
//更新用户名为:测试用户
user.setUserName("测试用户");
//更新数据库中的数据
currentSession.update(user);
System.out.println("更新用户信息成功");
}else{
System.out.println("用户不存在,更新失败");
}
//提交事务
beginTransaction.commit();
//关闭连接
buildSessionFactory.close();
}
/**
* 删除数据
*/
@Test
public void hibernateDelete(){
Configuration configuration = new Configuration().configure();
SessionFactory buildSessionFactory = configuration.buildSessionFactory();
//获取当前线程
Session currentSession = buildSessionFactory.getCurrentSession();
//启动事务
Transaction transaction = currentSession.beginTransaction();
//查询用户信息
Object object = currentSession.get(User.class, 3);
//如果查询到了数据,
if(object != null && !"".equals(object)){
//则将数据转换为User实体类
User user = (User) object;
//删除用户信息
currentSession.delete(user);
System.out.println("用户信息删除成功");
}else{
System.out.println("用户不存在,删除失败");
}
//提交事务
transaction.commit();
//关闭连接
buildSessionFactory.close();
}
}
9、执行测试类中的testHibernateSave/testHibernateSave1方法添加数据方法4次,添加4条记录,结果如下:
10、执行hibernateSelect()查询用户信息方法如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hibernate:
select
user0_.id as id0_0_,
user0_.userName as userName0_0_,
user0_.password as password0_0_
from
user user0_
where
user0_.id=?
User [id=1, userName=userName, password=password123]
11、执行hibernateEdit()更新用户信息方法如下:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hibernate:
select
user0_.id as id0_0_,
user0_.userName as userName0_0_,
user0_.password as password0_0_
from
user user0_
where
user0_.id=?
更新用户信息成功
Hibernate:
update
user
set
userName=?,
password=?
where
id=?
这里我没有指定utf-8编码出现 了乱码,如果指定了,不会出现这个问题的。
12、执行hibernateDelete()删除方法如下 :
Hibernate:
select
user0_.id as id0_0_,
user0_.userName as userName0_0_,
user0_.password as password0_0_
from
user user0_
where
user0_.id=?
用户信息删除成功
Hibernate:
delete
from
user
where
id=?
注意,因为代码中,我把输出的“用户信息删除成功”放到了事务中,而数据库中的SQL语句在未提交前,是不会输出执行的,所以就出现了提示信息在前的问题