Annotation在框架中是越来越受欢迎了,因为annotation的配置比起XML的配置来说方便了很多,不需要大量的XML来书写,方便简单了很多,只要几个annotation的配置,就可以完成我们以前需要书写的大量的XML文件。当然annotation的配置也有缺陷的,那就是annotation一般都是配置在代码中的,如果要修改的话,需要动源代码,丧失了灵活性,违背了OCP(增加开放,修改关闭)原则,但是在真实的项目开发中,我们只是动配置文件,而不修改源代码的情况实在是太少见了,所以现在annotation已经被广泛的运用到了编程中,各种框架都提供了基于annotation的配置。

hibernate的注解配置和Jpa中的注解使用基本上都差不多。

参考博客:

https://blog.csdn.net/ervinbao/article/details/52861000

https://www.cnblogs.com/liangxinxinbo/p/6092664.html

http://www.ilt.me/dmfx/89.html

导入jar包:

还有mysql的驱动

----------------------

简单的插入测试小案例:

实体:User

package org.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity
// @Table(name="t_user")//表名 默认不写的话 就是类名
public class User {
private int id;
private String username;
private String password;
private String nickname;
private Date bornDate; public User() {
} public User(int id, String username, String password, String nickname, Date bornDate) {
super();
this.id = id;
this.username = username;
this.password = password;
this.nickname = nickname;
this.bornDate = bornDate;
} public User(String username, String password, String nickname, Date bornDate) {
super();
this.username = username;
this.password = password;
this.nickname = nickname;
this.bornDate = bornDate;
} @Id
@GeneratedValue()//默认native @GeneratedValue()
//@GeneratedValue(generator = "x") // 使用uuid id的类型必须是String类型
//@GenericGenerator(name = "x", strategy = "uuid") // 使用hibernate的uuid策略
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 5, nullable = false)
public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} @Column(length = 10, nullable = false)//nullable属性:默认是true 允许空值
public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} @Column(length = 5, nullable = true)
public String getNickname() {
return nickname;
} public void setNickname(String nickname) {
this.nickname = nickname;
} @Column(name = "born_date")
public Date getBornDate() {
return bornDate;
} public void setBornDate(Date bornDate) {
this.bornDate = bornDate;
} @Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
+ ", bornDate=" + bornDate + "]";
} }

测试类:

package org.execute;

import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.model.User; public class Exe {
static Configuration config = null;
static SessionFactory sessionFactory = null; // 初始化
static {
// 加载核心配置文件 默认加载类路径下的hibernate.cfg.xml
config = new Configuration();
config.configure();
// 创建工厂
sessionFactory = config.buildSessionFactory();
} // 返回session
public Session rtn() {
return sessionFactory.openSession();
} // 保存测试
@Test
public void insert() {
Session session = rtn();
session.getTransaction().begin();
User u = new User("laomu", "123", "老孙", new Date());
session.save(u);
session.getTransaction().commit();
} }

我们发现在对实体进行注解配置的时候  导入的包和JPA配置时一样

在测试类中进行插入时,使用的不是JPA中的EntityManager对象,

EntityManagerFactory factory=Persistence.createEntityManagerFactory("simple");
EntityManager em = factory.createEntityManager();

而还是hibernate中的session对象。

配置文件:类路径下的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>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!--控制台打印sql语句-->
<property name="connection.url">
jdbc:mysql://localhost:3308/annotationhibernate
</property>
<property name="connection.username">root</property>
<property name="connection.password">jay571018</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property> <property name="show_sql">true</property>
<!--
<mapping resource="org/model/Course.hbm.xml" />
<mapping resource="org/model/Student.hbm.xml" />
--> <mapping class="org.model.User"/>
</session-factory> </hibernate-configuration>

下面观察数据库:

插入的数据:

-------------------------------------------------

annotation配置many-to-one双向

先看有问题的代码:(明明配置了级联  但是却没有进行级联保存的问题)

多方:Student

