Hibernate5 一对多关系的建立
**我这里直接以学生stu表与教室clss表为例子说明一对多关系(使用clss是因为防止class关键字)
总的项目结构如下
先拷maven开发包:**
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ht-hibernate-2</groupId>
<artifactId>ht-hibernate-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>ht-hibernate-2</name>
<description />
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--指明hibernate的版本,在此处指明下面可以直接写 ${hibernate.version}来引用,以后修改更方便-->
<hibernate.version>5.4.0.Final</hibernate.version>
</properties>
<dependencies>
<!-- hibernate核心开发包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>
${hibernate.version}
</version>
</dependency>
<!-- mysql连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- log4j开发包 用于生成日志 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
<!-- 也是log4j的开发包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<version>3.1</version>`在这里插入代码片`
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
写pojo实体类:
1.班级实体类Clss.java 班级中有学生集合 学生中有班级对象属性
package com.pojo;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;
import com.sort.StudentSort;
public class Clss implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int clssid;
private String clssname;
//班级里面有学生集合
private Set<Stu> studentSet = new TreeSet<Stu>(new StudentSort());
public Set<Stu> getStudentSet() {
return studentSet;
}
public void setStudentSet(Set<Stu> studentSet) {
this.studentSet = studentSet;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public int getClssid() {
return clssid;
}
public void setClssid(int clssid) {
this.clssid = clssid;
}
public String getClssname() {
return clssname;
}
public void setClssname(String clssname) {
this.clssname = clssname;
}
}
2.学生实体类:Stu.java
package com.pojo;
import java.io.Serializable;
public class Stu implements Serializable{
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public Clss getClss() {
return clss;
}
public void setClss(Clss clss) {
this.clss = clss;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
/**
*
*/
private static final long serialVersionUID = 1L;
private int stuid;
private String stuname;
//学生里面有班级对象属性
private Clss clss;
}
映射文件中的代码:
stu.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>
<!-- 配置映射文件的作用:描述类与表之间的映射关系( 1.建立类与表的映射 2.主键的映射 3.其他字段的映射 4.表与表之间的关系映射 )-->
<!-- 类与表的映射 -->
<class name="com.pojo.Stu" table="stu">
<id name="stuid" column="stuid">
<generator class="native"></generator>
</id>
<property name="stuname" column="stuname"></property>
<!-- 学生与班级的关系 多对一 使用<many-to-one> 班级name是班级属性 字段是外键的名字-->
<many-to-one name="clss" column="c_id"></many-to-one>
</class>
</hibernate-mapping>
clss.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>
<!-- 配置映射文件的作用:描述类与表之间的映射关系( 1.建立类与表的映射 2.主键的映射 3.其他字段的映射 4.表与表之间的关系映射 )-->
<!-- 类与表的映射 -->
<class name="com.pojo.Clss" table="clss">
<id name="clssid" column="clssid">
<generator class="native"></generator>
</id>
<property name="clssname" column="clssname"></property>
<!-- 班级中有学生集合 一对多的关系-->
<set name="studentSet" cascade="save-update,delete" sort="com.sort.StudentSort">
<key column="c_id"></key> <!-- 通过c_id外键与com.pojo.Clss建立一对多的关系 -->
<one-to-many class="com.pojo.Stu"/>
</set>
</class>
</hibernate-mapping>
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节点代表一个数据库 -->
<session-factory>
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!-- 数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!--
2.3 自动建表 加了这句话 如果数据库中存在相同的表则会替换 所以每次这样新增的话 总是只有最后一次添加数据 之前的数据会被删除 因为重新建了表
<property name="hibernate.hbm2ddl.auto">create</property>
-->
<!--3. 加载所有映射-->
<mapping resource="com/pojo/stu.hbm.xml"/>
<mapping resource="com/pojo/clss.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Log4j 用于生成日志的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="OFF" monitorInterval="1800">
<properties>
<property name="LOG_HOME">/WEB-INF/logs</property>
<property name="FILE_NAME">finance-pay</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<RollingFile name="running-log" fileName="${LOG_HOME}/${FILE_NAME}.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="true">
<PatternLayout
pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingFile>
</Appenders>
<Loggers>
<!-- <Logger name="com.cssweb.test.app" level="trace" additivity="true">
<AppenderRef ref="running-log" /> </Logger> -->
<Root level="info">
<!-- 这里是输入到文件,很重要-->
<AppenderRef ref="running-log" />
<!-- 这里是输入到控制台-->
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
最后就可以开始测试代码了,可以自己从这些方面测试:
首先要根据配置生成表(写在主方法中运行一下就好了),代码如下:
public static void main(String[] args) {
ServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
Metadata metadata = new MetadataSources(registry).buildMetadata();
SchemaExport export = new SchemaExport();
export.create(EnumSet.of(TargetType.DATABASE), metadata);
}
然后要进行下面的测试话必须先在数据库中添加内容
可以自己通过界面化工具添加
也可以直接写代码添加,例如添加班级(添加学生一样的):
public static void main(String[] args) {
//1.读取总的配置文件
Configuration configuration = new Configuration();
configuration.configure("/hibernate.cfg.xml");
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
Clss clss = new Clss();
clss.setClssname("s67");
session.save(clss);
transaction.commit();
session.close();
}
1.同时新增学生和班级
public class 同时新增学生和班级 {
public static void main(String[] args) {
//1.读取总的配置文件
Configuration configuration = new Configuration();
configuration.configure("/hibernate.cfg.xml");
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
//设置需要新增的学生姓名
Stu stu = new Stu();
stu.setStuname("小红");
Stu stu2 = new Stu();
stu2.setStuname("小紫");
//需要把该学生添加到哪个班级 通过班级编号得到该班级
Clss clss = new Clss();
clss.setClssname("s68");
clss.getStudentSet().add(stu);
clss.getStudentSet().add(stu2);
session.save(clss);
transaction.commit();
session.close();
}
}
2.根据班级编号找学生:
public static void main(String[] args) {
//1.读取总的配置文件
Configuration configuration = new Configuration();
configuration.configure("/hibernate.cfg.xml");
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//括号里面写hql语句 其中表是类名
Query<Stu> query = session.createQuery("from Stu");
List<Stu> list = query.list();
for (Stu stu : list) {
System.out.println(stu.getStuid()+"\t"+stu.getStuname()+"\t"+stu.getClss().getClssname());
}
transaction.commit();
session.close();
}
3.输出某班级的所有学生:
Configuration configuration = new Configuration();
configuration.configure("/hibernate.cfg.xml");
//创建session工厂
SessionFactory factory = configuration.buildSessionFactory();
//得到session对象 (打开session)
Session session = factory.openSession();
//得到事务
Transaction transaction = session.getTransaction();
//打开事务
transaction.begin();
//要输出血学生的班级
Clss clss = session.get(Clss.class,5);
//得到班级类中的学生集合
Set<Stu> set = clss.getStudentSet();
for (Stu stu : set) {
System.out.println(stu.getStuid()+"\t"+stu.getStuname()+"\t"+stu.getClss().getClssname());
}