只是个人简单的一点小结
hibernate的配置文件 hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/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://localhost/hibernate </property> <property name="connection.username">root</property> <property name="connection.password"></property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">10</property> <!-- SQL dialect --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache 不缓存--> <property name="cache.provider_class"> org.hibernate.cache.NoCacheProvider </property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <property name="format_sql">true</property> </session-factory> </hibernate-configuration>
一对一的映射关系
我们假设一个妻子对应一个老公,一个老公也只有一个妻子,其他社会问题我们不讨论
注解版:
首先在配置文件里添加映射关系:
<mapping class="com.cl.hiberanate.bean.Husband" /> <mapping class="com.cl.hiberanate.bean.Wife" />
Husband类
@Entity public class Husband { private int id; private String name; private Wife wife; @OneToOne public Wife getWife() { return wife; } public void setWife(Wife wife) { this.wife = wife; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
wife类
@Entity public class Wife { private int id; private String name; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
查看sql语句:
create table Husband ( id integer not null auto_increment, name varchar(255), wife_id integer, primary key (id) ) create table Wife ( id integer not null auto_increment, name varchar(255), primary key (id) ) alter table Husband add index FKAEEA401BA8A19199 (wife_id), add constraint FKAEEA401BA8A19199 foreign key (wife_id) references Wife (id)
husband不需要修改,只需要修改wife类
@Entity public class Wife { private int id; private String name; //双向 private Husband husband; //被 com.cl.hiberanate.bean.Husband.wife 所映射 //只是内存间的映射,知道即可,基本不用 @OneToOne(mappedBy="wife") public Husband getHusband() { return husband; } public void setHusband(Husband husband) { this.husband = husband; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
编写一个测试类测试一下就好了,JunitTest,实在不会就去 main函数里运行
Session session = new AnnotationConfiguration().configure().buildSessionFactory().openSession(); Wife w = new Wife(); w.setName("Helen"); Husband h = new Husband(); h.setName("Tom"); h.setWife(w); session.save(w); session.save(h); session.beginTransaction().commit();
再来看看xml版,现在公司很少使用这个,开发速度太慢
hibernate.cfg.xml这个肯定要有,
类就直接用上面的类好了
新增:映射文件Husband.hbm.xml,Wife.hbm.xml切记和你的类同名且在一个包下
Husband.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.cl.hiberanate.bean"> <class name="Husband"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="name"></property> <!-- one-to-one 不要怀疑,就是这么写的 加上unique--> <many-to-one name="wife" column="wifeId" unique="true"></many-to-one> </class> </hibernate-mapping>
Wife.hbm.xml 双向的只需要把注释取消即可
<hibernate-mapping package="com.cl.hiberanate.bean"> <class name="Wife"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="name" column="name" not-null="true" length="20" type="java.lang.String"></property> <!-- one-to-one 双向 --> <!-- <one-to-one name="husband" property-ref="wife"></one-to-one> --> </class> </hibernate-mapping>
hibernate.cfg.xml里新增:
<mapping resource="com/cl/hiberanate/bean/Husband.hbm.xml" /> <mapping resource="com/cl/hiberanate/bean/Wife.hbm.xml" />
注意跟注解版的区别
看看数据库语句,跟上面是一样的
create table Husband ( id integer not null auto_increment, name varchar(255), wifeId integer unique, primary key (id) ) create table Wife ( id integer not null auto_increment, name varchar(20) not null, primary key (id) ) alter table Husband add index FKAEEA401B29AAB07C (wifeId), add constraint FKAEEA401B29AAB07C foreign key (wifeId) references Wife (id)
Session session = new Configuration().configure().buildSessionFactory().openSession(); Wife w = new Wife(); w.setName("Helen"); Husband h = new Husband(); h.setName("Tom"); h.setWife(w); session.save(w); session.save(h); session.beginTransaction().commit();
OK ,再看看一对多
一本书只属于一个类型,比如《操作系统》这本书属于“计算机类”,而计算机类除了有操作系统,还有计算机组成原理、Java等等,即一类里有多本书
不要较真什么我有基本相同名字的书,那个跟我们现在讨论的没关系,他们可以通过Id区分,我们假设只有一本
一对多:一个类有多本书,
注解版
Book :
@Entity public class Book { private int id; private String bookname; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookname() { return bookname; } public void setBookname(String bookname) { this.bookname = bookname; } }
@Entity public class BookType { private int id; private String typename; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTypename() { return typename; } public void setTypename(String typename) { this.typename = typename; } //一对多 private Set<Book> books; @OneToMany public Set<Book> getBooks() { return books; } public void setBooks(Set<Book> books) { this.books = books; } }
修改hibernate.cfg.xml
<mapping class="com.cl.hibernate.bean.Book" /> <mapping class="com.cl.hibernate.bean.BookType" />
测试,
Session session = new AnnotationConfiguration().configure().buildSessionFactory().openSession(); Book book = new Book(); BookType booktype = new BookType(); book.setBookname("hibernate"); booktype.setTypename("computer"); Set<Book> books = new HashSet<Book>() ; books.add(book); booktype.setBooks(books); session.save(book); session.save(booktype); session.beginTransaction().commit();
看看建表语句
create table Book ( id integer not null auto_increment, bookname varchar(255), primary key (id) ) create table BookType ( id integer not null auto_increment, typename varchar(255), primary key (id) ) create table BookType_Book ( BookType_id integer not null, books_id integer not null, primary key (BookType_id, books_id), unique (books_id) ) alter table BookType_Book add index FK13FA97E56EF30904 (BookType_id), add constraint FK13FA97E56EF30904 foreign key (BookType_id) references BookType (id) alter table BookType_Book add index FK13FA97E53B4450C3 (books_id), add constraint FK13FA97E53B4450C3 foreign key (books_id) references Book (id)
自动帮我们新增了一张表
一对多的双向(反向)即 多对一,这里先不讨论,到多对一再讨论
再看看XML版的
同上面的规则一样,新建一个映射文件,同名同包
BookType
<hibernate-mapping package="com.cl.hibernate.bean"> <class name="BookType"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="typename"></property> <!-- 一对多 --> <set name="books"> <!-- 加在book那张表 --> <key column="typeId"></key> <one-to-many class="com.cl.hibernate.bean.Book"/> </set> </class> </hibernate-mapping>
Book:双向的就把那个注释取消即可
<class name="Book"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="bookname"></property> <!-- many-to-one --> <!-- <many-to-one name="booktype" column="typeId" ></many-to-one> --> </class>
建表语句同上面是一样的
多对一
还是上面的图书和分类的例子
Book :
@Entity public class Book { private int id; private String bookname; //一本书属于一个类型,一个类型有多本书 private BookType booktype; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookname() { return bookname; } public void setBookname(String bookname) { this.bookname = bookname; } @ManyToOne @JoinColumn(name="typeId") public BookType getBooktype() { return booktype; } public void setBooktype(BookType booktype) { this.booktype = booktype; } }
BookType :多对一的双向即一对多
@Entity public class BookType { private int id; private String typename; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTypename() { return typename; } public void setTypename(String typename) { this.typename = typename; } //多对一双向 一对多 private Set<Book> books; @OneToMany(mappedBy="booktype") public Set<Book> getBooks() { return books; } public void setBooks(Set<Book> books) { this.books = books; } }
XML版
Book.hbm.xml:
<class name="Book"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="bookname"></property> <!-- many-to-one --> <many-to-one name="booktype" column="typeId" ></many-to-one> </class>
BookType.hbm.xml:
<class name="BookType"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="typename"></property> </class>
多对多
所谓多对多的关系,老师和学生,一个学生有多个老师,一个老师有多个学生
注解版:双向映射取消下面的注释
Student :
@Entity public class Student { private int id; private String sname; /* //双向映射 private Set<Teacher> teachers; //映射至 com.cl.hibernate.bean.Teacher.students @ManyToMany(mappedBy="students") public Set<Teacher> getTeachers() { return teachers; } public void setTeachers(Set<Teacher> teachers) { this.teachers = teachers; } */ @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } }
Teacher :
@Entity public class Teacher { private int id; private String tname; private Set<Student> students; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return tname; } public void setName(String tname) { this.tname = tname; } @ManyToMany //如不写会指定默认值 加入第三张表 一个老师对应多个学生,一个学生对应多个老师 @JoinTable(name="t_s",joinColumns={@JoinColumn(name="teacher_id")}, inverseJoinColumns={@JoinColumn(name="student_id")}) public Set<Student> getStudent() { return students; } public void setStudent(Set<Student> students) { this.students = students; } }
看看建表语句:
create table Student ( id integer not null auto_increment, sname varchar(255), primary key (id) ) create table Teacher ( id integer not null auto_increment, name varchar(255), primary key (id) ) create table t_s ( teacher_id integer not null, student_id integer not null, primary key (teacher_id, student_id) ) alter table t_s add index FK1BF68467CBB30 (teacher_id), add constraint FK1BF68467CBB30 foreign key (teacher_id) references Teacher (id) alter table t_s add index FK1BF6835E17090 (student_id), add constraint FK1BF6835E17090 foreign key (student_id) references Student (id)
OK,看看XML 版的
Student.hbm.xml:
<class name="Student"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="sname"></property> </class>
Teacher.hbm.xml:
<class name="Teacher"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="tname"></property> <!-- many-to-many --> <!-- 对应的哪一个属性 表名 --> <set name="students" table="t_s"> <!-- 第一个列名 --> <key column="teacher_id"></key> <!-- 第二个列名 类+名 --> <many-to-many class="com.cl.hibernate.bean.Student" column="student_id"></many-to-many> </set> </class>
OK,关系映射就全部完成了
看看hibernate的分页,不管什么数据库都是一样的,hibernate已经给我们实现好了:
下面是一个测试代码
Session session = new AnnotationConfiguration().configure().buildSessionFactory().openSession(); Query query = session.createQuery("from Book "); List<?> total = query.list(); //分页 int pageSize = 3; int totalPage = total.size() / pageSize ; if(total.size() % pageSize != 0){ totalPage++; } System.err.println(totalPage); query.setMaxResults(pageSize); int currentPage = 1;//当前页号 query.setFirstResult((currentPage - 1)*pageSize); List<?> list = query.list();
可以写成方法,参数pageSize ,currentPage 就可以实现分页方法啦
如果查询时有参数呢,可以使用占位符 ?
比如:
Query query = session.createQuery("from Book b where b.id = ? "); query.setString(0, "1"); List<?> list = query.list(); for(Object o : list){ Book b = (Book)o; System.out.println(b); }
也可以使用替换变量
如:
hql = "from Book b where b.id = :id"; Query query = session.createQuery(hql); query.setParameter("id", 1) //.setParameter("id", 1);
这两种参数设置都是可以的
hibernate的功能很强大,学然后知不足。
所有的练习源码:http://download.csdn.net/detail/i_do_can/9372156
不过我好像忘了上传jar文件了,补上:http://download.csdn.net/detail/i_do_can/9372177