hibernate中文教程

2 篇文章 0 订阅
1 篇文章 0 订阅

hibernate

概述

hibernate是一个ORM框架,ORM指的是对象关系映射,因为java程序中使用的是面向对象模型,而关系型数据库使用的是关系模型,这两种模式是不匹配的。所以在使用JDBC操作数据库时需要手动的进行两种模型的转换,有了ORM框架之后可以让ORM框架来完成两种模型的转换,我们只需要给出对应的映射就可以了,映射可以是XML或者注解。

说明:除了hibernate还有很多其他的ORM框架,很多ORM框架都是JPA的实现,包括OpenJPA、EclipseLink

​ POJO

POJO - Plain Ordinary Java Object

PO POJO+Annotation/XML

PO - Persistent Object

​ 在pom.xml中添加依赖项

配置
	<dependency>
	    <groupId>org.hibernate</groupId>
	    <artifactId>hibernate-core</artifactId>
	    <version>5.2.10.Final</version>
	</dependency>
	<dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>5.1.38</version>
	</dependency>

​ 在类路径下添加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>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql:///hibernate?useUnicode=true&amp;characterEncoding=utf8                
       </property>
        <property name="connection.username">root</property>
        <property name="connection.password">lcw123</property>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
        <!-- SQL方言   MySQL57代表mysql版本5.7 -->
        <property name="dialect">org.hibernate.dialect.MySQL57Dialect</property>
        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider
        </property>
        <!-- Echo all executed SQL to stdout -->					
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <!--<property name="hbm2ddl.auto">update</property>   正向工程,根据实体自动对象建表-->
        <mapping class="com.lcw666.domain.hibernate.User"/> 
    </session-factory>
</hibernate-configuration>
映射实体类(通过注解的方式)
/*  如果需要建表时的写法,可以在 @Column在添加约束
@Entity 
@Table(name="tb_user")  
public class User implements Serializable{
    @Id
    @Column(length=20)
	private String username;
	@Column(name="userpass",length=20,nullable=false)
	private String password;
    @Column(unique=true)
	private String email;	*/
    
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tb_user")
public class User implements Serializable {
	@Id
	@Column(name = "userid")
	@GeneratedValue(strategy = GenerationType.IDENTITY) // 映射主键生成策略
	private Integer id;
	private String username;
	@Column(name = "userpass")
	private String password;
	private String email; 
    //getter and setter
}

映射实体类(通过xml配置的方式)

import java.io.Serializable;
public class User implements Serializable {
	private String id;
	private String username;
	private String password;
	private String email;
    //getter and setter
}

实体映射文件-User.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.lcw666.hibernate.domain">

    <class name="User1" table="tb_user1">
        <id name="id" column="userid">
            <generator class="uuid"/> //生成id的策略-uuid、increment、native等
        </id>
        <property name="username"/>
        <property name="password" column="userpass"/>
        <property name="email"/>
    </class>

</hibernate-mapping>

对实体类的要求:

  • 实体类不能用final修饰

  • 实体类实现Serializable接口

  • 实体类的属性最好不要使用基本数据类型

  • 保留无参构造器

  • 必须有ID属性

操作

通过hibernate来实现增删改查操作

public class AppTest{

	@Test
	public void testSave() {
		User user = new User();
		user.setUsername("lll");
		user.setPassword(DigestUtils.md5Hex("123123"));
		user.setEmail("lcww@qq.com");
		Session session = HibernateUtil.getSession();
		try {
			session.beginTransaction();
			Serializable key = session.save(user);
			Assert.assertNotNull(key);
			System.out.println(key);
			session.getTransaction().commit();
		} catch (Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally {
			session.close();
		}
	}
	@Test
	public void testGet() {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		User user = session.get(User.class, 1);
	
		session.getTransaction().commit();
		session.close();
		Assert.assertNotNull(user);
	}
	@Test
	public void testGetByUsername() {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		User user = session.createQuery("from User as u where u.username=:username", User.class).setParameter("username", "lll").getSingleResult(); //如果找不到username,则抛出异常,而不是返回null
		//Assert.assertNotNull(user); 
		System.out.println(user.getEmail());
		
		//正确的做法
		List<User> userList = session.createQuery("from User as u where u.username=:username", User.class).setParameter("username", "lfll").getResultList();  //如果找不到username,返回空集合
		/*List<User> userList = session.createQuery("from User as u where                                                                          u.username=:username", User.class)
                   .setParameter("username", "lfll")
                   .setFirstResult(0)
				  .setMaxResults(5)
                   .getResultList();  //分页查询,从第0条开始查,一次最大查5条记录   */	
	    Assert.assertEquals(0, userList.size());
		session.getTransaction().commit();
		session.close();
		
	}
	@Test
	public void testDelete() {   //根据主键删除
//		User user = new User();
//		user.setId(1);  不安全,如要要删除的对象不存在,则抛出异常
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		
		User user = session.get(User.class, 3);
		if (user!=null) {
			session.delete(user);
		}
		//session.remove(user); 和delete一样
		session.getTransaction().commit();
		session.close();
	}
	@Test
	public void testDeleteByUsername() { //根据用户名删除
		
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		int affectedRows = session.createQuery("delete from User as u where u.username = :uid")
		                 .setParameter("uid", "ll").executeUpdate();
		Assert.assertEquals(0, affectedRows);
		session.getTransaction().commit();
		session.close();
	}
}

类和类之间的继承关系和关联关系可以映射到关系型数据库中

继承映射

关联映射

一对一

一对多

多对多


其他
  1. 清理一级缓存

    一级缓存:Session里面容器保存的内容

    • Session.clear();
    • Session.evict(obj); 清理某个对象
  2. hibernate中的对象状态

    • 瞬时态(transient)- 创建一个对象,Session中没有缓存该对象,数据库中也没有与之对应的记录,此时对象处于瞬时态,瞬时态对象通过Session的save、savaOrUpdate、persist方法可以变成持久态。
    • 持久态(persistent)- 如果数据库中持有对象对应的记录,而且对象被纳入一级缓存(session)中,此时对象处于持久态,持久态的对象直接调用对象的setter方法就可以完成更新操作,不需要调用Session对象的update方法,持久态对象通过调用Session的evict、clear、close方法变成游离态,通过调用对象的delete或者remove方法会变成瞬时态(删除态)。
    • 游离态(detached)/脱管态 - 如果对象在数据库中有之对应的记录,但是Session中没有改对象(脱离了一级缓存的管理),此时对象处于游离态,如果希望对象从游离态回到持久态可以使用update方法。如果希望对象更新对象但又不让对象回到持久态应该使用merge方法,而不是update。
  3. hibernate锁

    悲观锁

​ 所谓悲观锁就是悲观的认为并发数据访问的冲突会经常性的发生,所以需要将数据锁住避免发生数据读写问题。

下面get方法的第三个参数用来设置悲观锁

Dept dept = session.get(Dept.class, 1,LockMode.PESSIMISTIC_READ);
  • LockMode.PESSIMISTIC_READ - 我读的时候他人可以读不能写

  • LockMode.PESSIMISTIC_WRITE - 我写的时候他人可以读不能写

悲观锁需要锁定行或者表,这就意味着没有并发,所以性能较差。

乐观锁

​ 乐观的认为并发数据访问冲突不会经常性的发生,如果发生了也不要紧,通过版本号来确定是否能够进行写数据的操作.

在实际开发中尽量使用乐观锁来替代悲观锁的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值