Hibernate多对多例子及连接池和日志的配置

 

大致描述:

        1、通过一位老师可以查询所有学生的信息。
         2、通过一个学生,可以查询他的所有老师信息。
         3、给一个学生分配置其它老师
         4、给一个老师再分配三个学生,可以是现有数据库中存在的学生,也可以是新增加的学生。
         5、删除一个老师,则时删除老师下面的所有学生。

学生表:

create table t_student(
    id int(11) primary key not null auto_increment COMMENT'学生编号',
  sName varchar(20) not null COMMENT '学生姓名',
  age int (3) COMMENT '学生年龄',
    hobby varchar(20) COMMENT '学生爱好'
);


   老帅表:

create table t_teacher(
    id int(11) primary key not null auto_increment COMMENT'老师编号',
  tName varchar(20) not null COMMENT '老师姓名',
    age int (3) COMMENT '老师教龄'
);


   中间表:

create table t_stu_tea(
    id int(11) primary key not null auto_increment COMMENT'编号',
  sId int (11) not null COMMENT '学生编号',
  tId int (11) not null COMMENT '老师编号'
);

插入数据:

insert into t_student values (1,"xxs",19,"read");
insert into t_student values (2,"sxj",20,"study");


insert into t_teacher values (1,"cs",5);
insert into t_teacher values (2,"shy",3);
insert into t_teacher values (3,"scc",3);

insert into t_stu_tea values (1,1,1);
insert into t_stu_tea values (2,1,2);
insert into t_stu_tea values (3,2,2);
insert into t_stu_tea values (4,2,3);

三张表数据:

Hibernate多对多例子及连接池和日志的配置Hibernate多对多例子及连接池和日志的配置Hibernate多对多例子及连接池和日志的配置

项目结构(注意是java项目):

Hibernate多对多例子及连接池和日志的配置

创建实体类:

Student.java

package cn.xxs.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


/**
 * Student 
 * @author xxs
 *
 */
@Entity
@Table(name="t_student")
public class Student implements Serializable{
	
	private static final long serialVersionUID = 1L;
	private int id;
	private String sName;
	private int age;
	private String hobby;
	private Set<Teacher> teacher = new HashSet<>();
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(int id, String sName, int age, String hobby, Set<Teacher> teacher) {
		super();
		this.id = id;
		this.sName = sName;
		this.age = age;
		this.hobby = hobby;
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column
	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;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
	
	@ManyToMany
	@JoinTable(name="t_stu_tea",
				joinColumns= {@JoinColumn(name="sId")},inverseJoinColumns= {@JoinColumn(name="tId")})
	public Set<Teacher> getTeacher() {
		return teacher;
	}
	public void setTeacher(Set<Teacher> teacher) {
		this.teacher = teacher;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", sName=" + sName + ", age=" + age + ", hobby=" + hobby + "]";
	}

	
	
}

Teacher.java

package cn.xxs.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
/**
 * Teacher 
 * @author xxs
 *
 */
@Entity
@Table(name="t_teacher")
public class Teacher implements Serializable{
	
	private static final long serialVersionUID = 1L;
	private int id;
	private String tName;
	private int age;
	
	private Set<Student> student = new HashSet<>();

