Hibernate的环境搭建(uid方式):
1:导入包
2:创建实体对象
3:hibernate的映射配置文件
4:hibernate的核心配置文件
5:创建测试类实现表的创建
2:创建实体对象—User.java
private int uid;
private String username;
private String password;
private String address;
3:hibernate的映射配置文件---User.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">
<hibernate-mapping>
<!--表名对应 ,name属性要求是实体对象的全路径,table属性要求是对应的表名 -->
<class name="com.entity.User" table="t_user">
<!--hibernate要求有唯一的id值,native值是说明表里的id是主键,并且自动增长 -->
<!-- column属性可以省略,如果省略默认和实体字段名相同 -->
<id name="uid" column="uid">
<generator class="native"></generator>
</id>
<!-- 这里的name属性必须和实体实里的字段名一样,建议复制过 -->
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="address" column="address"></property>
</class>
</hibernate-mapping>
4: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>
<!-- 1:配置数据库信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!-- 2:配置hibernate信息可选的 -->
<!--在控制台显示sql -->
<property name="hibernate.show_sql">true</property>
<!-- 控制台显示的sql语句格式化输出-->
<property name="hibernate.format_sql">true</property>
<!-- 这句代码很关键,只有配置了它,hibernate才会自动生成表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 这句代码能够让hibernate使用mysql的特殊语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 3:把映射文件放到核心配置文件中 -->
<mapping resource="com/entity/User.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
5:创建测试类实现表的创建---Demo1.java
public class Demo1 {
@Test
public void add() {
// 1.加载核心配置文件,它会自动去SRC下面找hibernate.cfg.xml的文件
Configuration configuration = new Configuration().configure();
// 根据核心配置文件创建SessionFactory对象,并根据映射关系,在配置数据库里把表创建
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.通过工厂创建Session,类似于连接
Session session = sessionFactory.openSession();
// 4.开启事务
Transaction tx = session.beginTransaction();
// 5.写具体的逻辑crud操作
User user = new User();
user.setUsername("小陈");
user.setPassword("123");
user.setAddress("中国");
//调用session的方法实现添加
session.save(user);
// 6.提交事务
tx.commit();
// 7.关闭资源
session.clear();
sessionFactory.close();
}
}
但是前面的代码有问题,它是不完整的,第二步的SessionFactory如果多次创建就会多次去创建表,这样就会特别浪费资源,所以,我们把它抽取出来封装成一个工具类.----HibernateUtils.java
public class HibernateUtils {
private static Configuration configuration =null;
private static SessionFactory sessionFactory=null;
static {
// 1.加载核心配置文件,它会自动去SRC下面找hibernate.cfg.xml的文件
configuration = new Configuration().configure();
// 根据核心配置文件内容创建SessionFactory对象,并根据映射关系在配置数据库里把表创建
sessionFactory = configuration.buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
那个我们的测试类就改写为:---Demo2.java
public class Demo2 {
@Test
public void add() {
//省略前两步,直接通过工具类得到SessionFactory对象;
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 3.通过工厂创建Session,类似于连接
Session session = sessionFactory.openSession();
// 4.开启事务
Transaction tx = session.beginTransaction();
// 5.写具体的逻辑crud操作
User user = new User();
user.setUsername("小洪");
user.setPassword("123");
user.setAddress("中国");
//调用session的方法实现添加
session.save(user);
// 6.提交事务
tx.commit();
// 7.关闭资源
session.clear();
sessionFactory.close();
}
}
同时后面几步也是不完整的,比如第三步的session下还有save,updata,delete,根据id查询的get方法
第四步的Transaction下面有commit和rollback方法;
实体类的编写规范:
1:实体类里面的属性私有
2:私有属性使用公开的set和get方法进行操作
3:要求实体类有属性作为唯一值 (一般使用id值)
4:实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类
比如如果使用基本数据数据类型去表示某一学生考0分和没有考就没办法表示
使用包装类我们就可以用0去表示0分,null去表示没有考
实体类的主键生成策略:
一共有两种:native 和uuid
上面用的native,如果改成uuid,那么实体类中的唯一值要改成字符串
private String uuid;
映射配置文件里的唯一id的生成策略要改成
<generator class="uuid"></generator>
实现类的操作,根据id查询:
// 5.写具体的逻辑crud操作
//第一个参数:实体类的class
//第二个参数:id值
User user=session.get(User.class, 1);
System.out.println(user);
实现类的操作,修改:
User user=session.get(User.class, 1);
user.setUsername("小小陈");
session.update(user);
实现类的操作,删除:
User user=session.get(User.class,2);
session.delete(user);
还有一种方式可以实现上面的四步:但是不推荐,因为结果有可能不是想要的,例如下面,它修改后其它项就是空
这种方式叫托管态,如果没有id值,那么它就是瞬时态,瞬时态一般只用于添加操作,其它三种操作尽量不要用;
删除,修改,查询,我们用持久态,里面有id,跟session有关联
User user=new User();
user.setUid(1);
user.setUsername("小洪");
session.update(user);
实现类的三种状态:
瞬时态:对象里面没有id,跟session没有关联(一般用于添加数据)
托管态:对象里面有id,跟session没有关联(如果是主键自动增长,这id通常没有意义)
持久态:有id,跟session有关联(数据库里查出来的数据)
Session下有一个常用的方法savaOrUpdate(),它会根据三种不同的状态去决定是保存还是修改
如果是瞬时态,那么它就会保存,如果是托管态或者持久态,它就会修改;
Hibernate的一级缓存:
1:它是默认打开的
2:它的范围,是session的范围,从session创建到session关闭
3:它存储的数据必须是持久数据(就是从数据库里查出来的数据)
当我们第一次根据id查询了数据后,它就保存到缓存中了,第二次查,就会直接到内存中去查了
Hibernate的二级缓存:
二级缓存现在不用了redis技术替代它了,它要手动开启,它的范围是SessionFactory
Hibernate查询数据的执行过程:
它首先会去缓存中查找,如果没有找到,它就会去数据库中找,并把找到的数据存入一级缓存中以及快照(副本)中
Hibernate修改数据的执行过程:
它会首先去修改实体对象里的值,以前一级缓存里的值,然后去比较快照里的值,如果相同,就不修改,如果不同就去数据库里修改值,这样极大的提高效率
事务隔离级别:
1:Read uncomitted isolation
2:Read committed isolation
4:Repeatable read isolation
8:Serializble isolation
Hibernate环境搭建最终模板
由于可能会有很多人同时访问你的程序,那么这时就要让session同线程一起绑定,保证session的唯一性,如何绑定:
1:在核心配置文件里加入绑定语句:
<property name="hibernate.connection.isolation">4</property>
2:工具类里加上返回session有方法:
public static Session getSession(){
return session;
}
3:实现类里加上try catch finnaly 并且不再关闭资源,因为session绑定线程后,关闭session后,纯种也后跟着关闭,这样就会出错;
那么四个模板的最终样式如下:
核心配置文件----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>
<!-- 1:配置数据库信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!-- 2:配置hibernate信息可选的 -->
<!--在控制台显示sql -->
<property name="hibernate.show_sql">true</property>
<!-- 控制台显示的sql语句格式化输出-->
<property name="hibernate.format_sql">true</property>
<!-- 这句代码很关键,只有配置了它,hibernate才会自动生成表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 这句代码能够让hibernate使用mysql的特殊语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- session绑定线程 -->
<property name="hibernate.connection.isolation">4</property>
<!-- 3:把映射文件放到核心配置文件中 -->
<mapping resource="com/entity/User.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
工具类----HibernateUtils.java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
private static Configuration configuration =null;
private static SessionFactory sessionFactory=null;
private static Session session=null;
static {
// 1.加载核心配置文件,它会自动去SRC下面找hibernate.cfg.xml的文件
configuration = new Configuration().configure();
// 根据核心配置文件内容创建SessionFactory对象,并根据映射关系,在配置数据库里把表创建
sessionFactory = configuration.buildSessionFactory();
//根据sessionFactory得到session
session=sessionFactory.openSession();
}
public static Session getSession(){
return session;
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
实现类模板----Demo.java
public class Demo1 {
@Test
public void add() {
Session session=null;
Transaction tx=null;
try {
session = HibernateUtils.getSession();
// 4.开启事务
tx = session.beginTransaction();
// 5.写具体的逻辑crud操作
User user = new User();
user.setUsername("小陈");
user.setPassword("123");
user.setAddress("中国");
// 调用session的方法实现添加
session.save(user);
// 6.提交事务
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}
}
}
映射类模板-----User.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">
<hibernate-mapping>
<!--表名对应 ,name属性要求是实体对象的全路径,table属性要求是对应的表名 -->
<class name="com.entity.User" table="t_user">
<!--hibernate要求有唯一的id值,native值是说明表里的id是主键,并且自动增长 -->
<!-- column属性可以省略,如果省略默认和实体字段名相同 -->
<id name="uuid" column="uuid">
<generator class="uuid"></generator>
</id>
<!-- 这里的name属性必须和实体实里的字段名一样,建议复制过 -->
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="address" column="address"></property>
</class>
</hibernate-mapping>
实现类里的查询操作有三个对象对应三种不同的方式可以实现分别如下:
Query:
Query query=session.createQuery("from User");
List<User> list=query.list();
for (User user : list) {
System.out.println(user);
}
Criteria
Criteria criteria=session.createCriteria(User.class);
List<User> list = criteria.list();
for (User user : list) {
System.out.println(user);
}
SQLQuery:
这个比较特殊,它返回的是数组,所以要先将数组转成对象
SQLQuery sqlQuery=session.createSQLQuery("select * from t_user");
sqlQuery.addEntity(User.class);
List<User> list=sqlQuery.list();
for (User user : list) {
System.out.println(user);
}
原文:http://www.cnblogs.com/chenxiaoyang/p/6358302.html