package org.model;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; //多方 由该方维护外键
@Entity
@Table(name = "t_student")
public class Student {
private int id;
private String name;
private String stuNo;
// 一方的属性
private ClassRoom room; @Id
@GeneratedValue()
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 5, nullable = false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Column(length = 10, nullable = false)
public String getStuNo() {
return stuNo;
} public void setStuNo(String stuNo) {
this.stuNo = stuNo;
} // optional=false 外键字段不能为空 即每个学生都必须有对应的班级 默认为true
// ManyToOne 查询student 默认使用即时加载
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
// 在维护端 指定外键字段名 也可以不写 默认属性_id
@JoinColumn(name = "r_id")
public ClassRoom getRoom() {
return room;
} public void setRoom(ClassRoom room) {
this.room = room;
} public Student() {
} // 互相关联的方法
public Student(String name, String stuNo) {
this.name = name;
this.stuNo = stuNo;
} @Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + room.toString() + "]";
} }

一方:ClassRoom

package org.model;

import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table; //一方 被维护端
@Entity
@Table(name = "t_classroom")
public class ClassRoom {
private int id;
private String name;
// 多方的集合属性
private Set<Student> students = new HashSet<Student>(); @Id
@GeneratedValue()
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 10, nullable = false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} // mappedBy属性:由集合中对应的实体Student中的classroom属性来维护外键 声明mappedBy的实体为被维护方
// 抓取方式 onetoMany 默认为lazy加载
@OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, mappedBy = "room")
public Set<Student> getStudents() {
return students;
} public void setStudents(Set<Student> students) {
this.students = students;
} public ClassRoom(String name) {
this.name = name;
} public ClassRoom() {}
/*
* public ClassRoom(int id,String name) { this.id=id; this.name = name; }
*/ // 互相关联的方法
public void addStudent(Student student) {
student.setRoom(this);
this.students.add(student);
} @Override
public String toString() {
return "ClassRoom [id=" + id + ", name=" + name + "]";
} }

测试类:

    //一对多插入测试
@Test
public void oneToManyInsert() {
Session session=rtn();
session.getTransaction().begin();
//创建对象
Student s1=new Student("乔克","A01010");
Student s2=new Student("小明","A01012");
ClassRoom classRoom=new ClassRoom("就业班");
//进行互相关联
classRoom.addStudent(s1);
classRoom.addStudent(s2);//在addStudent()中进行了互相关联 这里直接调用这个方法即完成了互相关联
//进行持久化操作
session.save(classRoom);
session.getTransaction().commit();
}

然后查看数据库:

可以看到  只对classRoom表进行了数据的插入   可以我们在实体中明明配置了级联保存的操作啊   同时也进行了互相的关联  为啥会出现这种情况呢?

还记得学习JPA时级联操作触发的时机吗?----》如果使用javax.persistence.*里面的注解,只有调用相应的方法才生效,如PERSIST,只有调用persist方法才生效

所以这里当然不能实现级联了

https://blog.csdn.net/l1028386804/article/details/17686229

https://blog.csdn.net/z69183787/article/details/22327725

第一种测试:

根据网上说的情况  我了试试  如果把ClassRoom中的级联属性配置为以下的情况:

CascadeType.PESIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH

也不能进行级联保存,但是,如果配置为CascadeType.All则可以级联保存成功,说明

JPA中的CascadeType.ALL并不等于{CascadeType.PESIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH}

第二种测试:

然后我把级联属性设置成了上面说的那种方式save_update   注意  导入的是hibernate.annotation中的包  而不再是jpa中的级联包了

roomClass中的级联方式修改为:

测试结果:

级联保存成功,所以这里需要明白,hibernate注解开发 设置级联时不能使用jpa规范中的级联方式,而只能是使用自己提供的级联方式,如下:

---------------------------------------

上面进行了插入测试,下面我们进行查询测试:

可见只查询了一次数据库,在查询student对象(多方)  立即查询一方数据

因为我们在student中是这样配置的

抓取方式  在ManyToOne情况下  默认直接加载了一方属性  如果改为下面的配置方式:

执行查询  观察打印的sql

可以看到  是发送了两次sql查询  同样  在执行查询一方属性时  不指定查询方式时   默认是懒加载多方属性的  这里就不再执行了

需要注意的一点是:在查询某个实体的时候  需要在该实体中配置一个无参数的构造方法    比如  我把student实体中的无参构造删除掉  然后执行查询