	public Teacher() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Teacher(int id, String tName, int age, Set<Student> student) {
		super();
		this.id = id;
		this.tName = tName;
		this.age = age;
		this.student = student;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String gettName() {
		return tName;
	}

	public void settName(String tName) {
		this.tName = tName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	@ManyToMany(mappedBy="teacher",cascade=CascadeType.ALL)
	 
	public Set<Student> getStudent() {
		return student;
	}

	public void setStudent(Set<Student> student) {
		this.student = student;
	}

	@Override
	public String toString() {
		return "Teacher [id=" + id + ", tName=" + tName + ", age=" + age + "  ]";
	}
	
	
}

配置连接池:

hibernate.cfg.xml

<?xml version="1.0" encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping 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:3306/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
     
     <!-- c3p0的配置 -->
        <!-- 配置连接池的提供商 -->
        <property name="hibernate.connection.provider_class">
        	org.hibernate.connection.C3P0ConnectionProvider
        </property>
        <!-- 数据库连接池的最大连接数 -->
		<property name="hibernate.c3p0.max_size">20</property>
		<!-- 数据库连接池的最小连接数 -->
		<property name="hibernate.c3p0.min_size">5</property>
		<!-- 数据库连接池中连接对象在多长时间没有使用后,就被销毁 -->
		<property name="hibernate.c3p0.timeout">5000</property>
		<!-- 缓存Statement对象的数量 -->
		<property name="hibernate.c3p0.max_statements">100</property>
		<!-- 连接池检测纯种多长时间检测一次池内的所有链接对象是否有效 -->
		<property name="hibernate.c3p0.idle_test_period">3000</property>
		<!-- 数据库连接池中的连接耗尽时, 同一时刻获取多少个数据库连接 -->
		<property name="hibernate.c3p0.acquire_increment">2</property>
     
     
     
     
        <!-- SQL dialect   方言  -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

       
        <!-- Echo all executed SQL to stdout   显示sql语句 -->
        <property name="show_sql">true</property>
        
 		<!-- 格式化sql语句  -->
		<property name="hibernate.format_sql">true</property>
		<!-- 为"当前" Session指定一个(自定义的)策略。 -->
		<property name="current_session_context_class">thread</property>
		<!-- 开启事务处理  -->
		<!-- <property name="hibernate.transaction.auto_close_session">true</property> -->
		
        <mapping class="cn.xxs.entity.Student"/>
        <mapping class="cn.xxs.entity.Teacher"/>

    </session-factory>

</hibernate-configuration>

日志资源文件:

log4j.properties

#
# Hibernate, Relational Persistence for Idiomatic Java
#
# License: GNU Lesser General Public License (LGPL), version 2.1 or later.
# See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
#

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=warn, stdout

log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
#log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

工具类:

HibernateUtil.java

package cn.xxs.util;

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

public class HibernateUtil {
	private static SessionFactory sessionFactory;
	
	static {
		sessionFactory = new Configuration().configure().buildSessionFactory();
	}
	
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
}

测试类:

package cn.xxs.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;


import cn.xxs.entity.Student;
import cn.xxs.entity.Teacher;

import cn.xxs.util.HibernateUtil;

public class HibernateTest {

	// 1.导入hibernate必须的jar包和mysql驱动jar包
	// 2.创建类(User)
	// 3.创建类的映射文件(User.hbm.xml)
	// 4.把User.hbm.xml文件加载到hibernate.cfg.xml核心配置文件中
	// 5.测试
	

	//1、通过一位老师可以查询所有学生的信息。
	@Test
	public void test1() {
		// 1、获取SessionFactory
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// 2、获取Session
		Session session = sf.openSession();
		//获取id为1的teacher对象
		Teacher teacher = session.get(Teacher.class, 1);
		System.out.println(teacher.toString());
		//获取id为1的teacher对象下所有学生的set集合
		Set<Student> stus = teacher.getStudent();
		//迭代器遍历
		Iterator<Student> it = stus.iterator();
		while(it.hasNext()) {
			System.out.println(it.next().toString());
		}
		//关闭Session
		session.close();
		
	}
	//2、通过一个学生,可以查询他的所有老师信息。
	@Test
	public void test2() {
		// 1、获取SessionFactory
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// 2、获取Session
		Session session = sf.openSession();
		//获取id为1的stus对象
		Student stus = session.get(Student.class, 1);
		System.out.println(stus.toString());
		//获取id为1的stus对象下所有老师的set集合
		Set<Teacher> teacher = stus.getTeacher();
		//迭代器遍历
		Iterator<Teacher> it = teacher.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		//关闭Session
		session.close();
		
	}
	
	// 3、给一个学生分配置其它老师
	@Test
	public void test3() {
		// 1、获取SessionFactory
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// 2、获取Session
		Session session = sf.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		//获取id为2的stus对象
		Student stus = session.get(Student.class, 2);
		//获取id为1的teacher对象
		Teacher teacher = session.get(Teacher.class, 1);
		//让id为1的老师分配给id为2的学生	
		stus.getTeacher().add(teacher);
		//提交
		transaction.commit();
		//关闭Session
		session.close();
		
	}
	// 4、给一个老师再分配三个学生,可以是现有数据库中存在的学生,也可以是新增加的学生。
	
	@Test
	public void test4() {
		// 1、获取SessionFactory
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// 2、获取Session
		Session session = sf.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		//获取id为1的stus对象
		Student stus = session.get(Student.class, 1);
		
		//新建两个Student对象
		Student stus2 = new Student();
		stus2.setsName("stu2");
		stus2.setAge(20);
		stus2.setHobby("Hobby2");
		Student stus3 = new Student();
		stus3.setsName("stu3");
		stus3.setAge(20);
		stus3.setHobby("Hobby3");
		//新建两个students集合
		Set<Student> students = new HashSet<Student>();
		//把stus2 ,stus3 放进students集合
		students.add(stus2);
		students.add(stus3);
		//保存
		session.save(stus2);
		session.save(stus3);
		
		Teacher teacher = session.get(Teacher.class, 3);
				
//		teacher.getStudent().add(stus);
//		teacher.getStudent().add(stus2);
//		teacher.getStudent().add(stus3);
		//给id为1的老师分配给stus,stus2,stus3三个学生
		stus.getTeacher().add(teacher);
		stus2.getTeacher().add(teacher);
		stus3.getTeacher().add(teacher);
		//保存
		session.save(teacher);
		//提交
		transaction.commit();
		//关闭Session
		session.close();
		
	}
	
	//5、删除一个老师,则时删除老师下面的所有学生。
	@Test
	public void test5() {
		// 1、获取SessionFactory
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// 2、获取Session
		Session session = sf.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		//获取id为2的teacher对象
		Teacher teacher = session.get(Teacher.class, 2);
		//删除id为2的老师以及他的学生		
		session.delete(teacher);
		//提交
		transaction.commit();
		//关闭Session
		session.close();
		
	}
}

结果:

大致描述:

        1、通过一位老师可以查询所有学生的信息。

Hibernate多对多例子及连接池和日志的配置
         2、通过一个学生,可以查询他的所有老师信息。

Hibernate多对多例子及连接池和日志的配置
         3、给一个学生分配其它老师

Hibernate多对多例子及连接池和日志的配置
         4、给一个老师再分配三个学生,可以是现有数据库中存在的学生,也可以是新增加的学生。

Hibernate多对多例子及连接池和日志的配置Hibernate多对多例子及连接池和日志的配置
         5、删除一个老师,则时删除老师下面的所有学生。

Hibernate多对多例子及连接池和日志的配置Hibernate多对多例子及连接池和日志的配置Hibernate多对多例子及连接池和日志的配置