菜鸟笔记——Hibernate入门知识点及简单操作

这些天开始研究Java的常用框架,首先先从Hibernate入手吧。到目前为止,个人感觉Hibernate是一个简化版的serlvet,他可以把原本需要我们自己写的增删查改等功能都封装好了直接通过实体类来调用便可以了,并且用起来也较方便。

参考链接:http://how2j.cn?p=48985

搭建一个简单的Hibernate来连接数据库吧

1、建立数据库

create database hibernate
create table book_(
       id int(11) not null auto_increment,
       num varchar(30),
       bookname varchar(30),
       price float,
       primary key(id)
)default charset=utf8;

注:id设置为自增长,num为书的编号,bookname为书名,price为价格

2、创建Java project并把jar包导入

3、创建实体类

注:放在pojo包下

package pojo;

public class Book {
	int id;
	String num;
	String bookname;
	float price;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public String getBookname() {
		return bookname;
	}
	public void setBookname(String bookname) {
		this.bookname = bookname;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
}

4、创建Book.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 package="pojo">
	<class name="Book" table="book_">  <!-- 指定实体类Book映射表book_ -->
		<id name="id" column="id">  <!-- 属性id映射表里的字段id -->
			<generator class="native"></generator>  <!-- id的自增长模式采用数据库本地方式 -->
		</id>
		<property name="num"></property>  <!-- 没用column=是默认字段名与name中相同,即column="num" -->
		<property name="bookname"></property>
		<property name="price"></property>
	</class>

</hibernate-mapping>

5、创建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://localhost:3306/hibernate?characterEncoding=UTF-8</property>
		<property name="connection.username">root</property>
		<property name="connection.password">admin</property>
		
		<!-- SQL dialect -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 指定用sql的方言来解读 -->
		<property name="current_session_class">thread</property> <!-- 指定事务管理方式,一个事务一个线程 -->
		<property name="show_sql">true</property> <!-- 是否在控制台显示sql语句 -->
		<property name="hbm2ddl.auto">update</property> <!-- 自动创建表结构,即可不用在sql中创建 -->
		<mapping resource="pojo/Book.hbm.xml"></mapping> <!-- hibernate会识别Book该实体类 -->
	</session-factory>
</hibernate-configuration>

6、写一个测试类TestHibernate.java用来测试与数据库之间的数据交互情况

package booksHibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		Book b = new Book();
		b.setNum("ISO1700");
		b.setBookname("Java入门");
		b.setPrice(50);   //通过实体类将值保存
		s.save(b);    //把实体类中的数据保存到数据库中
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

运行后,可在控制面板看到如下:

在目前的学习阶段可忽略上述的警告,对学习Hibernate暂无影响

数据库中查询可得:

7、在TestHibernate.java中对数据进行各种操作

1、将多条语句通过for循环添加到数据库中

package booksHibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
				
		for(int i=0;i<20;i++){
			Book b = new Book();
			b.setNum("ISO"+i);
			b.setBookname("Java入门"+i);
			b.setPrice(100);
			s.save(b);
		}  //通过循环把多条数据保存到数据库中
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

2、通过id获取某个对象

package booksHibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		Book b = (Book) s.get(Book.class, 6);  //获取类对象中id=6的对象
		System.out.println("id=6的书本名称是:"+b.getBookname());
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

3、通过id删除某条记录

package booksHibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		Book b = (Book) s.get(Book.class, 6);  //在删除之前会先把id=6的对象取出来
		s.delete(b); // 删除b对象	
                System.out.println("删除的记录id为:"+b.getId());	
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

4、更新数据

package booksHibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务