所以  因为框架中好多地方都会用到无参构造  在我们创建有参构造的时候  记得把无参构造也写出来。

---------------------------------------------------------------

annotation配置many-to-one单向

student

package org.model.om.danxiang;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; @Entity
@Table(name = "danxiang_student")
public class Student {
private int id;
private String name;
private String stuNo;
// 一方的属性
private ClassRoom room; @Id
@GeneratedValue()
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 5, nullable = false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Column(length = 10, nullable = false)
public String getStuNo() {
return stuNo;
} public void setStuNo(String stuNo) {
this.stuNo = stuNo;
} // optional=false 外键字段不能为空 即每个学生都必须有对应的班级 默认为true
// ManyToOne 查询student 默认使用即时加载
//使用hibernate自己的级联方式
@ManyToOne()
//@Cascade({CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
// 在维护端 指定外键字段名 也可以不写 默认属性_id
@JoinColumn(name = "cid")
public ClassRoom getRoom() {
return room;
} public void setRoom(ClassRoom classRoom) {
this.room = classRoom;
} public Student() {
} // 互相关联的方法
public Student(String name, String stuNo) {
this.name = name;
this.stuNo = stuNo;
} @Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + room.toString() + "]";
} }

classRoom

package org.model.om.danxiang;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; //一方 被维护端
@Entity
@Table(name = "danxiang_classroom")
public class ClassRoom {
private int id;
private String name;
/*
// 多方的集合属性
private Set<Student> students = new HashSet<Student>();*/ @Id
@GeneratedValue()
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 10, nullable = false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
/*
// mappedBy属性:由集合中对应的实体Student中的classroom属性来维护外键 声明mappedBy的实体为被维护方
// 抓取方式 onetoMany 默认为lazy加载
//使用hibernate自己的级联方式
@OneToMany(mappedBy = "room")
@Cascade({CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
public Set<Student> getStudents() {
return students;
} public void setStudents(Set<Student> students) {
this.students = students;
}*/ public ClassRoom(String name) {
this.name = name;
} public ClassRoom() {}
/*
* public ClassRoom(int id,String name) { this.id=id; this.name = name; }
*/ /*
// 互相关联的方法
public void addStudent(Student student) {
student.setRoom(this);
this.students.add(student);
}*/ @Override
public String toString() {
return "ClassRoom [id=" + id + ", name=" + name + "]";
} }

测试:

    //单向  一方classroom中不创建集合   只在多方student中创建一方对象 ---》 测试成功
//所以 单向方式操作时 只能是:在多方对象中创建一方对象属性 在一方中省略创建多方的集合属性 反之则不行 比如测试2
@Test
public void oneToManyInsertDanXiang() {
Session session=rtn();
session.getTransaction().begin();
//创建对象
org.model.om.danxiang.Student s1=new org.model.om.danxiang.Student("乔克","A01010");
org.model.om.danxiang.Student s2=new org.model.om.danxiang.Student("乔克2","A01012"); org.model.om.danxiang.ClassRoom classRoom=new org.model.om.danxiang.ClassRoom("就业班");
//进行互相关联
s1.setRoom(classRoom);
s2.setRoom(classRoom);
//保存
session.save(classRoom);//保存的顺序无关
session.save(s1);
session.save(s2); //classRoom.addStudent(s1);
//classRoom.addStudent(s2);//在addStudent()中进行了互相关联 这里直接调用这个方法即完成了互相关联
//进行持久化操作
session.save(classRoom);
session.getTransaction().commit();
}

查询测试:

    //单向查询
@Test
public void oneToManyInsertDanXiangQuery() {
Session session=rtn();
//查询多方 观察是否同时查询一方数据
org.model.om.danxiang.Student student = session.get(org.model.om.danxiang.Student.class,67);
System.out.println(student);
}

单向关系,查询多方的时候,可以顺带查询一方的数据   但是不能通过查询一方同时获得多方的数据   但是双向关系就可以  查询ClassRoom时  可以选择即使加载或者懒加载多方属性   然后通过ClassRoom中的students属性就可以得到多方集合数据

-----------------------------------------------

openSession和getCurrentSession的区别:

使用getCurrentSession时  出现下面错误  是因为没有开启事务

