Hibernate 注解

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本人声明。否则将追究法律责任。
作者: 永恒の_☆ 地址: http://blog.csdn.net/chenghui0317/article/details/8392980

一、介绍

    在以前弄hibernate的时候,每创建一个数据库表都要在entity下 新建对应的*.hbm.xml 配置文件,当数据库表很多之后就会严重影响开发效率和维护成本,所以 就有了注解,原理在于 省去之前繁琐的配置文件,取代的是在实体类中加上以“@”开头的标记,命名为 注解,待会一一解释其中含义。


二、准备

jar 文件:

   hibernate-core-3.3.2.GA.jar

   ejb3-persistence-1.0.2.GA.jar

   hibernate-annotations-3.4.0.GA.jar

   hibernate-commons-annotations-3.1.0.GA.jar

   javassist-3.11.0.GA.jar

  (缺一不可)


三、实现

   既然要使用注解,那么在entity 就不需要实体映射文件了,取而代之的是在实体类中加上很多标记,这些标记的使用效果和使用配置文件配置一样,因为在使用hibernate映射文件的时候是利用dom4j 解析的,同样使用注解的标记也是由程序去解析的,其具体效果会在程序中体现出来。常用的注解标记 如下:

   @Entity    标记为一个实体类,

   @Table   标记为该类与一个数据表绑定,哪个表,要在参数中体现出来,比如:@Table(name = "tb_film_info") ,相当于映射文件中的

<class name="FilmInfo" table="tb_film_info"></class>

   @Id    标记为Id,一般在主键出用到

   @SequenceGenerator   标记为序列,将改字段与数据库中的序列绑定,在这里指定序列值才行,如果不使用该标记绑定将使用hibernate默认的序列,相当于映射文件中的

<generator class="sequence"></generator>

   @GeneratedValue  标记为指定主键的生成策略,相当于映射文件的<param name="sequence">seq_film_info</param>

   @Column    标记为该字段与数据库字段绑定,如果不指定具体的字段值,将默认采用单词分割首字母大写的特点绑定,比如 字段是 fi_ticket_price 那么对应的属性值 应该是 fiTicketPrice ,相当于映射文件中的

       

         <property name="fiTicketPrice" type="java.lang.Double">
            <column name="fi_ticket_price" length="10" not-null="true">
         </column></property>

   @ManyToOne   标记为多对一的关联映射关系,需要指定映射的实体类即可,相当于映射文件的

        <many-to-one name="filmType" class="FilmType" >
            <column name="fi_film_type_id" not-null="true"></column>
        </many-to-one>

   @JoinColumn   标记为关联的外键,相当于映射文件的 <column name="fi_film_type_id" not-null="true"></column>

   @OneToMany   标记为一对多的关联映射关系,需要指定映射的实体类的级联方式等等,相当于映射文件的        <!-- 一个电影类型可以有多个电影详情,所以他们之间存在一对多的关联关系 -->

        <bag name="filmInfos" table="tb_film_info" cascade="all" inverse="true">
            <!-- 指定关联的字段,让字段作外键去关联 -->
            <key>
                <column name="fi_film_type_id" not-null="false"></column>
            </key>
            <!-- 指定关联的对象 -->
            <one-to-many class="FilmInfo"></one-to-many>
        </bag>

可见使用注解非常方便,省去了大部分繁琐的配置,从而节省了开发时间,提高了开发项目的效率。下面展示下两个简单的用到注解的实体类的例子,代码如下:

package com.hibernate.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


/**
 * 电影详情类
 * @author Administrator
 *
 */
@Entity  //标记为 数据库表
@Table(name = "tb_film_info")  // 指定该实体类映射的对应的数据库表名
public class FilmInfo implements Serializable{

	private static final long serialVersionUID = 1L;

	private Long fiId;
	private String fiName;
	private String fiActor;
	private String fiDirector;
	private Double fiTicketPrice;
	
	private FilmType filmType;
	
