hibernate4
来源:互联网 发布:java处理xml 编辑:程序博客网 时间:2024/05/22 23:22
1:Hibernate是一个对象关系映射(ORM)框架,对jdbc进行了轻量级的对象封装,将pojo和数据表建立映射,是一个全自动的ORM框架,可以自动生成sql语句,自动执行。,
既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。
Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
1:CMP (Container Managed Persistence,容器管理的持久性,服务器负责处理数据库访问)
2:ejb和hibernate都是反映对数据库的映射和操作,只不过ejb是重量级的,hibernate是轻量级的。不过ejb自主性比较高,可以更强的覆盖业务逻辑那块,划分的更细致,另外,还兼顾一定的spring那类的功能。ejb所谓重量级,是说更适合做银行项目,移动电信的项目,它对于这类的大项目,可以把步骤,操作做的更细,而且在分布上,对struts等一类的结合比hibernate更灵活一些。hibernate相对来讲,更适合做网站类项目,应用简单灵活。不过对于银行这类的项目弱点
3:引用传递:两个指向一个对象
值传递:一个变量接受一个值
2:hibernate的环境搭建
1:下载hibernate文件包,创建项目,导入需求(require)包
----------------------------------------------------------------------------
2:创建hibernate.cfg.xml配置文件(注意约束文件地址的缘由)
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate.connection.driver_class中的hibernate在hibernate项目中可以省略 -->
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- ///自动访问本地的数据库,默认端口没变的情况下可以这么写 -->
<propertyname="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<propertyname="hibernate.connection.username">root</property>
<propertyname="hibernate.connection.password">root</property>
<!-- 添加额外的属性显示sql语句并格式化-->
<propertyname="show_sql">true</property>
<propertyname="format_sql">true</property>
<!-- 引入hibernate的ORM文件 -->
<!--
ORM:对象关系映射(Object Relational Mapping)
1:对象名称映射表名
2:对象的属性名映射字段名
3:对象的类型映射字段兼容类型
-->
<mappingresource="com/hb/demo/pojo/BookInfo.hbm.xml"/>
<mappingresource="com/hb/demo/pojo/TypeInfo.hbm.xml"/>
</session-factory>
</hibernate-configuration>
----------------------------------------------------------------------------
3:创建两个pojo实体BookInfo、TypeInfo
private IntegerbookId;
private StringbookName;
private StringbookAuthor;
private FloatbookPrice;
private DatebookPublishDate;
private TypeInfo type;
private IntegertypeId;
private String typeName;
----------------------------------------------------------------------------
4:创建两个实体的BookInfo.hbm.xml、TypeInfo.hbm.xml映射配置(统一注意约束)
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mappingpackage="com.hb.demo.pojo">
<!--
字段和表名不区分大小写
属性要区分大小写
-->
<classname="TypeInfo"table="TypeInfo">
<!-- 配置主键 -->
<idname="typeId"type="java.lang.Integer">
<columnname="typeId"sql-type="int"/>
<!--
主键生成策略
1:native 根据hibernate提供对应数据的方言来生成id
2:increment,identity mysql/sqlserver
3:sequence oracle
4:assigned 需要手动制定主键的值
-->
<generatorclass="native"/>
</id>
<!-- 配置属性类型可自动识别,mybatis也一致-->
<propertyname="typeName"column="typeName"/>
</class>
</hibernate-mapping>
----------------------------------------------------------------------------
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mappingpackage="com.hb.demo.pojo">
<classname="BookInfo"table="BookInfo">
<idname="bookId"column="bookId">
<generatorclass="native"/>
</id>
<!--
有三种书写方式
column可省略
-->
<propertyname="bookName">
<columnname="bookName" />
</property>
<propertyname="bookAuthor"column="bookAuthor"/>
<propertyname="bookPrice"/>
<propertyname="bookPublishDate"/>
<!-- 配置多对一 -->
<!--
name 属性被设置为在父类中定义的变量
class 关联的类的名字
culumn-name 数据库中的BookInfo的typeId字段名称
-->
<many-to-onename="type"class="TypeInfo">
<!-- 数据库中的BookInfo的typeId字段名称 -->
<columnname="typeId"/>
</many-to-one>
</class>
</hibernate-mapping>
----------------------------------------------------------------------------
5:简单测试
public class TestHibernateDev {
private static SessionFactory sessionFactory;
private static final String FILE_PATH="/hibernate.cfg.xml";
private Sessionsession;
static{
//1:加载hibernate的配置文件
Configurationcfg= newConfiguration().configure(FILE_PATH);
//2:hibernate4以下版本,5以上版本
//sessionFactory = cfg.buildSessionFactory();
//3: 4版本
//1:注册一个创建SessionFactory对象的服务对象ServiceRegistry
ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
//2:构建SessionFactory对象
sessionFactory=cfg.buildSessionFactory(serviceRegistry);
}
//断言测试,判断对象是否存在
@Test
public void testSessionFactory(){
System.out.println(sessionFactory);
//断言(可使用包静态导入)
Assert.assertNotNull(sessionFactory);
}
//获取SessionFactory中的Session对象
@Before
public void getSession(){
System.out.println("执行测试方法之前执行");
session = sessionFactory.openSession();
}
@Test
public void testSession(){
System.out.println(session);
}
@After
public void closeSession(){
System.out.println("执行测试方法之后执行");
if(session.isConnected()){
session.close();
session = null;
}
}
}
----------------------------------------------------------------------------
6:测试添加对象的方法
/**
* 测试添加对象的方法
* 2017年4月13日
* void
* saveObject
*/
@Test
public void saveObject(){
// 创建一个TypeInfo对象
TypeInfotypeInfo= newTypeInfo();
typeInfo.setTypeName("漫画");
typeInfo.setTypeId(32);
// 定义事务对象的句柄
Transactiontx = null;
try {
//开启事务对象
tx = session.beginTransaction();
// 返回当前新增数据对应的主键值
/*Serializable result = session.save(typeInfo);*/
// 根据对象session中存储的oid存在,进行修改,只设置名称进行新增;
/*session.saveOrUpdate(typeInfo);*/
// 先判断是否存在oid,存在:detached entity passedto persist;只有在事务中执行,才能打印sql语句,没有id时,直接添加
session.persist(typeInfo);
tx.commit();
//System.out.println(result);
}catch(Exceptione) {
e.printStackTrace();
if(tx !=null){
// 回滚事务
tx.rollback();
}
}
}
----------------------------------------------------------------------------
/**
* 测试修改的方式
* 2017年4月13日
* void
* updateObject
*/
@Test
public void updateObject(){
// 创建一个TypeInfo对象
TypeInfotypeInfo= newTypeInfo();
typeInfo.setTypeName("文学");
typeInfo.setTypeId(34);
// 定义事务对象的句柄
Transactiontx = null;
try {
tx = session.beginTransaction();
//1:推荐
// session.update(typeInfo);
//2:必须设置typeId
// session.saveOrUpdate(typeInfo);
//3: 1:查询数据存在后,所有字段都相同时,不会更新,
// 2:发现typeId不存在时,实行增加(typeId可加可不加)
// 3:当typeId存在时,名字不同时,实行修改
session.merge(typeInfo);
tx.commit();
}catch(Exceptione) {
e.printStackTrace();
if(tx !=null){
// 回滚事务
tx.rollback();
}
}
}
----------------------------------------------------------------------------
/**
* 测试删除的方式
* 只能通过主键删除对象
* 2017年4月13日
* void
* updateObject
*/
@Test
public void deleteObject(){
// 创建一个TypeInfo对象
TypeInfotypeInfo= newTypeInfo();
typeInfo.setTypeId(33);
// 定义事务对象的句柄
Transactiontx = null;
try {
tx = session.beginTransaction();
//必须typeId存在,否则会报错
session.delete(typeInfo);
tx.commit();
}catch(Exceptione) {
e.printStackTrace();
if(tx !=null){
// 回滚事务
tx.rollback();
}
}
}
----------------------------------------------------------------------------
3:hibernate的三种状态
////////////////对象的三种状态(瞬时,持久,游离)//////////////////////
// 1:瞬时:与session没有关联,hibernate监控不到对象的状态
// 2:持久:与session有关联,事务未提交,当对象的内容发生变化时,hibernate可以监控到
// 3:游离(删除|托管):与session没有关联;游离对象在数据库中可能还存在一条与它对应的记录,hibernate检测不了对象的状态
@Test
public void testState(){
TypeInfotypeInfo= newTypeInfo();//瞬时态
typeInfo.setTypeName("xxx");
Transactiontx = null;
try {
tx = session.beginTransaction();
// 判断oid是否存在:存在就报错,不存在更新,没有id时,直接添加
session.persist(typeInfo);//提交事务对象变为持久状态
typeInfo.setTypeName("aaa");
tx.commit();
/*// 会打印修改语句
typeInfo.setTypeName("bbb");
//如果一个对象以及是持久化状态了,那么此时对该对象进行各种修改,
* 或者调用多次update、save方法时,hibernate都不会发送sql语句,
* 只有当事物提交的时候,此时hibernate才会拿当前这个对象与之前保存在session中的持久化对象进行比较,
* 如果不相同就发送一条update的sql语句,否则就不会发送update语句
//删除后,不会打印修改和删除语句
session.delete(typeInfo);*/
session.close();//关闭session后变为游离状态(托管对象)
System.out.println(typeInfo.getTypeName());
typeInfo.setTypeName("ccccccccc");
session = sessionFactory.openSession();
/*// 不能对托管对象进行持久化操作
session.persist(typeInfo);*/
session = sessionFactory.openSession();
tx = session.beginTransaction();
//sava可以将托管对象转换为持久对象
session.save(typeInfo);
tx.commit();
}catch(Exceptione) {
if(tx !=null){
tx.rollback();
}
}
}
----------------------------------------------------------------------------
4:使用hibernate插件搭建环境
1:使用link安装插件方式
1. 在eclipse目录创建myplugins和links
2. 将插件的两个文件复制到myplugins中
3. 在links创建配置文件,以.link结尾,名字可任意
配置内容:
Path=myplugins的目录(path=D:\\eclipse\\myplugins)
2:使用插件工具生成hibernate.cfg.xml配置文件
1:添加额外属性
<propertyname="show_sql">true</property>
<propertyname="format_sql">true</property>
2:引入hibernate的ORM文件
<mappingresource="com/hb/demo/pojo/BookInfo.hbm.xml"/>
<mappingresource="com/hb/demo/pojo/TypeInfo.hbm.xml"/>
3:配置正向生成数据库中的表
update:每次访问的时候会检测如果存在就不更新
create:每次访问都会删除重新生成语句(需要修改数据库的时候使用)
<property name="hbm2ddl.auto">update</property>
3:创建BookInfo和TyperInfo实体,再使用插件工具通过实体生成
注意两个小细节
1:将所有的列表格式化
<column name="BOOK_ID" />
2:将修改生成主键策略
<generatorclass="native" />
5:创建一个sessionFactory工具类,
1:保证一个数据库对应一个sessionFactory
2:保证同一个客户端用户使用同一个session对象
public class HibernateSessionFactory {
private static SessionFactory sessionFactory;
// 使用本地线程对象管理session对象
private final staticThreadLocal<Session>threadLocal =newThreadLocal<Session>();
// 保证满足第一个条件
static {
buildSessionFactory();
}
/**
* 定义构建SessionFactory对象的方法 2017年4月14日
*
* @return SessionFactory buildSessionFactory
*/
public static void buildSessionFactory() {
// 判断SessionFactory是否为空
if (sessionFactory==null){
Configurationcfg= newConfiguration().configure();
ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties())
.build();
sessionFactory=cfg.buildSessionFactory(serviceRegistry);
}
}
/**
* 定义获取session的方法
* 2017年4月14日
* @return
* Session
* getSession
*/
public static Session getSession() {
// 从本地线程中获取Session对象
Sessionsession= threadLocal.get();
// 判断session为null需要把创建的session对象方法放到本地线程中
if (session ==null) {
// 判断sessionFactory为空
if(sessionFactory==null){
buildSessionFactory();
}
session = sessionFactory.openSession();
// 设置到本地线程中
threadLocal.set(session);
}
returnsession;
}
public static void closeSession(){
Sessionsession= threadLocal.get();
if(session.isConnected()&&session!=null){
session.close();
session = null;
threadLocal.set(null);
}
}
}
简单的创建一个测试类,创建一个实例
publicclass TestUtil {
public static void main(String[] args) {
System.out.println(HibernateSessionFactory.getSession());
}
}
----------------------------------------------------------------------------
6:四种查询操作
1:原生SQL
public classTestNativeQuery {
@SuppressWarnings("unchecked")
/**
* 查询所有字段
* 2017年4月14日
* void
* testQueryAll
*/
@Test
public void testQueryAll() {
Sessionsession= HibernateSessionFactory.getSession();
// 创建原生SQL查询对象
SQLQueryquery= session.createSQLQuery("select * from bookInfo");
// 1:得到对象地址
/*List<?>list = query.list();
System.out.println(list); */
// 返回结果:
// [[Ljava.lang.Object;@4e0ae11f,[Ljava.lang.Object;@238d68ff,
// [Ljava.lang.Object;@4b86805d,[Ljava.lang.Object;@5852c06f]
// 2: 返回对象的键的值
/*List<Object[]>list = query.list();
for (Object[] object : list) {System.out.println(object[0]); }*/
// 返回结果:
//1
//2
//3
//4
// 3:返回实体对象地址
List<BookInfo> bookList =query.addEntity(BookInfo.class).list();
System.out.println(bookList);
// 返回结果:
// [com.hb.demo.pojo.BookInfo@4149c063,
// com.hb.demo.pojo.BookInfo@6c7a164b,
// com.hb.demo.pojo.BookInfo@4c2bb6e0,
// com.hb.demo.pojo.BookInfo@3e62d773]
}
/**
* 查询单个字段 2017年4月14日 voidTestQuerySingle
*/
@SuppressWarnings("unchecked")
@Test
public void TestQuerySingle() {
Sessionsession= HibernateSessionFactory.getSession();
SQLQueryquery= session.createSQLQuery("select book_name from bookInfo");
// 返回查询单个字段值组成数组
List<Object>list= query.list();
System.out.println(list);
// 返回结果:
// [朝花夕拾,三国演义,葫芦娃,近代史]
}
/**
* 查询多个字段
* 2017年4月14日
* void
* TestQueryMultiple
*/
@SuppressWarnings("unchecked")
@Test
public void TestQueryMultiple() {
Sessionsession= HibernateSessionFactory.getSession();
// 1:不加条件的多个字段查询
/*SQLQuery query = session.createSQLQuery("selectbook_Id,book_Name from bookInfo");
//返回查询多个字段值组成数组集合
List<Object>list = query.list();
System.out.println(list);
//返回结果
//[[Ljava.lang.Object;@78fa769e, [Ljava.lang.Object;@16612a51,
//[Ljava.lang.Object;@54e041a4, [Ljava.lang.Object;@2c78324b]*/
// 2:帅选条件的多个字段查询(两种写法)
// 1:不使用占位符的方式写条件
SQLQueryquery= session.createSQLQuery("select book_Id,book_Name from bookInfo wherebook_id=?");
// 设置参数
query.setInteger(0, 2);
List<Object>list= query.list();
System.out.println(list);
// 返回结果:
// [[Ljava.lang.Object;@54e041a4]
// 2:使用占位符的方式写条件
SQLQueryquery1= session.createSQLQuery("select book_Id,book_Name from bookInfo wherebook_id=:bookId");
// 设置参数
query1.setInteger("bookId",2);
List<Object>list1= query1.list();
System.out.println(list1);
}
}
----------------------------------------------------------------------------
2:HQL测试HQL的查询操作
public classTestHibernateQuery{
/**
* 查询所有实体对象
* 2017年4月14日
* void
* testQueryAll
*/
@SuppressWarnings("unchecked")
@Test
public void testQueryAll(){
Sessionsession= HibernateSessionFactory.getSession();
// 创建HQL查询对象
// HQL sql语句的(标准)是关键字全部大写
Queryquery= session.createQuery("FROM BookInfo");
System.out.println(query.list());
List<BookInfo>bookList=query.list();
for (BookInfobookInfo :bookList) {
System.out.println(bookInfo.getType().getTypeName());
}
// 返回结果:
// [com.hb.demo.pojo.BookInfo@1787bc24,com.hb.demo.pojo.BookInfo@29a5f4e7,
// com.hb.demo.pojo.BookInfo@79c97cb,com.hb.demo.pojo.BookInfo@2d9caaeb]
}
/**
* 查询单个实体对象
* 2017年4月14日
* void
* testQuerySingle
*/
@SuppressWarnings("unchecked")
@Test
public void testQuerySingle(){
Sessionsession= HibernateSessionFactory.getSession();
Queryquery= session.createQuery("SELECT new BookInfo(bookName) FROM BookInfo");
List<BookInfo>bookList=query.list();
System.out.println(bookList.get(0).getBookName());
// 返回结果:
// 朝花夕拾
}
/**
* 带条件的查询对象
* 2017年4月14日
* void
* testQueryByCount
*/
@SuppressWarnings("unchecked")
@Test
public void testQueryByCount(){
Sessionsession= HibernateSessionFactory.getSession();
Queryquery= session.createQuery("FROM BookInfo WHERE type.typeId=:typeId");
query.setInteger("typeId",3);
List<BookInfo>bookList=query.list();
System.out.println(bookList);
// 返回结果:
// [com.hb.demo.pojo.BookInfo@59d4cd39]
}
/**
* 查询单条记录的时候
* 2017年4月14日
* void
* testQueryByCount
*/
@Test
public void testSingleRecord(){
Sessionsession= HibernateSessionFactory.getSession();
Queryquery= session.createQuery("FROM BookInfo WHERE bookId=:bookId");
query.setInteger("bookId",3);
BookInfobookInfo= (BookInfo)query.uniqueResult();
System.out.println(bookInfo);
// 返回结果:
// com.hb.demo.pojo.BookInfo@59d4cd39
}
/**
* 查询单条数据
* 2017年4月14日
* void
* testSingleRecord
*/
@Test
public void testLoad(){
Sessionsession= HibernateSessionFactory.getSession();
BookInfobookInfo= (BookInfo)session.load(BookInfo.class, 2);
System.out.println(bookInfo);
HibernateSessionFactory.closeSession();
// 返回结果:
// com.hb.demo.pojo.BookInfo@463fd068
}
/**
* 查询单条数据
* 2017年4月14日
* void
* testGet
*/
@Test
public void testGet(){
Sessionsession= HibernateSessionFactory.getSession();
BookInfobookInfo= (BookInfo)session.get(BookInfo.class, 2);
System.out.println(bookInfo);
HibernateSessionFactory.closeSession();
// 返回结果:
// com.hb.demo.pojo.BookInfo@463fd068
}
/**
* 查询单条数据得到TypeInfo的字段
* 2017年4月14日
* void
* testGet
*/
@Test
public void testGetTypeInfo(){
Sessionsession= HibernateSessionFactory.getSession();
BookInfobookInfo= (BookInfo)session.get(BookInfo.class, 2);
System.out.println(bookInfo.getType().getTypeName());
HibernateSessionFactory.closeSession();
// 返回结果:
// 小说
}
/**
* 测试load()和 get()两者的结果是否相同
* 2017年4月14日
* void
* test
*/
@Test
public void test(){
testLoad();
testGet();
// 返回结果:相同
// 因为查询后oid(session)会放在缓存中,若存在就直接拿
}
/**
* 测试分页查询
* 2017年4月14日
* void
* testPagination
*/
@Test
public void testPagination(){
Sessionsession= HibernateSessionFactory.getSession();
Queryquery= session.createQuery("FROM BookInfo");
// (当前页-1)*每页数=当前页第一条数据的记录数
query.setFirstResult(2);//从第2条记录开始
query.setMaxResults(2);//每页显示2条
System.out.println(query.list());
// 返回结果为:
// [com.hb.demo.pojo.BookInfo@6b6776cb,com.hb.demo.pojo.BookInfo@f14a7d4]
// 查询最新一个对象
// select * from bookInfo order by book_Iddesclimit 1
// 查询最新一个id
// select MAX(book_Id) from bookInfo
}
/**
* 查询总记录数
* 2017年4月14日
* void
* testCount
*/
@Test
public void testCount(){
Sessionsession= HibernateSessionFactory.getSession();
Queryquery= session.createQuery("SELECT count(*) FROM BookInfo");
// 两种取值
System.out.println(query.list().get(0));
System.out.println((((Long)query.iterate().next())).intValue());
// 返回结果为:
// 4
}
}
----------------------------------------------------------------------------
3:QBC操作
public classTestHibernateCriteria {
/**
* 查询所有实体对象
* 2017年4月14日
* void
* testQueryAll
*/
@SuppressWarnings("unchecked")
@Test
public void testQueryAll(){
Sessionsession= HibernateSessionFactory.getSession();
List<BookInfo>bookList= (List<BookInfo>)session.createCriteria(BookInfo.class).list();
System.out.println(bookList);
// 返回结果:
// [com.hb.demo.pojo.BookInfo@74287ea3,com.hb.demo.pojo.BookInfo@a8ef162,
// com.hb.demo.pojo.BookInfo@7ac296f6,com.hb.demo.pojo.BookInfo@22f59fa]
}
/**
* 查询所有对象的某一个字段
* 2017年4月14日
* void
* testQueryAll
*/
@Test
public void testSingleField(){
Sessionsession= HibernateSessionFactory.getSession();
Criteriacrt= session.createCriteria(BookInfo.class);
/*crt.setProjection(Projections.id());
System.out.println(crt.list());
//返回结果:
//[1, 2, 3, 4]
*/
crt.setProjection(Projections.property("bookName"));
System.out.println(crt.list());
// 返回结果:
// [朝花夕拾,三国演义,葫芦娃,近代史]
}
/**
* 查询所有对象的多个字段(根据条件'模糊查询)
* 2017年4月14日
* void
* testMultipleField
*/
@Test
public void testMultipleField(){
Sessionsession= HibernateSessionFactory.getSession();
Criteriacrt= session.createCriteria(BookInfo.class);
crt.setProjection(Projections.projectionList().add(Projections.property("bookName")).add(Projections.property("bookAuthor")));
crt.add(Restrictions.eq("bookId",1));
crt.add(Restrictions.ilike("bookName","花", MatchMode.ANYWHERE));
// ilike 忽略大小写
System.out.println(crt.list());
System.out.println(crt.uniqueResult());
// 返回结果:
// [[Ljava.lang.Object;@17d919b6]
// [Ljava.lang.Object;@7283d3eb
}
}
----------------------------------------------------------------------------
4:命名SQL查询
public classTestNamedQuery {
/**
* 查询所有对象
* 2017年4月14日
* void
* testQueryAll
*/
@Test
public void testQueryAll(){
Sessionsession= HibernateSessionFactory.getSession();
Queryquery= session.getNamedQuery("selectAll");
query.setInteger("bookId",2);
System.out.println(query.list());
// 返回结果
// [com.hb.demo.pojo.BookInfo@5495333e]
}
/**
* 查询所有对象
* 2017年4月14日
* void
* testSQLQuery
*/
@Test
public void testSQLQuery(){
Sessionsession= HibernateSessionFactory.getSession();
SQLQueryquery= (SQLQuery)session.getNamedQuery("selectSqlAll");
query.addEntity(BookInfo.class);
System.out.println(query.list());
// 返回结果
// [com.hb.demo.pojo.BookInfo@61eaec38,com.hb.demo.pojo.BookInfo@31920ade,
// com.hb.demo.pojo.BookInfo@1d483de4,com.hb.demo.pojo.BookInfo@4032d386]
}
}
一:一对一映射
1:主键关联
注意: 1:<one-to-one name="card"class="com.relational.onetoone_primary.IDCard" /> Person.hbm.xml
2:<generatorclass="foreign"> IDcard.hbm.xml
<paramname="property">person</param>
</generator>
constrained="true"
IDCard表和Person表存在外键关系
one-to-one的单向关联中,如果constrained=false,则会在查询时就全部取出来,用left outer join的方式。
如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。
cascade="all"
all : 所有情况下均进行关联操作。
none:所有情况下均不进行关联操作。这是默认值。
save-update:在执行save/update/saveOrUpdate时进行关联操作。
delete:在执行delete时进行关联操作。
3:<one-to-onename="person" class="com.relational.onetoone_primary.Person"cascade="all" constrained="true" />
2:外键关联
默认情况下,把被关联实体主键字段作为关联字段。
有了property-ref,就可以通过它指定被关联实体主键以外的字段作为关联字段。
property-ref="person" card表和person表建立外键关系
注意:1:<one-to-onename="card" class="com.relational.onetoone_foreign.IDCard"property-ref="person" />Person.hbm.xml
2:<many-to-one name="person"class="com.relational.onetoone_foreign.Person"unique="true"> IDcard.hbm.xml
<columnname="person_id" unique="true" />
</many-to-one>
二:多对一映射
注意: 1: privateInteger deptId;
privateString deptName;
privateSet<Emp> emps = newHashSet<Emp>();
2: private Integer empId;
privateString empName;
privateDept dept;
Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,
但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。
3: <set name="emps"inverse="true">
<key>
<columnname="DEPT_ID" />
</key>
<one-to-manyclass="Emp" />
</set>
join方式,主体对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询
4: <many-to-onename="dept" class="Dept" fetch="join">
<columnname="DEPT_ID" />
</many-to-one>
三:多对多映射
注意: 1: privateInteger stuId;
privateString stuname;
privateSet teas = new HashSet(0);
2: private Integer teaId;
privateString teaname;
privateSet stus = new HashSet(0);
3: <set name="teas"table="TEA_STU" inverse="false" lazy="true">
<key>
<columnname="STU_ID" />
</key>
<many-to-manyclass="com.relational.manytomany.Tea">
<columnname="TEA_ID" />
</many-to-many>
</set>
4:<set name="stus" table="TEA_STU"inverse="false" lazy="true">
<key>
<columnname="TEA_ID" />
</key>
<many-to-manyclass="com.relational.manytomany.Stu">
<columnname="STU_ID" />
</many-to-many>
</set>
四:JPA注解映射
1: @Table(name = "dpetInfo") // 指定数据中生成表名
@Entity(name="DeptInfo")// 指定对象查询过程中使用对象名
publicclass Dept {
privateInteger deptId;
privateString deptName;
privateSet<Emp> emps = newHashSet<Emp>();
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
publicInteger getDeptId() {
returndeptId;
}
publicvoid setDeptId(Integer deptId) {
this.deptId= deptId;
}
@Column(name="dname")
publicString getDeptName() {
returndeptName;
}
publicvoid setDeptName(String deptName) {
this.deptName= deptName;
}
@OneToMany(mappedBy="dept")
publicSet<Emp> getEmps() {
returnemps;
}
publicvoid setEmps(Set<Emp> emps) {
this.emps= emps;
}
}
表名一样,只配一个entity即可
2: @Entity
publicclass Emp {
privateInteger empId;
privateString empName;
privateDept dept;
@Id
@Column(name= "emp_id")
@GeneratedValue(strategy=GenerationType.AUTO)
publicInteger getEmpId() {
returnempId;
}
publicvoid setEmpId(Integer empId) {
this.empId= empId;
}
当属性名和列名相同时,@Column()可省略
publicString getEmpName() {
returnempName;
}
publicvoid setEmpName(String empName) {
this.empName= empName;
}
@ManyToOne
@JoinColumn(name="dept_id")
publicDept getDept() {
returndept;
}
publicvoid setDept(Dept dept) {
this.dept= dept;
}
}
7:一对一映射
sessionFactory util工具类
public classHibernateUtil {
private static SessionFactory sessionFactory;
// 使用本地线程对象管理Session对象
private final staticThreadLocal<Session>threadLocal =newThreadLocal<Session>();
// 保证满足第一个条件
static {
buildSessionFactory();
}
/**
* 定义构建SessionFactory对象的方法
*/
private static void buildSessionFactory() {
// 判断sessionFactory是否为空
if ( sessionFactory== null ) {
Configurationcfg= newConfiguration().configure();
ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
sessionFactory=cfg.buildSessionFactory(serviceRegistry);
}
}
/**
* 定义获取Session对象的方法
*/
public static Session getSession() {
// 从本地线程中获取Session对象
Sessionsession= threadLocal.get();
// 判断session为null需要把创建Session对象放到本地线程对象中
if ( session == null ) {
if (sessionFactory==null){
buildSessionFactory();
}
session = sessionFactory.openSession();
// 设置到本地线程中
threadLocal.set(session);
}
returnsession;
}
/**
* 定义关闭Session的方法
*/
public static void closeSession() {
// 从本地线程中获取Session对象
Sessionsession= threadLocal.get();
if (session !=null &&session.isConnected()) {
session.close();
session = null;
threadLocal.set(null);
}
}
}
1:外键共享
a:hibernate.cfg.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<!-- 关联一对一映射文件 -->
<!-- <mapping resource="com/relational/onetoone_primary/Person.hbm.xml"/>
<mapping resource="com/relational/onetoone_primary/IDCard.hbm.xml"/>
</session-factory>
</hibernate-configuration>
b:创建实体:
private Integerid;
private Stringnumber;
private Person person;
private Integerid;
private Stringname;
private IDCard card;
c:配置实体映射文件
Person.hbm.xml
<hibernate-mapping>
<classname="com.relational.onetoone_primary.Person"table="PERSON">
<idname="id"type="java.lang.Integer">
<columnname="ID"/>
<generatorclass="native"/>
</id>
<propertyname="name"type="java.lang.String">
<columnname="NAME"/>
</property>
<one-to-onename="card"class="com.relational.onetoone_primary.IDCard"/>
</class>
</hibernate-mapping>
IDCard.hbm.xml
<hibernate-mapping>
<classname="com.relational.onetoone_primary.IDCard"table="IDCARD">
<idname="id"type="java.lang.Integer">
<columnname="ID"/>
<!-- IDCARD中主键的值由Person表的主键值提供 -->
<generatorclass="foreign">
<paramname="property">person</param>
</generator>
</id>
<propertyname="number"type="java.lang.String">
<columnname="NUMBER"/>
</property>
<!--
constrained="true"IDCard表和Person表存在外键关系(设置cascade="all"级联后,只需要设置调用副表的添加方法session.save(card);即可)
-->
<one-to-onename="person"class="com.relational.onetoone_primary.Person"cascade="all"constrained="true"/>
</class>
</hibernate-mapping>
d: TestRelational测试
public classTestRelational {
@Test
public void testOneToOne() {
System.out.println(HibernateUtil.getSession());
}
@Test
public void testAdd() {
Sessionsession= HibernateUtil.getSession();
// 创建一个人
Personperson= newPerson();
person.setName("张文娜1");
// 创建一个身份证对象
IDCardcard= newIDCard();
card.setNumber("500335198810167423");
// 设置关系
person.setCard(card);
card.setPerson(person);
// 开启事务
session.beginTransaction();
// 保存操作
session.save(card);
session.getTransaction().commit();
}
@Test
public void testQuery() {
Sessionsession= HibernateUtil.getSession();
//(注意两种查询存在的区别)懒加载
//1:如果查询子表的字段时,不会去查询副表
//2:如果查询父表的字段,那么也会关联查询所有的子表信息
Personperson= (Person) session.load(Person.class, 2);
System.out.println(person.getName()+"--"+person.getCard().getNumber());
IDCardcard= (IDCard) session.load(IDCard.class, 1);
System.out.println(card.getNumber()+"---"+card.getPerson().getName());
}
}
2:外键关联
a: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<!-- 关联一对一映射文件 -->
<mapping resource="com/relational/onetoone_foreign/Person.hbm.xml"/>
<mapping resource="com/relational/onetoone_foreign/IDCard.hbm.xml"/>-->
</session-factory>
</hibernate-configuration>
b:创建实体:
private Integerid;
private Stringnumber;
private Person person;
private Integerid;
private Stringname;
private IDCard card;
c:配置实体映射文件
Person.hbm.xml
<hibernate-mapping>
<classname="com.relational.onetoone_foreign.Person"table="PERSON1">
<idname="id"type="java.lang.Integer">
<columnname="ID"/>
<generatorclass="native"/>
</id>
<propertyname="name"type="java.lang.String">
<columnname="NAME"/>
</property>
<!--
property-ref="person"card表和person表建立外键关系
-->
<one-to-onename="card"class="com.relational.onetoone_foreign.IDCard"property-ref="person"/>
</class>
</hibernate-mapping>
IDCard.hbm.xml
<hibernate-mapping>
<classname="com.relational.onetoone_foreign.IDCard"table="IDCARD1">
<idname="id"type="java.lang.Integer">
<columnname="ID"/>
<generatorclass="native"/>
</id>
<propertyname="number"type="java.lang.String">
<columnname="NUMBER"/>
</property>
<many-to-onename="person"class="com.relational.onetoone_foreign.Person"unique="true">
<columnname="person_id"unique="true"/>
</many-to-one>
</class>
</hibernate-mapping>
d: TestRelational测试
public classTestRelational {
@Test
public void testOneToOne() {
System.out.println(HibernateUtil.getSession());
}
@Test
public void testAdd() {
Sessionsession= HibernateUtil.getSession();
// 创建一个人
Person person = new Person();
person.setName("张文娜1");
// 创建一个身份证对象
IDCardcard= newIDCard();
card.setNumber("500335198810167423");
// 设置关系
person.setCard(card);
card.setPerson(person);
// 开启事务
session.beginTransaction();
// 保存操作
session.save(person);
session.save(card);
session.getTransaction().commit();
}
@Test
public void testQuery() {
Sessionsession= HibernateUtil.getSession();
Personperson= (Person) session.load(Person.class, 1);
System.out.println(person.getName()+"--"+person.getCard().getNumber());
IDCardcard= (IDCard) session.load(IDCard.class, 1);
System.out.println(card.getNumber()+"---"+card.getPerson().getName());
}
}
----------------------------------------------------------------------------
8:多对一映射
a: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<!-- 关联多对一映射文件 -->
<mapping resource="com/relational/onetomany/Dept.hbm.xml"/>
<mapping resource="com/relational/onetomany/Emp.hbm.xml"/>
</session-factory>
</hibernate-configuration>
b:创建Dept、Emp实体
private IntegerdeptId;
private StringdeptName;
private Set<Emp> emps = new HashSet<Emp>();
private IntegerempId;
private StringempName;
private Dept dept;
c: 配置实体映射文件
Dept.hbm.xml
<hibernate-mappingpackage="com.relational.onetomany">
<classname="Dept"table="dept">
<idname="deptId"type="java.lang.Integer">
<columnname="DEPT_ID"/>
<generatorclass="native"/>
</id>
<propertyname="deptName"type="java.lang.String">
<columnname="DEPT_NAME"/>
</property>
<setname="emps"inverse="true">
<key>
<columnname="DEPT_ID"/>
</key>
<one-to-manyclass="Emp"/>
</set>
</class>
</hibernate-mapping>
Emp.hbm.xml
<hibernate-mappingpackage="com.relational.onetomany">
<classname="Emp"table="emp"catalog="hibernate">
<idname="empId"type="java.lang.Integer">
<columnname="EMP_ID"/>
<generatorclass="native"/>
</id>
<many-to-onename="dept"class="Dept"fetch="join">
<columnname="DEPT_ID"/>
</many-to-one>
<propertyname="empName"type="java.lang.String">
<columnname="EMP_NAME"/>
</property>
</class>
</hibernate-mapping>
d: TestRelational测试
public classTestRelational {
@Test
public void testManyToOne() {
System.out.println(HibernateUtil.getSession());
}
@Test
public void testAdd() {
Sessionsession= HibernateUtil.getSession();
// 创建一个部门
Deptdept= newDept();
dept.setDeptName("开发部");
// 创建2个员工
Empemp1= newEmp();
emp1.setEmpName("张三");
Empemp2= newEmp();
emp2.setEmpName("王五");
// 设置关系
emp1.setDept(dept);
emp2.setDept(dept);
// 开启事务
session.beginTransaction();
session.save(dept);
session.save(emp1);
session.save(emp2);
session.getTransaction().commit();
}
@Test
public void query() {
Sessionsession= HibernateUtil.getSession();
Deptdept= (Dept) session.get(Dept.class, 2);
System.out.println(dept.getDeptName());
System.out.println(dept.getEmps());
}
}
----------------------------------------------------------------------------
9:多对多映射
a: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<!-- 关联多对一映射文件 -->
<mapping resource="com/relational/manytomany/Stu.hbm.xml"/>
<mappingresource="com/relational/manytomany/Tea.hbm.xml"/>
</session-factory>
</hibernate-configuration>
b:创建Stu、Tea实体
private IntegerstuId;
private Stringstuname;
private Setteas =new HashSet(0);
public Stu() {
}
public Stu(Teatea, Stringstuname, Setteas) {
this.stuname =stuname;
this.teas =teas;
}
private IntegerteaId;
private Stringteaname;
private Setstus =new HashSet(0);
public Tea() {
}
public Tea(Stustu, Stringteaname, Setstus) {
this.teaname =teaname;
this.stus =stus;
}
c: 配置实体映射文件
Stu.hbm.xml
<hibernate-mapping>
<classname="com.relational.manytomany.Stu"table="STU">
<idname="stuId"type="java.lang.Integer">
<columnname="STUID"/>
<generatorclass="native"/>
</id>
<propertyname="stuname"type="java.lang.String">
<columnname="STUNAME"/>
</property>
<setname="teas"table="TEA_STU"inverse="false"lazy="true">
<key>
<columnname="STU_ID"/>
</key>
<many-to-manyclass="com.relational.manytomany.Tea">
<columnname="TEA_ID"/>
</many-to-many>
</set>
</class>
</hibernate-mapping>
Tea.hbm.xml
<hibernate-mapping>
<classname="com.relational.manytomany.Tea"table="TEA">
<idname="teaId"type="java.lang.Integer">
<columnname="TEAID"/>
<generatorclass="native"/>
</id>
<propertyname="teaname"type="java.lang.String">
<columnname="TEANAME"/>
</property>
<setname="stus"table="TEA_STU"inverse="false"lazy="true">
<key>
<columnname="TEA_ID"/>
</key>
<many-to-manyclass="com.relational.manytomany.Stu">
<columnname="STU_ID"/>
</many-to-many>
</set>
</class>
</hibernate-mapping>
d: TestRelational测试
public classTestRelational {
@Test
public void testManyToMany() {
System.out.println(HibernateUtil.getSession());
}
}
----------------------------------------------------------------------------
10:JPA注解实现多对一映射
a: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<mappingclass="com.relational.jpa.Dept"/>
<mappingclass="com.relational.jpa.Emp"/>
</session-factory>
</hibernate-configuration>
b:两个实体的注解
Dept
@Table(name= "dpetInfo") // 指定数据中生成表名
@Entity(name="DeptInfo")//指定对象查询过程中使用对象名
public classDept {
private IntegerdeptId;
private StringdeptName;
private Set<Emp>emps =new HashSet<Emp>();
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getDeptId() {
returndeptId;
}
public void setDeptId(Integer deptId) {
this.deptId =deptId;
}
@Column(name="dname")
public String getDeptName() {
returndeptName;
}
public void setDeptName(String deptName) {
this.deptName =deptName;
}
@OneToMany(mappedBy="dept")
public Set<Emp>getEmps() {
returnemps;
}
public void setEmps(Set<Emp> emps) {
this.emps =emps;
}
}
Emp
@Entity
public classEmp {
private IntegerempId;
private StringempName;
private Deptdept;
@Id
@Column(name = "emp_id")
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getEmpId() {
returnempId;
}
public void setEmpId(Integer empId) {
this.empId =empId;
}
public String getEmpName() {
returnempName;
}
public void setEmpName(String empName) {
this.empName =empName;
}
@ManyToOne
@JoinColumn(name="dept_id")
public Dept getDept() {
returndept;
}
public void setDept(Dept dept) {
this.dept =dept;
}
}
c: TestRelational测试
public classTestRelational {
@Test
public voidtestManyToOneInjection() {
System.out.println(HibernateUtil.getSession());
}
}
----------------------------------------------------------------------------
11:缓存(懒加载、一级缓存、二级缓存)
HibernateUtil
/**
* 1、保证一个数据库对应一个SessionFactory对象
* 2、保证在同一客户端用户使用同一个Session对象
* @author Administrator
*
*/
public classHibernateUtil{
private static SessionFactory sessionFactory;
// 使用本地线程对象管理Session对象
private final staticThreadLocal<Session>threadLocal =newThreadLocal<Session>();
// 保证满足第一个条件
static {
buildSessionFactory();
}
/**
* 定义构建SessionFactory对象的方法
*/
private static void buildSessionFactory() {
// 判断sessionFactory是否为空
if ( sessionFactory== null ) {
Configurationcfg= newConfiguration().configure();
ServiceRegistryserviceRegistry=newStandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
sessionFactory=cfg.buildSessionFactory(serviceRegistry);
}
}
/**
* 定义获取Session对象的方法
*/
public static Session getSession() {
// 从本地线程中获取Session对象
Sessionsession= threadLocal.get();
// 判断session为null需要把创建Session对象放到本地线程对象中
if ( session == null ) {
if (sessionFactory==null){
buildSessionFactory();
}
session = sessionFactory.openSession();
// 设置到本地线程中
threadLocal.set(session);
}
returnsession;
}
/**
* 定义关闭Session的方法
*/
public static void closeSession() {
// 从本地线程中获取Session对象
Sessionsession= threadLocal.get();
if (session !=null &&session.isConnected()) {
session.close();
session = null;
threadLocal.set(null);
}
}
}
1:懒加载
a: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1?userUnicode=true&characterEncoding=utf-8</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<mappingclass="com.hb.demo.pojo.CarInfo"/>
<mappingclass="com.hb.demo.pojo.TypeInfo"/>
</session-factory>
</hibernate-configuration>
b: TypeInfo
@Table(name= "typeInfo") // 指定数据中生成表名
@Entity(name="TypeInfo")//指定对象查询过程中使用对象名
public classTypeInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID= 1L;
private IntegertypeId;
private StringtypeName;
private Set<CarInfo>cars =new HashSet<>();
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getTypeId() {
returntypeId;
}
public void setTypeId(Integer typeId) {
this.typeId =typeId;
}
public String getTypeName() {
returntypeName;
}
public void setTypeName(String typeName) {
this.typeName =typeName;
}
@OneToMany(mappedBy="type")
public Set<CarInfo>getCars() {
returncars;
}
public voidsetCars(Set<CarInfo> cars) {
this.cars =cars;
}
}
c: CarInfo
@Entity
public classCarInfo implementsSerializable{
/**
*
*/
private static final long serialVersionUID= 1L;
private Integerid;
private Stringname;
private Stringcolor;
private TypeInfotype;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
returnid;
}
public void setId(Integer id) {
this.id =id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name =name;
}
public String getColor() {
returncolor;
}
public void setColor(String color) {
this.color =color;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="type_id")
public TypeInfo getType() {
returntype;
}
public void setType(TypeInfo type) {
this.type =type;
}
}
d: TestLazy
/**
* 延迟加载:需要使用对象的时候才会通过数据库生成的代理查询数据
* load : 支持懒加载的
* get : 不支持懒加载,及时加载
* @authorliang
*
*/
public classTestLazy {
@Test
public voidtestManyToOneInjection() {
System.out.println(HibernateUtil.getSession());
}
/*@Test
publicvoid testAdd() {
TypeInfoinfo1 = new TypeInfo();
info1.setTypeName("手动挡");
TypeInfoinfo2 = new TypeInfo();
info2.setTypeName("自动挡");
TypeInfoinfo3 = new TypeInfo();
info3.setTypeName("全自动挡");
try{
Sessionsession = HibernateUtil.getSession();
session.beginTransaction();
session.persist(info1);
session.persist(info2);
session.persist(info3);
session.getTransaction().commit();
}catch (Exception e) {
}
}*/
@Test
public void testGet(){
Sessionsession= HibernateUtil.getSession();
CarInfocarInfo= (CarInfo)session.get(CarInfo.class, 2);//打印sql语句
// HibernateUtil.closeSession();
System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());
}
@Test
public void testLoad(){
Sessionsession= HibernateUtil.getSession();
CarInfocarInfo= (CarInfo)session.load(CarInfo.class, 2);
// HibernateUtil.closeSession();
System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());//打印sql语句
}
}
2:一级缓存
a: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<mappingclass="com.hb.demo.pojo.CarInfo"/>
<mappingclass="com.hb.demo.pojo.TypeInfo"/>
</session-factory>
</hibernate-configuration>
b: TypeInfo
@Table(name= "typeInfo") // 指定数据中生成表名
@Entity(name="TypeInfo")//指定对象查询过程中使用对象名
public classTypeInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID= 1L;
private IntegertypeId;
private StringtypeName;
private Set<CarInfo>cars =new HashSet<>();
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getTypeId() {
returntypeId;
}
public void setTypeId(Integer typeId) {
this.typeId =typeId;
}
public String getTypeName() {
returntypeName;
}
public void setTypeName(String typeName) {
this.typeName =typeName;
}
@OneToMany(mappedBy="type")
public Set<CarInfo>getCars() {
returncars;
}
public voidsetCars(Set<CarInfo> cars) {
this.cars =cars;
}
}
C: CarInfo
@Entity
public classCarInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID= 1L;
private Integerid;
private Stringname;
private Stringcolor;
private TypeInfotype;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
returnid;
}
public void setId(Integer id) {
this.id =id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name =name;
}
public String getColor() {
returncolor;
}
public void setColor(String color) {
this.color =color;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="type_id")
public TypeInfo getType() {
returntype;
}
public void setType(TypeInfo type) {
this.type =type;
}
}
d: TestCache
/**
* 一级缓存:
* 1:Session级缓存
* 2:不同session之间不能实现共享
* 3:不可卸载的,Hibernate自带的
*
* 缺点:命中率低
*
* 解释: 1:如果查询的数据所对应的oid在session中存在,就使用session缓存中的对象
* 2:如果不存在,从数据库中进行查询
* @authorliang
*
*/
public classTestCache {
@Test
public voidtestManyToOneInjection() {
System.out.println(HibernateUtil.getSession());
}
/*@Test
publicvoid testGet(){
Sessionsession = HibernateUtil.getSession();
CarInfocarInfo = (CarInfo) session.get(CarInfo.class, 2);//打印sql语句
// HibernateUtil.closeSession();
System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());
}
@Test
publicvoid testLoad(){
Sessionsession = HibernateUtil.getSession();
CarInfocarInfo = (CarInfo) session.load(CarInfo.class, 2);//打印sql语句
// HibernateUtil.closeSession();
System.out.println(carInfo.getName()+""+carInfo.getType().getTypeName());
}*/
// 三种清空session方式
@Test
public void testFirstCache(){
Sessionsession= HibernateUtil.getSession();
CarInfocarInfo1= (CarInfo)session.get(CarInfo.class, 3);
session.clear();//清空session中所有的缓存
CarInfocarInfo2= (CarInfo)session.get(CarInfo.class, 3);
session.evict(carInfo2);//清空session中指定的缓存对象
CarInfocarInfo3= (CarInfo)session.get(CarInfo.class, 3);
// session.close();
System.out.println(carInfo1.getName()+""+carInfo1.getType().getTypeName());
System.out.println(carInfo2.getName()+""+carInfo2.getType().getTypeName());
System.out.println(carInfo3.getName()+""+carInfo3.getType().getTypeName());
}
@SuppressWarnings("unchecked")
@Test
public void testFirstCache1(){
Sessionsession= HibernateUtil.getSession();
List<CarInfo>list1= session.createCriteria(CarInfo.class).list();
List<CarInfo>list2= session.createCriteria(CarInfo.class).list();
List<CarInfo>list3= session.createCriteria(CarInfo.class).list();
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
}
}
3:二级缓存
a:导入ehcache必备的包
B: hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="hibernate.connection.password">root</property>
<propertyname="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate1</property>
<propertyname="hibernate.connection.username">root</property>
<!-- 配置数据的方言 -->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置额外属性 -->
<propertyname="format_sql">true</property>
<propertyname="show_sql">true</property>
<!-- 配置正向生成数据中的表 -->
<propertyname="hbm2ddl.auto">update</property>
<!-- 配置二级缓存高速缓存提供类 -->
<propertyname="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
<!-- 开启二级缓存 -->
<propertyname="hibernate.cache.use_second_level_cache">true</property>
<!-- 开启查询缓存 -->
<propertyname="hibernate.cache.use_query_cache">true</property>
<mappingclass="com.hb.demo.pojo.CarInfo"/>
<mappingclass="com.hb.demo.pojo.TypeInfo"/>
</session-factory>
</hibernate-configuration>
C: TypeInfo
@Table(name= "typeInfo") // 指定数据中生成表名
@Entity(name="TypeInfo")//指定对象查询过程中使用对象名
@Cache(usage= CacheConcurrencyStrategy.READ_ONLY)//配置缓存策略
public classTypeInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID= 1L;
private IntegertypeId;
private StringtypeName;
private Set<CarInfo>cars =new HashSet<>();
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getTypeId() {
returntypeId;
}
public void setTypeId(Integer typeId) {
this.typeId =typeId;
}
public String getTypeName() {
returntypeName;
}
public void setTypeName(String typeName) {
this.typeName =typeName;
}
@OneToMany(mappedBy="type")
public Set<CarInfo>getCars() {
returncars;
}
public voidsetCars(Set<CarInfo> cars) {
this.cars =cars;
}
}
D: CarInfo
@Entity
@Cache(usage= CacheConcurrencyStrategy.READ_ONLY)//配置缓存策略
public classCarInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID= 1L;
private Integerid;
private Stringname;
private Stringcolor;
private TypeInfotype;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
returnid;
}
public void setId(Integer id) {
this.id =id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name =name;
}
public String getColor() {
returncolor;
}
public void setColor(String color) {
this.color =color;
}
@ManyToOne
@JoinColumn(name="type_id")
public TypeInfo getType() {
returntype;
}
public void setType(TypeInfo type) {
this.type =type;
}
}
E: TestSecondCache
/**
* 二级缓存:
* 1:sessionFactory缓存
* 2:插拔式缓存
* 3:修改少,不是重要数据
*
* 二级缓存配置步骤
* 1:使用EhCache插件
* 2: 在resource里面添加ehcache.xml配置文件
* 3:在hibernate的配置文件中配置缓存类提供类
* a:开启二级缓存
* b:开启查询缓存
* 4:配置缓存策略
* @authorliang
*
*/
public classTestSecondCache{
@Test
public voidtestManyToOneInjection() {
System.out.println(HibernateUtil.getSession());
}
@SuppressWarnings("unchecked")
@Test
public void testSecondCache(){
Sessionsession1= HibernateUtil.getSession();
List<CarInfo>list1= session1.createCriteria(CarInfo.class).setCacheable(true).list();
HibernateUtil.closeSession();
Sessionsession2= HibernateUtil.getSession();
List<CarInfo>list2= session2.createCriteria(CarInfo.class).setCacheable(true).list();
HibernateUtil.closeSession();
Sessionsession3= HibernateUtil.getSession();
List<CarInfo>list3= session3.createCriteria(CarInfo.class).setCacheable(true).list();
HibernateUtil.closeSession();
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
}
@SuppressWarnings("unchecked")
@Test
public void testSecondCache1(){
Sessionsession1= HibernateUtil.getSession();
List<CarInfo>list1= session1.createQuery("FROM CarInfo").setCacheable(true).list();
System.out.println(list1);
}
}
- hibernate4
- Hibernate4
- Hibernate4
- hibernate4
- Hibernate4
- hibernate4
- hibernate4
- hibernate4
- Hibernate4
- hibernate4-过程
- Hibernate4 Listener
- Hibernate4详解
- hibernate4例子
- Hibernate4例子
- hibernate4 basedao
- Hibernate4学习
- Hibernate4 + ehcache
- hibernate4二级缓存
- CSS实现背景透明,文字不透明
- HTML 如何避免页面卡顿
- Ignite使用小记
- 随机数组不重复
- chapter5——打印杨辉三角形
- hibernate4
- bookStore第三篇【用户模块、购买模块、订单模块】
- 1012. 数字分类 (20)
- BZOJ2251 外星联络 (Trie树)
- lua中对table的排序
- 一些常用Java操作方法封装:Java Utils
- 51nod 1002 数塔取数问题
- c#编程积累
- 小程序无网络状态时不刷新提示信息