开启事务  就可以解决该问题

---------------------------------------------------

 annotation配置many-to-one双向

Person

package org.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; //一对一双向实体 person作为维护方
@Entity
@Table(name = "t_person")
public class Person {
private int id;// 主键
private String name;// 姓名
private IDCard idCard; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} // 这里暂时不配置 数据库默认字段为name 可以为空 长度255
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @OneToOne
@JoinColumn(name = "cardid")
@Cascade(value = { CascadeType.ALL })
public IDCard getIdCard() {
return idCard;
} public void setIdCard(IDCard idCard) {
this.idCard = idCard;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", idCard=" + idCard + "]";
} }

IDCard

package org.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; //一对一双向实体
@Entity
@Table(name = "t_card")
public class IDCard {
private int id;// 主键
private String no;// 编号
private Person person; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getNo() {
return no;
} public void setNo(String no) {
this.no = no;
} @OneToOne(mappedBy = "idCard")
@Cascade(value = { CascadeType.ALL })
public Person getPerson() {
return person;
} public void setPerson(Person person) {
this.person = person;
} @Override
public String toString() {
return "IDCard [id=" + id + ", no=" + no + ", person=" + person + "]";
} }

测试

//一对一双向关联
@Test
public void oneToOne() {
Session session=rtn();
session.getTransaction().begin();
//创建person对象
Person p=new Person();
p.setName("张三");
//创建IDCard对象
IDCard idCard=new IDCard();
idCard.setNo("xx1");
//进行相互关联
/**
* 如果没有配置级联保存的话 那么需要相互关联 并且还要分别保存
p.setIdCard(idCard);
idCard.setPerson(p);
session.save(idCard);
session.save(p);
*/
//配置级联之后
p.setIdCard(idCard);
session.save(p);
session.getTransaction().commit();
session.close();
}

数据库:

-------------------------------------

annotation配置many-to-many

user

package org.model.mm.shuangxiang;

import java.util.Date;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name="mm_user")
//规定该实体为外键维护方
public class User {
private int id;
private String username;
private String password;
private String nickname;
private Date bornDate;
private Set<Role> roles;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(length=10,nullable=false)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column(length=10,nullable=false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(length=10,nullable=false)
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Temporal(TemporalType.TIMESTAMP)//日期 时间 yyyy-dd-mm HH:MM:SS
public Date getBornDate() {
return bornDate;
}
public void setBornDate(Date bornDate) {
this.bornDate = bornDate;
}
//以m打头 默认加载方式为lazy
@ManyToMany()
@Cascade(value= {CascadeType.ALL})
/**
@JoinTable(
name="u_r",//中间表名称
joinColumns=@JoinColumn(name="uid"),//本实体在中间表中创建的字段名
inverseJoinColumns= @JoinColumn(name="rid"))//关联实体在中间表中创建的字段名
//以上内容可以省略不写 有默认值
*/
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public User(String username, String password, String nickname, Date bornDate) {
super();
this.username = username;
this.password = password;
this.nickname = nickname;
this.bornDate = bornDate;
}
public User() {} }

role

package org.model.mm.shuangxiang;

import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; @Entity
@Table(name = "mm_role")
public class Role {
private int id;
private String name;
private Set<User> users;
@Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
}
@Column(length=10,nullable=false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
@ManyToMany(mappedBy="roles")
@Cascade(value= {CascadeType.ALL})
public Set<User> getUsers() {
return users;
} public void setUsers(Set<User> users) {
this.users = users;
} @Override
public String toString() {
return "Role [id=" + id + ", name=" + name + ", users=" + users + "]";
} public Role(String name) {
super();
this.name = name;
}
public Role() {} }

测试:

//多对多不拆分
@Test
public void manyToMany() {
Session session=rtn();
session.getTransaction().begin();
//创建user对象
org.model.mm.shuangxiang.User user1=new org.model.mm.shuangxiang.User("zhang","123","小张",new Date());
//org.model.mm.shuangxiang.User user2=new org.model.mm.shuangxiang.User("wang","123","小王",new Date());
//org.model.mm.shuangxiang.User user3=new org.model.mm.shuangxiang.User("sun","123","小孙",new Date()); //创建role对象
Role role1=new Role("总监");
Role role2=new Role("保安");
Role role3=new Role("菜鸟");
//创建集合
Set<Role> roles=new HashSet<Role>();
roles.add(role1);
roles.add(role2);
roles.add(role3);
//进行关联
user1.setRoles(roles);
//保存user对象
session.save(user1);
session.getTransaction().commit();
session.close();
}

数据库:

-----------------------------------------