		Book b = (Book) s.get(Book.class, 5);  //更新前获取类对象
		System.out.println(b.getBookname());
		b.setBookname("Java精通到实战");  //修改该对象的属性
		s.update(b);  //把修改后的数据用update方法更新到数据库中
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

5、查询语句-HQL

package booksHibernate;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		String name="Java";
		Query q = s.createQuery("from Book b where b.bookname like ?");  //创建Query对象,不需要select *
		q.setString(0, "%"+name+"%");   //设置参数
		List<Book> ps=q.list();    //用list方法返回查询结果
		for(Book b : ps){
			System.out.println(b.getBookname());
		}
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

6、用Criteria进行查询

package booksHibernate;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		String name="Java";
		Criteria c = s.createCriteria(Book.class);   //创建一个Criteria对象
		c.add(Restrictions.like("bookname", "%"+name+"%"));  //通过add增加约束
		List<Book> ps=c.list();     //返回查询结果
		for(Book b:ps){
			System.out.println(b.getBookname());
		}
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

同时Criteria可以实现分页查询:

package booksHibernate;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		
		String name="Java";
		Criteria c = s.createCriteria(Book.class);   //创建一个Criteria对象
		c.add(Restrictions.like("bookname", "%"+name+"%"));  //通过add增加约束
		c.setFirstResult(2);   //分页查询,表示从第二条数据开始
		c.setMaxResults(5);  //一共查询5条数据
		
		List<Book> ps=c.list();     //返回查询结果
		for(Book b:ps){
			System.out.println(b.getBookname());
		}
		
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

7、用标准sql进行查询

package booksHibernate;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import pojo.Book;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
				
		String name="java";
		String sql="select * from book_ b where b.bookname like '%"+name+"%'";
		Query q = s.createSQLQuery(sql);
		List<Object[]> list=q.list();
		for(Object[] os:list){
			for(Object filed:os){
				System.out.println(filed+"\t");
			}    //返回的集合里的每一个元素是一个对象数组,再通过下标把这个对象数组中的数据取出
			System.out.println();
		}    //用标准sql查询
		 
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

8、多对一关系

注:一本书对应一种类别,而一种类别对应多本书,因此先创建一个Category类

Category实体类

package pojo;

public class Category {
	int id;
	String name;
	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;
	}
	
}

配置Category的xml文件:Category.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 package="pojo">
	<class name="Category" table="category_">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
	</class>
</hibernate-mapping>

在前面创建好的Book实体类中增加Category属性

package pojo;

public class Book {
	int id;
	String num;
	String bookname;
	float price;
	Category category;  //增加Category属性
	
	public Category getCategory() {
		return category;
	}
	public void setCategory(Category category) {
		this.category = category;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public String getBookname() {
		return bookname;
	}
	public void setBookname(String bookname) {
		this.bookname = bookname;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
}

Book.hbm.xml文件中设置Category多对一的关系

<?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 package="pojo">
	<class name="Book" table="book_">  <!-- 指定实体类Book映射表book_ -->
		<id name="id" column="id">  <!-- 属性id映射表里的字段id -->
			<generator class="native"></generator>  <!-- id的自增长模式采用数据库本地方式 -->
		</id>
		<property name="num"></property>  <!-- 没用column=是默认字段名与name中相同,即column="num" -->
		<property name="bookname"></property>
		<property name="price"></property>
		<many-to-one name="category" class="Category" column="cid"></many-to-one>
		<!-- 设置多对一的关系 cid表示category_表的外键-->
	</class>

</hibernate-mapping>

Hibernate.cfg.xml文件中增加对Category类的映射

<?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://localhost:3306/hibernate?characterEncoding=UTF-8</property>
		<property name="connection.username">root</property>
		<property name="connection.password">admin</property>
		
		<!-- SQL dialect -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 指定用sql的方言来解读 -->
		<property name="current_session_class">thread</property> <!-- 指定事务管理方式,一个事务一个线程 -->
		<property name="show_sql">true</property> <!-- 是否在控制台显示sql语句 -->
		<property name="hbm2ddl.auto">update</property> <!-- 自动创建表结构,即可不用在sql中创建 -->
		<mapping resource="pojo/Book.hbm.xml"></mapping> <!-- hibernate会识别Book该实体类 -->
		<mapping resource="pojo/Category.hbm.xml"></mapping> <!-- 增加映射 -->
	</session-factory>
</hibernate-configuration>

TestHibernate.java文件中测试多对一关系

package booksHibernate;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import pojo.Book;
import pojo.Category;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		 
		Category c = new Category();  //新增了一个对象Category
		c.setName("c1");
		s.save(c);
		
		Book b = (Book) s.get(Book.class, 2);  //将c1设置为id=2的书的分类为1
		b.setCategory(c);
		s.update(b);
		
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

9、一对多关系

在Category类中加入Set集合

package pojo;

import java.util.Set;
public class Category {
	int id;
	String name;
	Set<Book> books;  //增加一个set集合
	public Set<Book> getBooks() {
		return books;
	}
	public void setBooks(Set<Book> books) {
		this.books = books;
	}
	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;
	}
	
}

在Category.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 package="pojo">
	<class name="Category" table="category_">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		
		<set name="books" lazy="false">  <!-- 对应Category类中的book属性,lazy="f"表示不适用延迟加载 -->
			<key column="cid" not-null="false"></key>  <!-- 外键为cid,可以为空 -->
			<one-to-many class="Book"/> <!-- 表示一对多所对应的类是Book -->
		</set>
		
