标签:date() cer 外键 word sql ppi text root nfa
@OneToMany注解可以用在一对多的数据结构来操作数据库,这里以班级<->学生为例来测试这个注解。
首先来看看项目结构:

xml文件配置,与前面一篇‘一对一‘的随笔差不多,有两个Java类:ClassRoom、Student。所以,应该将两个表写到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>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 设置数据库的连接 -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate?useSSL=false&useUnicode=true&characterEncoding=UTF-8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 数据库的方言:根据底层的数据库生成不同的SQL -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 配置格式化SQL -->
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping class="o2m.Student"/>
<mapping class="o2m.ClassRoom"/>
</session-factory>
</hibernate-configuration>
ClassRoom类:
package o2m;
import javax.persistence.*;
import java.util.Set;
@Entity
public class ClassRoom {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column
private Integer cid;
@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinColumn(name = "cid")
private Set<Student> stus; // 学生集合
@Column
private Integer nums; // 一个班的总人数
public ClassRoom() {
}
public ClassRoom(Set<Student> stus, Integer nums) {
this.stus = stus;
this.nums = nums;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Set<Student> getStus() {
return stus;
}
public void setStus(Set<Student> stus) {
this.stus = stus;
}
public Integer getNums() {
return nums;
}
public void setNums(Integer nums) {
this.nums = nums;
}
}
@OneToMany注解写在少的类中的对应多的头上。
Student类:
package o2m;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.util.Date;
@Entity
public class Student {
@Id
@GeneratedValue(generator="sid")
@GenericGenerator(name="sid", strategy = "assigned")
@Column(length = 6)
private String sid; // 学号
@Column
private String name; // 姓名
@Column
private String sex; // 性别
@Column
private String school; // 学校
@Column
private String address; // 地址
@Column
private Date registertime; // 注册学籍时间
public Student() {
}
public Student(String sid, String name, String sex, String school, String address, Date registertime) {
this.sid = sid;
this.name = name;
this.sex = sex;
this.school = school;
this.address = address;
this.registertime = registertime;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getRegistertime() {
return registertime;
}
public void setRegistertime(Date registertime) {
this.registertime = registertime;
}
}
还有一个@ManyToOne注解,@ManyToOne应加在多的类中的对应少的头上,但这里我没有用,因为目前需求只要单向外键关联的。
这样就有两张表了:

然后插入数据测试:
package main;
import o2m.ClassRoom;
import o2m.Student;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import controller.StudentController;
import java.util.*;
public class Main {
public static void main(String[] args) {
Configuration configuration = new Configuration().configure();
ServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = configuration.buildSessionFactory(registry);
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
List<String> name = new LinkedList<>();
List<String> sex = new LinkedList<>();
List<String> address = new LinkedList<>();
name.add("漩涡鸣人");
name.add("宇智波佐助");
name.add("春野樱");
name.add("旗木卡卡西");
name.add("自来也");
name.add("纲手");
name.add("大蛇丸");
name.add("宇智波鼬");
name.add("九尾");
name.add("八尾");
sex.add("男");
sex.add("男");
sex.add("女");
sex.add("男");
sex.add("男");
sex.add("女");
sex.add("男");
sex.add("男");
sex.add("男");
sex.add("男");
address.add("木叶村501号");
address.add("木叶村504号");
address.add("木叶村902号");
address.add("木叶村401号");
address.add("木叶村107号");
address.add("木叶村219号");
address.add("木叶村901号");
address.add("木叶村116号");
address.add("木叶村511号");
address.add("木叶村801号");
Set<Student> s1 = new HashSet<>();
for (int i = 0; i < name.size(); i++) {
Student studenet = new Student(
"S0000" + i,
name.get(i),
sex.get(i),
"木叶村",
address.get(i),
new Date()
);
s1.add(studenet);
session.save(studenet);
}
ClassRoom c1 = new ClassRoom(s1, s1.size());
session.save(c1);
transaction.commit();
session.close();
}
}
这里注意session.close(),应该放在提交(commit)的后面,不然Student中cid就为null,如果不写也可以,但我想一般api都加上关闭更符合标准一点。
ps:请不用在意我使用List,我知道它的底层是链表,肯定效率不如数组,这里只是想用用它而已。。。
最后看一看插入数据后的效果:
ClassRoom表:

对应为:1班共10人。
Student表:

显然,cid是外键classroom的主键,即这些学生都是1班的。
实际上也有好多问题我不明白,比如,我将CRUD功能单独封装起来调用,就不能有这样的效果了。。。可能我的session会话没使用正确、@OneToMany的具体作用我也不清楚...感觉按理来说Student中没有ClassRoom对象成员,我的操作中也没有手动设置,那么外键cid不应该会有值(这样说也不对,因为本来cid就是外键,既然ClassRoom表创建并给cid赋值了,那它理应有值,与Student无关,但我就是遇到有情况,ClassRoom类中cid有值,但Student表中就为null,比如前面提到的session.close()放在了commit前面就会有这种情况),那么只有可能是@OneToMany做了这件事,正因为有这个注解,Student表中对应的外键就能自动关联...感觉应该是这样。
标签:date() cer 外键 word sql ppi text root nfa
原文地址:https://www.cnblogs.com/darkchii/p/8758960.html