 annotation配置many-to-many变种  拆分为两个一对多

Student

package org.model.mm.shuangxiang2;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; @Entity
@Table(name = "mm_student")
public class Student {
private int id;
private String name;
private String stuNo;
private Set<StudentCourse> tcs; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 10, nullable = false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Column(length = 10, nullable = false)
public String getStuNo() {
return stuNo;
} public void setStuNo(String stuNo) {
this.stuNo = stuNo;
} // 与中间表相比 是一方 被维护端
@OneToMany(mappedBy = "student")
@Cascade(value = { CascadeType.ALL })
public Set<StudentCourse> getTcs() {
return tcs;
} public void setTcs(Set<StudentCourse> tcs) {
this.tcs = tcs;
} public Student() {
} public Student(String name, String stuNo) {
this.name = name;
this.stuNo = stuNo;
}
}

Course

package org.model.mm.shuangxiang2;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; @Entity
@Table(name = "mm_course")
public class Course {
private int id;
private String name;
private Set<StudentCourse> tcs; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 10, nullable = false)
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} // 是一方 被维护端
@OneToMany(mappedBy = "course")
@Cascade(value = { CascadeType.ALL })
public Set<StudentCourse> getTcs() {
return tcs;
} public void setTcs(Set<StudentCourse> tcs) {
this.tcs = tcs;
} public Course() {
} public Course(String name) {
this.name = name;
} }

中间实体  StudentCourse

package org.model.mm.shuangxiang2;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; @Entity
@Table(name = "mm_SC") // 指定中间表名称
public class StudentCourse {
private int id;
private double score;
private Student student;
private Course course; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Column(length = 5, nullable = false)
public double getScore() {
return score;
} public void setScore(double score) {
this.score = score;
} // 多方维护外键 指定中间表外键名称为student_ID
@ManyToOne()
@Cascade(value = { CascadeType.ALL })
@JoinColumn(name = "student_ID")
public Student getStudent() {
return student;
} public void setStudent(Student student) {
this.student = student;
} // 多方维护外键 指定中间表外键名称为course_ID
@ManyToOne()
@Cascade(value = { CascadeType.ALL })
@JoinColumn(name = "course_ID") // 多方作为维护端
public Course getCourse() {
return course;
} public void setCourse(Course course) {
this.course = course;
} public StudentCourse(double score, Student student, Course course) {
super();
this.score = score;
this.student = student;
this.course = course;
} public StudentCourse() {
} }

配置文件中引入:

测试:

//多对多  拆分为两个一对多
@Test
public void manyToMany2() {
Session session=rtn();
session.getTransaction().begin();
//创建2个student对象
org.model.mm.shuangxiang2.Student student1=new org.model.mm.shuangxiang2.Student("zhang","141164000");
org.model.mm.shuangxiang2.Student student2=new org.model.mm.shuangxiang2.Student("wang","141164888");
//创建2个course对象
Course course1=new Course("java");
Course course2=new Course("php");
//创建studentCourse对象 把创建的student course加入进去
//学生1的两门课成绩
StudentCourse sc1=new StudentCourse(88.5,student1,course1);
StudentCourse sc2=new StudentCourse(99.5,student1,course2);
//学生2的两门课成绩
StudentCourse sc3=new StudentCourse(66.5,student2,course1);
StudentCourse sc4=new StudentCourse(49.5,student2,course2);
//保存维护端对象 studentcourse
session.save(sc1);
session.save(sc2);
session.save(sc3);
session.save(sc4);
session.getTransaction().commit();
session.close();
}

数据库:

-------------------------------------