	</class>
</hibernate-mapping>

在TestHibernate.java中测试一对多的关系

package booksHibernate;

import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import pojo.Book;
import pojo.Category;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
			
                Category c=(Category) s.get(Category.class, 1);  //找出分类为1的所有书籍
		Set<Book> ps=c.getBooks();
		for(Book b:ps){
			System.out.println(b.getBookname());
		}
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

10、多对多关系

一本书可以被多个消费者购买,一个消费者也可以购买多本书

准备User.java文件

package pojo;

import java.util.Set;

public class User {
	int id;
	String name;
	Set<Book> books;
	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;
	}
	public Set<Book> getBooks() {
		return books;
	}
	public void setBooks(Set<Book> books) {
		this.books = books;
	}
	
}

准备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 package="pojo">
	<class name="User" table="user_">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		
		<set name="books" table="user_book" lazy="false">
			<key column="uid"></key>
			<many-to-many column="bid" class="Book"></many-to-many>
		</set>
	</class>
        
</hibernate-mapping>

Book.java中增加User集合的属性

package pojo;

import java.util.Set;

public class Book {
	int id;
	String num;
	String bookname;
	float price;
	Category category;  //增加Category属性
	Set<User> users;
	
	
	public Set<User> getUsers() {
		return users;
	}
	public void setUsers(Set<User> users) {
		this.users = users;
	}
	public Category getCategory() {
		return category;
	}
	public void setCategory(Category category) {
		this.category = category;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public String getBookname() {
		return bookname;
	}
	public void setBookname(String bookname) {
		this.bookname = bookname;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
}

Book.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 package="pojo">
	<class name="Book" table="book_">  <!-- 指定实体类Book映射表book_ -->
		<id name="id" column="id">  <!-- 属性id映射表里的字段id -->
			<generator class="native"></generator>  <!-- id的自增长模式采用数据库本地方式 -->
		</id>
		<property name="num"></property>  <!-- 没用column=是默认字段名与name中相同,即column="num" -->
		<property name="bookname"></property>
		<property name="price"></property>
		<many-to-one name="category" class="Category" column="cid"></many-to-one>
		<!-- 设置多对一的关系 cid表示category_表的外键-->
		
		<set name="users" table="user_book" lazy="false">
			<key column="bid"></key>  <!-- 增加多对多关系 -->
			<many-to-many column="uid" class="User"></many-to-many>
		</set>
	</class>

</hibernate-mapping>

hibernate.cdg.xml文件中增加对User的映射

<?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://localhost:3306/hibernate?characterEncoding=UTF-8</property>
		<property name="connection.username">root</property>
		<property name="connection.password">admin</property>
		
		<!-- SQL dialect -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 指定用sql的方言来解读 -->
		<property name="current_session_class">thread</property> <!-- 指定事务管理方式,一个事务一个线程 -->
		<property name="show_sql">true</property> <!-- 是否在控制台显示sql语句 -->
		<property name="hbm2ddl.auto">update</property> <!-- 自动创建表结构,即可不用在sql中创建 -->
		<mapping resource="pojo/Book.hbm.xml"></mapping> <!-- hibernate会识别Book该实体类 -->
		<mapping resource="pojo/Category.hbm.xml"></mapping> <!-- 增加映射 -->
		<mapping resource="pojo/User.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

在TestHibernate.java中增加3个用户,演示3个用户买了图书1

package booksHibernate;

import java.util.List;
import java.util.Set;
import java.util.HashSet;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import pojo.Book;
import pojo.Category;
import pojo.User;

public class TestHibernate {
	public static void main(String[] args) {
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		
		Session s = sf.openSession();  //打开新对象
		s.beginTransaction();   //开启一个事务
		
		
		Set<User> users = new HashSet();
		for(int i=0;i<3;i++){
			User u=new User();
			u.setName("user"+i);
			users.add(u);
			s.save(u);
		}    //增加三个用户
		
		Book b1=(Book) s.get(Book.class, 1);
		b1.setUsers(users);
		s.save(b1);  //书1被用户1,2,3,购买
		
		
		s.getTransaction().commit();  //提交事务(若同一个事务之内有任一个动作出错不能执行,则整个事务不执行)
		s.close();
		sf.close();
	}
}

注:从以上的表与表之间关系可以看出,一对多与多对一彼此是相互的,如一本书对应一个分类,而一个分类对应多本书,因此需要在不同的表中间增加不一样的映射,而多对多彼此之间的关系都是一样的,因此只需增加同样的多对多映射。

11、注解

原先在配置映射的时候,我们需要一个实体类Book.java,通过Book.hbm.xml来对数据库中的表字段进行一一对应,注解的方式便是不再需要hbm.xml该文件,直接在实体类中对各对应的属性和字段建立一个映射,达到连接数据库的目的。

Book.java中添加注解

package pojo;

import java.util.Set;

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="book_")  //表示这是一个映射到表名为book_的类
public class Book {
	int id;
	String num;
	String bookname;
	float price;

