一、配置文件(设置隔离级别和配置使用getCurrentSession)
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"hibernate.cfg.xml">
<!--hibernate 配置的跟标签 -->
<hibernate-configuration>
<!--sessionFactory(会话工厂)相当于,数据库连接池 -->
<session-factory>
<!--加载数据库的驱动类 ,基础设置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/a_hibernate_01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!--hibernate方言 mysql方言 limit -->
<!--配置使用哪个类,全类名 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--在控制台输出sql语句 -->
<property name="hibernate.show_sql">true</property>
<!--美化sql语句 -->
<property name="hibernate.format_sql">true</property>
<!--hbm2ddl.auto是否自动生成表结构 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--
通过hibernate来设置事物的隔离级别
这个事物的隔离级别设置
1.脏读
2.可重复读
3.幻读
READ UNCOMMITTED 读未提交 123 1
READ COMMITTED 读已提交 23 2
REPEATABLE READ 可重复读 3 4
SERIALIZABLE 串行化(只能一个一个访问) 8
设置事物的隔离级别(etc里面找到
specify a JDBC isolation level
hibernate.connection.isolation 1|2|4|8
隔离级别是用一个字节存储的
0001 1
0010 2
0100 4
1000 8
-->
<property name="hibernate.connection.isolation">4</property>
<!--使用getCurrentSession必须配置一下
注意:当你使用getCurrentSession时
不需要你手动关闭session,系统会帮你关闭
-->
<property name="hibernate.current_session_context_class">thread</property>
<!--注意:映射实体类 全文件名 从包名开始 -->
<!--让配置文件知道有你这个实体类 与映射文件进行关联配置 -->
<mapping resource="com/lanou3g/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
二、映射文件(主键生成策略有7个)
1.indentity:主键自增,有数据库维护
2.increment:主键自增,有hibernate维护,会先查询最大id,然后
在这个最大id的基础上+1,并且插入数据时有id
3.sequence:序列-Oracle
4.hilo:高低位算法,通过hibernate会自己通过该算法,算出主键自增
5.native(常用):hilo + indentity + sequence 三选一
6.uuid:全球范围内,不重复的值,是字符串。
注意:主键是字符串类型,是由hibernate生成uuid,然后插入到数据库中的
7.assigned:是由程序员自己管理主键
<?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.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>
三、hibernate中的三种状态
1.游离态:没有id,没有和session产生关联
2.持久态:有id,有和session产生关联
3.游离态:有id,没有和session产生关联
//hibernate的三种形态
public void fun2() {
//获取session
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
User user = new User(); //瞬时态,没有id,没有和session关联
user.setUsername("wanglong");
user.setPassword("123");
session.save(user); //持久态,有id,有session关联
transaction.commit();
session.close(); //游离态,有id,没有关联
}
解析:这里我们获取数据库中数据,当我们第一次get的时候,会生成查询语句,
获取查询的数据,然后在向hibernate返回结果集,并且将
结果集封装成对象,保存在缓存中,当我们再次调用get时,这时我们会去缓存中查看是否有这个id的对象,
有的话,就不生成sql查询语句,
没有的话就生成sql查询语句。
注:在这个方法执行内,所有的返回到hibernate的结果集都会保存在缓存中。
public void fun3() {
//获取session
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//---------
/*
* 测试一下hibernate中的缓存
*
*/
User user1 = session.get(User.class, 1);
User user2 = session.get(User.class, 1);
User user3 = session.get(User.class, 1);
User user4 = session.get(User.class, 1);
User user5 = session.get(User.class, 1);
//1.生成几条sql语句
//2.打印结果
System.out.println(user2==user5);
//----------
transaction.commit();
session.close();
}
快照测试:
解析:这里我们两次设置usernaeme,第二个dp是数据库中id为1存在的,但是没有更新数据库的sql语句打印
是因为当我们第一个get的时候返回的结果集封装成对象到hibernate中,并且分别保存到缓存中和保存到快照中,在我们去set修改的时候,第一次修改我们修改了缓存中的对象,也就是将dp变成了haha,然后我们再继续执行set又将haha变成了dp,set语句执行完毕,当事物进行提交后,就会与快照里面的对象进行比对:
有:就不做修改的sql语句生成
没有:就生成更新的sql语句
public void fun4() {
//获取session
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//---------
User user = session.get(User.class, 1);
user.setUsername("haha");
user.setUsername("dp");
session.update(user);
//----------
transaction.commit();
session.close();
}
四、查询测试
1.HQL查询测试:session调用createQuery();方法,在用该方法的返回对象去调用预见结果的方法
这个预见方法分为两种
a):uniqueResult()--这个是预见但数据结果的方法
b):list()--这个是预见多数据结果的方法
public void fun1() {
String hql ="From User";
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery(hql);
//------------
//预见一下结果(单数据)
// User user = (User)query.uniqueResult();
List list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
2.占位符 ?
解析:我们用createQuery()的返回对象去调用setParamenter(1,2)方法,
里面的参数1:我们填写的是索引(也就是从左到右第一个问号索引是0,第二个是1。。。。)
参数2:我们填写的是对应的值
public void fun2() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//------------
String hql = "from User where id = ? and username = ?";
Query query = session.createQuery(hql);
//给语句中问号赋值,索引从0开始
query.setParameter(0, 1);
query.setParameter(1, "wanglong");
User user = (User)query.uniqueResult();
System.out.println(user);
//----------
transaction.commit();
session.close();
}
3.冒号占位符 :
public void fun3() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//------------
//冒号后面相当于,给这个冒号占位符,起了个别名
//注意:冒号后面不要搞空格
String hql = "from User where id =:ww";
Query query = session.createQuery(hql);
//直接使用别名,给占位符赋值
User user = (User)query.setParameter("ww",1);
System.out.println(user);
//----------
transaction.commit();
session.close();
}
4. 分页查询
@Test
public void fun4() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//------------
String hql = "from User";
Query query = session.createQuery(hql);
//设置起始和最大显示
query.setFirstResult(2);
query.setMaxResults(2);
//接受结果
List list = query.list();
System.out.println(list);
//----------
transaction.commit();
session.close();
}
5.无语局查询
public void fun5() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//------------
Criteria criteria = session.createCriteria(User.class);
List list = criteria.list();
System.out.println(list);
//----------
transaction.commit();
session.close();
}
7.查询一共有多少记录数
public void fun7() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//------------
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.rowCount());
//一般返回值是个数的通常都是用大Long来接收
Long l =(Long) criteria.uniqueResult();
System.out.println(l);
//----------
transaction.commit();
session.close();
}
8.原生sql语句查询
注意:返回的结果跟对象没有关系
public void fun8() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//------------
String sql = "select * from user where id = ?";
Query query = session.createSQLQuery(sql);
//一条记录就是一个Object数组
query.setParameter(0, 3);
Object [] objects = (Object[])query.uniqueResult();
System.out.println(Arrays.toString(objects));
// List<Object[]> list = query.list();
// for (Object[] objects : list) {
// System.out.println(Arrays.toString(objects));
// }
//----------
transaction.commit();
session.close();
}