Hibernate基于注解annotation的配置的更多相关文章

  1. Struts2基于注解的Action配置

    使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...

  2. 缓存初解(五)---SpringMVC基于注解的缓存配置--web应用实例

    之前为大家介绍了如何使用spring注解来进行缓存配置 (EHCache 和 OSCache)的简单的例子,详见 Spring基于注解的缓存配置--EHCache AND OSCache 现在介绍一下 ...

  3. 缓存初解(三)---Spring3.0基于注解的缓存配置+Ehcache和OScache

    本文将构建一个普通工程来说明spring注解缓存的使用方式,关于如何在web应用中使用注解缓存,请参见: Spring基于注解的缓存配置--web应用实例 一.简介 在spring的modules包中 ...

  4. 8 -- 深入使用Spring -- 4...5 AOP代理:基于注解的“零配置”方式

    8.4.5 基于注解的“零配置”方式 AspectJ允许使用注解定义切面.切入点和增强处理,而Spring框架则可识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5 一样的 ...

  5. 基于注解的形式配置Bean

    基于注解的方式配置Bean:也就说我们在每个Bean的类名前面注解一下,Spring会自动帮我们扫描Bean放进IOC容器中 I基于注解的方式配置Bean(没有依赖关系的Bean)有两个步骤: 1组件 ...

  6. 10 Spring框架--基于注解的IOC配置

    1.工程环境搭建 2.基于注解的IOC配置 IOC注解的分类 (1)用于创建对象的 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的@Component: 作用: ...

  7. spring-第十七篇之spring AOP基于注解的零配置方式

    1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...

  8. 基于注解的bean配置

    基于注解的bean配置,主要是进行applicationContext.xml配置.DAO层类注解.Service层类注解. 1.在applicationContext.xml文件中配置信息如下 &l ...

  9. hibernate基于注解的维护权反转:@OneToMany(mappedBy=)

    背景说明:首先是SSH环境下,对象基于注解的方式映射到数据库: 昨天遇到一个比较纠结的问题,@OneToMany(mappedBy="xxx"), mappedBy属性有什么用,然 ...

随机推荐

  1. bzoj 1601 灌水

    题目大意: 决定把水灌到n块农田,农田被数字1到n标记 把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库 建造一个水库需要花费wi,连接两块土地需要花费Pij. 计算所需的最少代价 ...

  2. IDEA Spark Streaming Flume数据源 --解决无法转化为实际输入数据,及中文乱码(Scala)

    需要三步: 1.shell:往 1234 端口写数据 nc localhost 1234 2.shell: 启动flume服务 cd /usr/local2/flume/bin ./flume-ng ...

  3. PCB 加投率计算实现基本原理--K最近邻算法(KNN)

    PCB行业中,客户订购5000pcs,在投料时不会直接投5000pcs,因为实际在生产过程不可避免的造成PCB报废, 所以在生产前需计划多投一定比例的板板, 例:订单 量是5000pcs,加投3%,那 ...

  4. P1452 Beauty Contest

    传送门 求凸包周长,用旋转卡壳,具体可见yyb大佬的博客 顺便一提这题暴力+随机化也能过 暴力代码 //minamoto #include<bits/stdc++.h> #define r ...

  5. [Swift通天遁地]五、高级扩展-(14)扩展String快速计算字符串中的各种数学表达式

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. keystone身份认证服务

    Keystone介绍 keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户权限的定义等等.云 ...

  7. Scaffold-DbContext-EFCore DB First

    在使用 Scaffold-DbContext迁移数据库的时候会遇到两个问题. 一.文件已存在,其实报错很明显,增加 -force即可. 二.大小写转换,不和数据库一样了,如果要保持和数据库一致.增加  ...

  8. $P5269 欧稳欧再次学车$

    \(problem\) 哇 看各位巨佬都来发\(T1\)的题解 我也来发一篇.(别的题目不会别瞎bb) 题目大意就是 \(T\) 秒 能走多少路程 第一行六个整数 \(T,N,L,R,X,K\) 接下 ...

  9. 安卓中Canvas实现清屏效果

    可以在代码里面添加: paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawPaint(paint) ...

  10. UNIX环境高级编程--5

    标准I/O库流和FILE对象:    所有I/O函数都是围绕文件描述符的.当打开一个文件时,即返回一个文件描述符,然后该文件描述符就用于后续的I/O操作.当用标准I/O库打开或者创建一个文件时,我们已 ...