	@Id   //主键id
	@SequenceGenerator(name = "generator", sequenceName = "seq_film_info" )   //指定序列
	@GeneratedValue(generator = "generator", strategy = GenerationType.SEQUENCE) //指定主键生成策略   
	@Column(name = "fi_id")   //因为数据表中的结构都是以“_”分割,然后 hibernate默认识别方式没有以任何方式分割,所以每个列都要在getter()方法标记
	public Long getFiId() {
		return fiId;
	}
	public void setFiId(Long fiId) {
		this.fiId = fiId;
	}
	@Column(name = "fi_name")
	public String getFiName() {
		return fiName;
	}
	public void setFiName(String fiName) {
		this.fiName = fiName;
	}
	@Column(name = "fi_actor")
	public String getFiActor() {
		return fiActor;
	}
	public void setFiActor(String fiActor) {
		this.fiActor = fiActor;
	}
	@Column(name = "fi_director")
	public String getFiDirector() {
		return fiDirector;
	}
	public void setFiDirector(String fiDirector) {
		this.fiDirector = fiDirector;
	}
	@Column(name = "fi_ticket_price")
	public Double getFiTicketPrice() {
		return fiTicketPrice;
	}
	public void setFiTicketPrice(Double fiTicketPrice) {
		this.fiTicketPrice = fiTicketPrice;
	}
	@ManyToOne(fetch = FetchType.LAZY)  //多对一关联关系,采用@ManyToOne标记,指定下加载方式
	@JoinColumn(name = "fi_film_type_id")  //指定下 关联的外键 
	public FilmType getFilmType() {
		return filmType;
	}
	public void setFilmType(FilmType filmType) {
		this.filmType = filmType;
	}
}

package com.hibernate.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

/**
 * 电影类型类
 * @author Administrator
 *
 */
@Entity//标记为 数据库表
@Table(name = "tb_film_type")// 指定该实体类映射的对应的数据库表名  
public class FilmType implements Serializable{

	private static final long serialVersionUID = 1L;
	
	private Long ftId;
	private String ftName;

	private List<FilmInfo> filmInfos = new ArrayList<FilmInfo>();
	
	@Id
	@SequenceGenerator(name = "generator", sequenceName = "seq_film_type")
	@GeneratedValue(generator = "generator", strategy = GenerationType.SEQUENCE)
	@Column(name = "ft_id")
	public Long getFtId() {
		return ftId;
	}
	public void setFtId(Long ftId) {
		this.ftId = ftId;
	}
	@Column(name = "ft_name")
	public String getFtName() {
		return ftName;
	}
	public void setFtName(String ftName) {
		this.ftName = ftName;
	}
	
	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)   //一对多关联关系,指定级联方式
	@JoinColumn(name = "fi_film_type_id")   // 这里指定 tb_Film_info 表的主键id,和引用tb_film_type表的外键都可以。
	public List<FilmInfo> getFilmInfos() {
		return filmInfos;
	}
	public void setFilmInfos(List<FilmInfo> filmInfos) {
		this.filmInfos = filmInfos;
	}
	
}

基本就是这个样子,然后 以前使用映射文件配置的时候都要在hibernate.cfh.xml中 加上映射的配置,比如:

		<mapping resource="com/hibernate/entity/FilmInfo.hbm.xml"/>
		<mapping resource="com/hibernate/entity/FilmType.hbm.xml"/> 
那么用到注解之后 就不需要了。

另外以前使用hibernate映射文件配置获得SessionFactory 的方式是Configuration 的实例,但是使用hibernate注解之后要使用AnnotationConfiguration 的实例,如下:

/**
 * Hibernate Session Factory
 * @author Administrator
 *
 */
public class HibernateSessionFactory {

    static Session session = null;
    static SessionFactory sessionFactory = null;
    private static Logger logger = Logger.getLogger(HibernateSessionFactory.class);
    
    //第一次加载该类才会执行,仅仅一次
    static{
    /*  当使用的是entity.hbm.xml 映射文件时,就使用下面的方式读取配置文件
          Configuration configuration = new Configuration().configure();
        sessionFactory = configuration.buildSessionFactory();
    */
    /*  如果实体类使用的是注解完成的,就使用下面的方式完成读取配置信息*/
        AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration().configure();
        sessionFactory = annotationConfiguration.buildSessionFactory();
    }
    
    /**
     * 得到session对象的实例
     * @return
     */
    public static Session getSession(){
        session = sessionFactory.openSession();
        logger.info("get this session case.");
        return session;
    }
    
