原子性:指事务是一个不可分割的工作单位。
事务中的操作要么都发生,要么都不发生
一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务
不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性:指一个事务一旦被提交,它对数据库中数据的改变就是永久性的
接下来即使数据库发生故障也不应该对其有任何影响
用事务的sql语句(事务开始和事务提交)包裹住要执行的语句
1.把事务打开
2.写要执行sql语句
3.把事务进行提交
4.当遇到突发事件(如遇到断电)事务没有提交,那么事务会自动回滚
例如:
begin;
update 表 set money=money-100 where username='a';
update 表 set money=money+100 where username='b';
commit;
赃读:指一个事务读取了另一个事务未提交的数据。
(比如:转账还钱,没提交就回滚了)
不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。
一个事务读取到了另一个事务提交后的数据。(update)
(比如:我从柜台取钱,我母亲从ATM取钱 柜台小姐 发现账户数据在跳动)
虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(insert)
mysql默认隔离级别:REPEATABLE READ:避免赃读、不可重复读。虚读有可能发生。
操作数据的对象关系型数据库
使用面向对象的思想去增删改查,避免使用繁琐的sql语句去操作数据
添加对象到数据库
@Test
public void fun1() {
// 1.加载配置文件
// 直接调用configure() 系统会默认读取 hibernate.cfg.xml这个文件
Configuration configuration = new Configuration().configure();
// 2.获取sessionFactory对象 相当于获取连接池对象
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.从工厂中获取一个session对象
// openSession 获取的是一个全新的session
Session session = sessionFactory.openSession();
// 向数据库插入对象
User user = new User();
user.setUsername("SC");
user.setPassword("123");
// 4.使用session对象开启一个事务 返回一个事务对象transaction
Transaction transaction = session.beginTransaction();
// 包裹的要执行的任务
session.save(user);
// 5.提交事务
transaction.commit();
// 6.关闭资源
session.close();
sessionFactory.close();
}
修改对象
@Test
public void fun2() {
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// 修改对象
// 1.获取对象(根据id获取)
User user = session.get(User.class, 1);
// 2.修改对象
user.setUsername("zb");
user.setPassword("1");
// 3.把对象更新一遍 注意:修改的时候就使用update
//session.save(user);
session.update(user);
transaction.commit();
session.close();
sessionFactory.close();
}
查询
方式一:
@Test
public void fun3() {
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// 查询
User user = session.get(User.class, 1);
System.out.println(user);
transaction.commit();
session.close();
sessionFactory.close();
}
方式二:
@Test
public void fun4() {
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// 查询
User user = session.load(User.class, 1);
System.out.println(user);
transaction.commit();
session.close();
sessionFactory.close();
// 报错原因:这时代理对象 才会使用session去查询数据库
// 而session已经销毁了
// System.out.println(user);
}
get和load方法的区别
相同:都能进行对象的查询
不同:
load方式的查询方式是懒加载(延迟加载)
当load方法被执行的时,不会跟get方法一样立即生成sql语句执行
而是生成一个代理对象直接返回
只有当你访问了代理对象的属性时
这时才会去生成sql语句 查询数据库
利用延迟加载提高了hibernate的执行效率
删除
@Test
public void fun5() {
Configuration configuration = new Configuration().configure();
// sessionFactory线程安全的
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// 删除
// 1.先查对象 把该对象删除
// User user = session.get(User.class, 1);
// session.delete(user);
// 2.创建一个对象 只赋值id 删除
User user = new User();
user.setId(2);
session.delete(user);
transaction.commit();
session.close();
sessionFactory.close();
}
简单封装
public class HibernateUtils {
// 把sessionFactory写成成员变量
private static SessionFactory sessionFactory;
static {
// 加载配置文件
Configuration configuration = new Configuration().configure();
// 创建session工厂
sessionFactory = configuration.buildSessionFactory();
}
// 返回session的方法
public static Session getSession() {
return sessionFactory.openSession();
}
// 返回当前session的方法
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
使用HQL查询
@Test
public void fun6() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
// 返回的是保存查询结果的对象
//Query query = session.createQuery("from com.lanou3g.User");
Query query = session.createQuery("from User", User.class);
// 获取到查询结果的集合
List list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
SQL语句查询
@Test
public void fun7() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
// 直接使用sql语句查询
NativeQuery
配置文件的默认名字 hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">123456property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/a_hibernate_01property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialectproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
<mapping resource="com/lanou3g/User.hbm.xml"/>
session-factory>
hibernate-configuration>
需要创建实体类 配置对应的映射文件
名字规范:
1.与实体类名字相同
2.与实体类在同一个包下
3.xml文件
User.hbm.xml
<hibernate-mapping package="com.lanou3g">
<class name="User" table="user">
<id name="id" column="id">
<generator class="native">generator>
id>
<property name="username" column="username">property>
<property name="password" column="password">property>
class>
hibernate-mapping>