	@Id   //属性注解在对应的get方法上,这里表示为主键
	@GeneratedValue(strategy = GenerationType.IDENTITY)  //表示自增长方式用mysql自带的
	@Column(name="id")  //映射到字段id
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Column(name="num")
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	@Column(name="bookname")
	public String getBookname() {
		return bookname;
	}
	public void setBookname(String bookname) {
		this.bookname = bookname;
	}
	@Column(name="price")
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
}

然后在hibernate.cfg.xml文件中修改一下对应映射的路径,即把对应到Book.hbm.xml的路径改为Book.java

<?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://localhost:3306/hibernate?characterEncoding=UTF-8</property>
		<property name="connection.username">root</property>
		<property name="connection.password">admin</property>
		
		<!-- SQL dialect -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 指定用sql的方言来解读 -->
		<property name="current_session_class">thread</property> <!-- 指定事务管理方式,一个事务一个线程 -->
		<property name="show_sql">true</property> <!-- 是否在控制台显示sql语句 -->
		<property name="hbm2ddl.auto">update</property> <!-- 自动创建表结构,即可不用在sql中创建 -->
<!-- 		<mapping resource="pojo/Book.hbm.xml"></mapping> hibernate会识别Book该实体类 -->
<!-- 		<mapping resource="pojo/Category.hbm.xml"></mapping> 增加映射 -->
<!-- 		<mapping resource="pojo/User.hbm.xml"/> -->
		<mapping class="pojo.Book"/> <!-- 使Hibernate支持该注解方式 -->
	</session-factory>
</hibernate-configuration>

其他代码无需改变,即可完成CRUD(增删查改)的操作

注:注解中的一些其他属性仅供参考

小项目开发简单,参与人较少的用注解,开发快速;大项目多人交互,配置量大的用配置文件。

1)类相关注解