    /**
     * 释放所有资源,关闭session服务
     */
    public static void closeAll(){
        if(session!=null){
            session.close();
        }
        if(sessionFactory!=null){
            sessionFactory.close();
        }
        logger.info("close this session.");
    }
    
}

接下来在Junit 测试环境中演示一下:

0、获取FileInfo 表中价格在100元以下的电影信息

	@Test
	public void test00() {
		Session session = HibernateSessionFactory.getSession();
		Query query = session.createQuery("select info from FilmInfo info where info.fiTicketPrice <= 100");
		Iterator<FilmInfo> iterators = query.iterate();
		while(iterators.hasNext()){
			FilmInfo info = iterators.next();
			System.out.println("电影名 : " + info.getFiName() +" 价格:," + info.getFiTicketPrice());
		}
		HibernateSessionFactory.closeAll();
	}
在控制台显示的效果如下:



1、获取FileInfo 表中价格在100元以下的电影信息

	@Test
	public void test01() {
		Session session = HibernateSessionFactory.getSession();
		//获取id为4的电影信息,包括该电影的电影类型
		FilmInfo filmInfo = (FilmInfo) session.get(FilmInfo.class, (long)4);
		System.out.println("电影名:" + filmInfo.getFiName());
		FilmType fileType = filmInfo.getFilmType();
		System.out.println("类型:" + fileType.getFtName());
		System.out.println(fileType.getFilmInfos().size());
		HibernateSessionFactory.closeAll();
	}
在控制台显示的效果如下:



2、获取id为4的电影类型,包该类型下的所有电影信息

	@Test
	public void test02() {
		Session session = HibernateSessionFactory.getSession();
		//获取id为4的电影类型,包该类型下的所有电影信息
		FilmType filmType = (FilmType) session.get(FilmType.class, 4l);
		System.out.println("类型:" + filmType.getFtName());
		List<FilmInfo> filmInfos = filmType.getFilmInfos();
		for (FilmInfo filmInfo : filmInfos) {
			System.out.println("电影名:"+filmInfo.getFiName());
		}
		HibernateSessionFactory.closeAll();
	}
在控制台显示的效果如下:


3、添加一个电影信息,然后添加一个电影分类,先保存分类 在保存 电影。这里需要手动去保存

	@Test
	public void test03() {
		//添加一个电影信息,然后添加一个电影分类,先保存分类 在保存 电影
		FilmInfo filmInfo = new FilmInfo();
		filmInfo.setFiActor("actor");
		filmInfo.setFiDirector("director");
		filmInfo.setFiName("finame");
		filmInfo.setFiTicketPrice((double) 100);
		
		FilmType filmType = new FilmType();
		filmType.setFtName("typeName");
		filmInfo.setFilmType(filmType);
		
		Session session = HibernateSessionFactory.getSession();
		Transaction transaction = session.beginTransaction();
		transaction.begin();
		//先保存分类,然后保存分类下的信息
		session.save(filmType);
		session.save(filmInfo);
		
		transaction.commit();
		HibernateSessionFactory.closeAll();
	}
在控制台显示的效果如下:



4、添加一个电影信息,然后添加一个电影分类,保存分类的同时 级联保存电影信息

	
	@Test
	public void test04() {
		//保存分类的同时 级联保存电影信息
		FilmInfo filmInfo = new FilmInfo();
		filmInfo.setFiActor("actor");
		filmInfo.setFiDirector("director");
		filmInfo.setFiName("finame");
		filmInfo.setFiTicketPrice((double) 100);
		
		FilmType filmType = new FilmType();
		filmType.setFtName("typeName");
		
		filmInfo.setFilmType(filmType);
		filmType.getFilmInfos().add(filmInfo);
		
		Session session = HibernateSessionFactory.getSession();
		Transaction transaction = session.beginTransaction();
		transaction.begin();
		//先保存分类,然后保存分类下的信息
		session.save(filmType);
		
		transaction.commit();
		HibernateSessionFactory.closeAll();
	}
在控制台显示的效果如下:



那么 注解的使用先介绍到这里,其他的实现方式 和以前是一样的。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值