• Hibernate关联关系的CRUD


    本文以Group和User(一对多、多对一)双向关联为例,介绍关联关系的CRUD

    下面先介绍两个属性

    cascade:只影响CRUD中的CUD,即存储(save)、更新(update)、删除(delete)
    
    fetch:只影响CRUD中的R,即读取(get、load)
    cascade(级联):
    
    此属性仅仅帮助我们简化编程,不是必选项
    
    如果A和B为单向关联,则在主导方设置cascade属性
    
    如果A和B为双向关联,则在双方都要设置cascade属性
    
    
    如果两个对象之间有关联关系,比如User和Group多对一关联
    
    如果想要保存User的时候自动保存Group,可在User类的@ManyToOne注解中设置cascade(级联)属性
    
    反过来,如果想要保存Group的时候自动保存User,可在Group类的@OneToMany注解中设置cascade(级联)属性
    对于User(多方)和Group(一方)
    
    执行如下语句
     
    User u = (User) session.get(User.class, 1);
    
    在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置.相当于设置@ManyToOne(fetch=FetchType.EAGER)
    
    反过来,取一方对象的时候,则不会把多方对象取出
    
    若想要在取出一方对象g的同时取出多方对象,则应在Group类的@OneToMany注解中设置fetch属性
    @OneToMany注解中fetch的默认值为FetchType.LAZY, 相当于设置@OneToMany(fetch=FetchType.LAZY) 
    
    fetch的取值有两个
    
    fetch=FetchType.EAGER :执行语句就取出
    
    fetch=FetchType.LAZY :用的时候才取出
    
    两者的区别类似于get和load的区别
     
    
    注意:对于双向关联,不要两边都设EAGER(会有多余的查询语句发出),可以都设LAZY
    
    一般是多对一设置EAGER,一对多设置LAZY

    建Group实体类和User实体类,以及Junit测试类

    @Entity
    @Table(name="_group")
    public class Group {
    	private int id;
    	private String name;
    	private Set<User> users = new HashSet<User>();
    	@Id
    	@GeneratedValue
    	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;
    	}
    	@OneToMany(mappedBy="group")
    	public Set<User> getUsers() {
    		return users;
    	}
    	public void setUsers(Set<User> users) {
    		this.users = users;
    	}
    }
    @Entity
    @Table(name="_user")
    public class User {
    	private int id;
    	private String name;
    	private Group group;
    	@Id
    	@GeneratedValue
    	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;
    	}
    	@ManyToOne
    	public Group getGroup() {
    		return group;
    	}
    	public void setGroup(Group group) {
    		this.group = group;
    	}
    }
    public class ORMappingTest {
    	
    	private static SessionFactory sf = null;
    	
    	@BeforeClass
    	public static void beforeClass(){
    		sf = new Configuration().configure().buildSessionFactory();
    	}
    	
    	@AfterClass
    	public static void afterClass(){
    		sf.close();
    	}
    	
    	@Test
    	public void test() {
    
    		//下面将会完善此test()方法
    			
    	}	
    }

    接下来开始CRUD的练习

    首先在Group类和User类的@OneToMany和@ManyToOne注解中添加cascade属性

    //Group类    此处fetch属性中,LAZY为默认值,故也可不写
    @OneToMany(mappedBy="group",cascade={CascadeType.ALL},fetch=FetchType.LAZY)
    public Set<User> getUsers() {
        return users;
    }
    //User类    此处fetch属性中,EAGER为默认值,故也可不写
    @ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
    public Group getGroup() {
        return group;
    }

    然后,完善Junit测试类的test()方法

    CRUD----C   增   session.save()

    1.保存User对象的同时自动保存Group对象

    @Test
    public void test() {
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    		
    	Group g = new Group();
    	g.setName("lisi");
    		
    	User u = new User();
    	u.setName("user1");
    	u.setGroup(g);
    		
    	session.save(u);   //因为在User类的@ManyToOne注解中设置了cascade(级联)属性,故只需保存User对象即可,Group对象会自动保存
    		
    	session.getTransaction().commit();		
    }

    2.保存Group对象的同时自动保存User对象

    @Test
    public void test() {
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    		
    	User u1 = new User();
    	User u2 = new User();
    		
    	Group g = new Group();
    		
    	u1.setName("user1");
    	u1.setGroup(g);
    	u2.setName("user2");
    	u2.setGroup(g);
    		
    	g.setName("group1");
    	g.getUsers().add(u1);
    	g.getUsers().add(u2);
    	
    	session.save(g);   //因为在Group类的@OneToMany注解中设置了cascade(级联)属性,故只需保存Group对象即可,User对象会自动保存
    		
    	session.getTransaction().commit();		
    }

    CRUD----R   查   session.get()和session.load()

    1.取出User对象的同时取出Group对象

    @Test
    public void test() {
    			
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    		
    	User u = (User) session.get(User.class, 1);   //在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置
    	System.out.println(u.getGroup().getName());   //打印输出_group表中对应的name值
    			
    	session.getTransaction().commit();		
    }

    2.取出Group对象的同时取出User对象

    @Test
    public void test() {
    				
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    		
    	Group g = (Group) session.get(Group.class, 2); //在取出一方对象g的同时取出多方对象,此时应在Group类的@OneToMany注解中设置fetch属性
    	for(User u : g.getUsers()){
    		System.out.println(u.getId()+","+u.getName());  //打印输出_user表中的相关数据
    	}
    		
    	session.getTransaction().commit();		
    }

    CRUD----U   改   session.update()

    通过取出的User对象,既可以更改User对象中的属性名字,也可以更改与其级联的Group对象中的属性名字

    @Test
    public void test {
    	
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    	
    	User u = (User) session.get(User.class, 3);   //在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置
    	u.setName("name");                            //更改User对象中的属性名字
    	u.getGroup().setName("Groupname");            //也可以更改与其级联的Group对象中的属性名字
    	session.update(u);
    	
    	session.getTransaction().commit();		
    }

    CRUD----D   删   session.delete()

    删除User表中的某一条记录

    两种方式,如下:

    @Test
    public void testDelete() {
    	
    	Session session = sf.getCurrentSession();
    	session.beginTransaction();
    	
    	//删除User表中id值为1的记录
    	User u = (User) session.get(User.class, 1);   //在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置
    	u.setGroup(null);                             //应该先消除关联关系,再删除对应记录
    	session.delete(u);                            //如果直接删除,由于设置了cascade属性,则会删除Group和User中相关的所有数据      
    	
    	//删除User表中id值为2的记录
    	session.createQuery("delete from User u where u.id=2").executeUpdate();
    	
    	session.getTransaction().commit();		
    }
  • 相关阅读:
    Struts1简单开发流程梳理
    更改数据库字符集编码引起的问题、textarea标签输出内容时不能顶格(左对齐)输出
    FineReport基本使用
    Navicat for MySQL笔记1
    Hibernate(十)
    Elasticsearch NEST 控制字段名称命名格式
    ckeditor 敏感词标记显示处理方法
    Elasticsearch .Net Client NEST 多条件查询示例
    Elasticsearch .Net Client NEST 索引DataSet数据
    一个很简单的SqlServer生成常用C#语句工具的诞生
  • 原文地址:https://www.cnblogs.com/weilunhui/p/3900176.html
Copyright © 2020-2023  润新知