@Entity —— 将一个类声明为一个实体bean(即一个持久化POJO类) 
@Table —— 注解声明了该实体bean映射指定的表(table),目录(catalog)和schema的名字

2)属性相关注解

@Id —— 注解声明了该实体bean的标识属性(对应表中的主键)。 
@Column —— 注解声明了属性到列的映射。该注解有如下的属性 
name 可选,列名(默认值是属性名) 
unique 可选,是否在该列上设置唯一约束(默认值false) 
nullable 可选,是否设置该列的值可以为空(默认值false) 
insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true) 
updatable 可选,该列是否作为生成的update语句中的一个列(默认值true) 
columnDefinition 可选,为这个特定列覆盖sql ddl片段(这可能导致无法在不同数据库间移植) 
table 可选,定义对应的表(默认为主表) 
length 可选,列长度(默认值255) 
precision 可选,列十进制精度(decimal precision)(默认值0) 
scale 可选,如果列十进制数值范围(decimal scale)可用,在此设置(默认值0) 
@GeneratedValue —— 注解声明了主键的生成策略。该注解有如下属性 
strategy 指定生成的策略(JPA定义的),这是一个GenerationType。默认是GenerationType. AUTO 
GenerationType.AUTO 主键由程序控制 
GenerationType.TABLE 使用一个特定的数据库表格来保存主键 
GenerationType.IDENTITY 主键由数据库自动生成(主要是自动增长类型) 
GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列。(这个值要与generator一起使用) 
generator 指定生成主键使用的生成器(可能是orcale中的序列)。 
@SequenceGenerator —— 注解声明了一个数据库序列。该注解有如下属性 
name 表示该表主键生成策略名称,它被引用在@GeneratedValue中设置的“gernerator”值中 
sequenceName 表示生成策略用到的数据库序列名称。 
initialValue 表示主键初始值,默认为0. 
allocationSize 每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50.

3)关系相关注解

@ManyToOne 设置多对一关联 
    方法一 
    @ManyToOne(cascade={CasCadeType.PERSIST,CascadeType.MERGE}) 
    @JoinColumn(name="外键") 
    public 主表类 get主表类(){return 主表对象} 
    方法二 
    @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE}) 
    @JoinTable(name="关联表名", 
    joinColumns = @JoinColumn(name="主表外键"), 
    inverseJoinColumns = @JoinColumns(name="从表外键") 
    ) 
@OneToMany 设置一对多关联。
    方法一 
    “一端”配置 
    @OneToMany(mappedBy="“多端”的属性") 
    public List<“多端”类> get“多端”列表(){return “多端”列表} 
    “多端”配置参考@ManyToOne. 
     方法二 
    “一端”配置 
    @OneToMany(mappedBy="“多端”的属性") 
    @MapKey(name="“多端”做为Key的属性") 
    public Map<“多端”做为Key的属性的类,主表类> get“多端”列表(){return “多端”列表} 
    “多端”配置参考@ManyToOne. 
    方法三 使用这种配置,在为“一端”添加“多端”时,可以修改“多端”的外键。 
    “一端”配置 
    @OneToMany 
    @JoinColumn(name="“多端”外键") 
    public List<“多端”类> get“多端”列表(){return “多端”列表} 
    “多端”配置参考@ManyToOne.

发布了12 篇原创文章 · 获赞 14 · 访问量 6447

猜你喜欢

转载自blog.csdn.net/weixin_42678675/article/details/81233604