关联映射

映射实体Bean的关联关系

一对一(One-to-one)

使用@OneToOne注解可以建立实体bean之间的一对一的关联. 一对一关联有三种情况: 一是关联的实体都共享同样的主键, 二是其中一个实体通过外键关联到另一个实体的主键 (注意要模拟一对一关联必须在外键列上添加唯一约束). 三是通过关联表来保存两个实体之间的连接关系 (注意要模拟一对一关联必须在每一个外键上添加唯一约束).

1,共享主键来进行一对一关联映射:

使用注解@PrimaryKeyJoinColumn定义了一对一关联.

@OneToOne(cascade = CascadeType.ALL)

@PrimaryKeyJoinColumn

 

2, 使用外键列进行实体的关联.

@Entity

public class Customer implements Serializable {

    @OneToOne(cascade = CascadeType.ALL)

    @JoinColumn(name="passport_fk")

    public Passport getPassport() {

        ...

    }

 

@Entity

public class Passport implements Serializable {

    @OneToOne(mappedBy = "passport")

    public Customer getOwner() {

    ...

}

 

上面这个例子中,Customer 通过Customer 表中名为的passport_fk 外键列和 Passport关联. @JoinColumn注解定义了联接列(join column). 该注解和@Column注解有点类似, 但是多了一个名为referencedColumnName的参数. 该参数定义了所关联目标实体中的联接列. 注意,当referencedColumnName关联到非主键列的时候, 关联的目标类必须实现Serializable, 还要注意的是所映射的属性对应单个列(否则映射无效).

一对一关联可能是双向的.在双向关联中, 有且仅有一端是作为主体(owner)端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性. 在上面这个例子中,mappedBy的值为 passport. 最后,不必也不能再在被关联端(ownedside)定义联接列了,因为已经在主体端进行了声明.

如果在主体没有声明@JoinColumn,系统自动进行处理: 在主表(owner table)中将创建联接列, 列名为:主体的关联属性名+下划线+被关联端的主键列名. 在上面这个例子中是passport_id,因为Customer中关联属性名为passport, Passport的主键是id.

多对一(Many-to-one)

在实体属性一级使用@ManyToOne注解来定义多对一关联:

@Entity()

public class Flight implements Serializable {

    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )

    @JoinColumn(name="COMP_ID")

    public Company getCompany() {

        return company;

    }

    ...

}

其中@JoinColumn是可选的,关联字段默认值和一对一 (one to one)关联的情况相似, 列名为:主体的关联属性名+下划线+被关联端的主键列名. 在这个例子中是company_id,因为关联的属性是company, Company的主键是id.

一对多(One-to-many)

在属性级使用 @OneToMany注解可定义一对多关联.一对多关联可以是双向关联.

双向(Bidirectional)

@Entity

public class Troop {

    @OneToMany(mappedBy="troop")

    public Set<Soldier> getSoldiers() {

    ...

}

 

@Entity

public class Soldier {

    @ManyToOne

    @JoinColumn(name="troop_fk")

    public Troop getTroop() {

    ...

}  

 单向(Unidirectional)

@Entity

public class Customer implements Serializable {

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)

    @JoinColumn(name="CUST_ID")

    public Set<Ticket> getTickets() {

    ...

}

 

@Entity

public class Ticket implements Serializable {

    ... //no bidir

}

 

Customer 通过 CUST_ID列和Ticket 建立了单向关联关系

通过关联表处理单向关联

@Entity

public class Trainer {

    @OneToMany

    @JoinTable(

            name="TrainedMonkeys",

            joinColumns = { @JoinColumn( name="trainer_id") },

            inverseJoinColumns = @JoinColumn( name="monkey_id")

    )

    public Set<Monkey> getTrainedMonkeys() {

    ...

}

 

@Entity

public class Monkey {

    ... //no bidir

}

 

Trainer通过 TrainedMonkeys表和 Monkey 建立了单向关联. 其中外键trainer_id关联到Trainer (joinColumns), 而外键monkey_id关联到 Monkey (inversejoinColumns).

 

多对多(Many-to-many)

你可以通过@ManyToMany注解可定义的多对多关联. 同时,你也需要通过注解@JoinTable描述关联表和关联条件. 如果是双向关联,其中一段必须定义为owner,另一端必须定义为inverse(在对关联表进行更新操作时这一端将被忽略):

@Entity

public class Store {

    @ManyToMany(cascade = CascadeType.PERSIST)

    public Set<City> getImplantedIn() {

        ...

    }

}

 

@Entity

public class City {

    ... //no bidirectional relationship

}

 

 

双向

@Entity

public class Store {

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})

    public Set<Customer> getCustomers() {

        ...

    }

}

 

@Entity

public class Customer {

    @ManyToMany(mappedBy="customers")

    public Set<Store> getStores() {

        ...

    }

}

  

 这里常用的方法是生成中间表。配置了级联映射后,不会直接去操作中间表,而是通过操作主表去间接操作中间表。中间表的增、删、改都是通过主表的update实现的,如下面例子:用户添加权限或更新,则Role role=sessin.get(Role.class,rid);user.setRole(role);如果是删除权限,直接Role role=new Role()即可。中间表的查找操作则是主表的get方法来获取。如获取用户权限,直接user.getRole()。

举例:用户权限登录:

一个用户只能拥有一个角色,用户和角色为多对一关系,角色和权限为多对多关系。

1、实体类:

(1、)用户

package com.ifytek.domain;

import java.util.ArrayList;
import java.util.List;

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.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name="userlogin")
@SequenceGenerator(name="seq_userlogin",sequenceName="seq_userlogin",allocationSize=1)
public class User {
	
	private int id;
	private String name;
	private String pwd;
	private String realname;
	private String sex;
	private String birthday;
	private String idnum;
	private String phone;
	private String email;
	private Role role=new Role();
	@ManyToOne
	@JoinTable(name = "user_role", joinColumns = {
			@JoinColumn(name = "lid") }, inverseJoinColumns = @JoinColumn(name = "rid"))
	public Role getRole() {
		return role;
	}
	public void setRole(Role role) {
		this.role = role;
	}
	
	
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO,generator="seq_userlogin")
	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;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getRealname() {
		return realname;
	}
	public void setRealname(String realname) {
		this.realname = realname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}
	public String getIdnum() {
		return idnum;
	}
	public void setIdnum(String idnum) {
		this.idnum = idnum;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	@Override
	public String toString() {
		return "User [name=" + name + "]";
	}
	

	
}
(2、)角色:

package com.ifytek.domain;

import java.io.Serializable;
import javax.persistence.JoinColumn;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="t_role")
public class Role implements Serializable{
	
private int id;
private String name;
private List<Menu> menulist=new ArrayList<>();
private List<User> user=new ArrayList<>();
@OneToMany(mappedBy="role",fetch=FetchType.EAGER)
public List<User> getUser() {
	return user;
}
public void setUser(List<User> user) {
	this.user = user;
}
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="role_menu",joinColumns=@JoinColumn(name="rid"),inverseJoinColumns=@JoinColumn(name="mid"))
public List<Menu> getMenulist() {
	return menulist;
}
public void setMenulist(List<Menu> menulist) {
	this.menulist = menulist;
}
@Id
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;
}
@Override
public String toString() {
	return "Role [id=" + id + ", name=" + name + ", menulist=" + menulist + ", user=" + user + "]";
}

}

(3、)权限(即菜单):

package com.ifytek.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name="menu")
public class Menu implements Serializable{
	
	private int id;
	private int pid;
	private String urls;
	private String name;
	
	private ArrayList<Menu> children = new ArrayList<>();
	private List<Role> role=new ArrayList<>();
	
  //  @ManyToMany(mappedBy="menulist")
	public List<Role> getRole() {
		return role;
	}

	public void setRole(List<Role> role) {
		this.role = role;
	}
	@Id
	public int getId() {
		return id;
	}

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

	public int getPid() {
		return pid;
	}

	public void setPid(int pid) {
		this.pid = pid;
	}

	public String getUrls() {
		return urls;
	}

	public void setUrls(String urls) {
		this.urls = urls;
	}
	@Transient
	public ArrayList<Menu> getChildren() {
		return children;
	}

	public void setChildren(ArrayList<Menu> children) {
		this.children = children;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

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

	public Menu(int id, int pid, String urls, String name) {
		//super();
		this.id = id;
		this.pid = pid;
		this.urls = urls;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Menu [name=" + name + "]";
	}

	

}

2、前台

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="assets/themes/default/easyui.css">
		<link rel="stylesheet" type="text/css" href="assets/themes/icon.css">
		<link rel="stylesheet" type="text/css" href="assets/css/all.css">
		<script type="text/javascript" src="assets/jquery.min.js"></script>
		<script type="text/javascript" src="assets/jquery.easyui.min.js"></script>
<script>

	
			$(function(){
				$("form").submit(function(){
					var dt=$("form").serialize();
					$.post("login",dt,function(data){
						//alert(data);
						if(data=="登录成功"){
							
							window.location.href="main";
						}else{
							alert(data);
						}
					});
					return false;
				})
			})
		</script>
<style type="text/css">
* {
	margin: 0;
	padding: 0;
}

.container {
	width: 80%;
	margin: 0 auto;
}

#header {
	width: 1130px;
	height: 100px;
	background-color: darkgrey;
	margin: 0 auto;
	text-align: center;
}

#content {
	width: 1130px;
	margin: 0 auto;
}

#left {
	width: 700px;
	height: 650px;
	background-color: white;
	float: left;
}

#right {
	height: 650px;
	float: left;
	width: 430px;
	background-color: lightgray;
}

form {
	width: 80%;
	margin: 0 auto;
	margin-top: 200px;
}

form input {
	margin-top: 20px;
	height: 40px;
	font-size: 20px;
	width: 300px;
}
.registerdiv{
width:500px;
height:500px;
background-color: wheat;
position: absolute;
top:100px;
left:200px;
}
.left_top{
width:100%;
height:10%}

.left_mid{
width:100%;
height:50%;
//background-color: #0099FF;}
.dg{

width: 100%;
height: 100%;
}
.left_bottom{
width:100%;
height:50%;
//background-color: #0099FF;}
.img{
width:100%;
height:100%;}

.header1{
height:15%;}
.header2{
height:85%;
float:left;}
</style>
</head>

<body>
	<div id="header">
	<div class="header1"><h1>欢迎使用设备报修系统</h1></div>
		
		<div class="header2"><iframe allowtransparency="true" frameborder="0" width="385" height="96" scrolling="no" src="//tianqi.2345.com/plugin/widget/index.htm?s=1&z=1&t=0&v=0&d=3&bd=0&k=&f=<f=009944&htf=cc0000&q=1&e=1&a=1&c=71879&w=385&h=96&align=left"></iframe>
		</div>
		
	</div>
	<div id="content">
		<div id="left">
			
			
			<!-- <div class="left_bottom">  -->
<img src="assets/img/main.png" class="img">



		</div>
		
		<!-- 登录 -->
		<div id="right" name="right" class="right">
			<form method="post">
				<input type="text" name="username" placeholder="请输入用户名" /><br /> <input
					type="password" name="pwd" placeholder="请输入密码" /><br /> <input
					type="text" name="authcode" placeholder="请输入验证码" /> <img
					src="getImg" οnclick="this.src='getImg?authCode=' + Math.random();"
					> <br /> <input type="submit" value="登录" /><br>
				
				<a href='register' >还没有账号,马上注册</a>
			</form>

		</div>
	</div>




</body>

</html>

首页:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>欢迎</title>
		<link rel="stylesheet" href="assets/css/zTreeStyle/zTreeStyle.css" type="text/css">
		<link rel="stylesheet" href="assets/css/home.css" type="text/css">
		<script type="text/javascript" src="assets/js/jquery-1.4.4.min.js"></script>
		<script type="text/javascript" src="assets/js/jquery.ztree.core.js"></script>
		<style>
			.box {
				position: absolute;
				top: 200px;
				left: 200px;
				width: 300px;
				height: 300px;
				display: none;
				border: 1px solid antiquewhite;
			}
			
			input {
				margin: 20px;
			}
			
			a {
				text-decoration: none;
			}
			
			.div1 {
				float: right;
				margin: 2px;
			}
			
			.div2 {
				float: right;
				margin: 2px;
			}
			
			.box {
				height: 350px;
				top: 0px
			}
		</style>
		<SCRIPT type="text/javascript">
			var setting = {
				view: {
					dblClickExpand: false,
					showLine: true,
					selectedMulti: false,
					showIcon: true,
					addDiyDom: addDiyDom
				},
				async: {
					enable: true,
					url: "getmenu", //请求树形组件
				},
				callback: {
					beforeClick: function(treeId, treeNode) {
						var zTree = $.fn.zTree.getZTreeObj("treeDemo");
						if(treeNode.isParent) {
							zTree.expandNode(treeNode);
							return false;
						} else {
							demoIframe.attr("src", treeNode.urls);
							return true;
						}
					}
				}
			};
			$(document).ready(function() {
				var t = $("#treeDemo");
				$.fn.zTree.init(t, setting);
				demoIframe = $("#testIframe");
				demoIframe.bind("load", loadReady);
			});

			function loadReady() {
				var bodyH = demoIframe.contents().find("body").get(0).scrollHeight,
					htmlH = demoIframe.contents().find("html").get(0).scrollHeight,
					maxH = Math.max(bodyH, htmlH),
					minH = Math.min(bodyH, htmlH),
					h = demoIframe.height() >= maxH ? minH : maxH;
				if(h < 530) h = 530;
				demoIframe.height(h);
			}

			function addDiyDom(treeId, treeNode) {
				var spaceWidth = 5;
				var switchObj = $("#" + treeNode.tId + "_switch"),
					icoObj = $("#" + treeNode.tId + "_ico");
				switchObj.remove();
				icoObj.before(switchObj);

				if(treeNode.level > 1) {
					var spaceStr = "<span style='display: inline-block;width:" + (spaceWidth * treeNode.level) + "px'></span>";
					switchObj.before(spaceStr);
				}
			}

			var name;
			$.post("main", function(data) {
				name = data;
				$("#name").html(data);
			})

			function exit() {
				var a = confirm("确定退出吗?");
				if(a) {
					window.location.href = "exit";
				}

			}
			//隐藏的修改密码div
			function msgbox(n) {
				if(n == 0) {
					$(".box").css("display", "none");
				} else {
					$(".box").css("display", "block");
				}
			}

			function updatepwd() {
				msgbox(1);
			}

			function fun() {
				var bepwd = $("#bepwd").val();
				var npwd = $("#npwd").val();
				var npwd1 = $("#npwd1").val();
				if(bepwd == "" || npwd == "" || npwd1 == "") {
					alert("密码不可以为空");
				} else if(npwd != npwd1) {
					alert("两次输入密码不相等");
				} else {
					var dt = "&name=" + name + "&pwd=" + npwd;
					$.post("updatepwd", dt, function(data) {
						alert(data);
						if(data=="修改成功"){
							window.location.href = "exit";
						}
					})
				}
			}
		</SCRIPT>
	</head>

	<body>
		<div id="header">
			<div class="div1">
				<a href="exit" target="_top">退出登录</a>
			</div>
			<div class="div2"><button οnclick="updatepwd()">修改密码</button></div>
			<h1>欢迎您,<div id="name" ></h1></div>

		<!-- 修改密码div -->
		<div class="box">
			<a class='x' href='' ; οnclick="msgbox(0); return false;">关闭</a><br> 原 密 码:
			<input type="password" name="bepwd" id="bepwd" /><br /> 新 密 码:
			<input type="password" name="npwd" id="npwd" /><br /> 确认密码:
			<input type="password" name="npwd1" id="npwd1" /><br />
			<input type="button" value="提交" οnclick="fun()" />
		</div>
	</div>

		<div id="content">
			<TABLE border=0 height=650px align=left>
				<TR>
					<TD width=260px align=left valign=top style="BORDER-RIGHT: #999999 1px dashed">
						<ul id="treeDemo" class="ztree" style="width:260px; overflow:auto;"></ul>
					</TD>
					<TD width=1130px align=left valign=top>
						<IFRAME ID="testIframe" Name="testIframe" FRAMEBORDER=0 SCROLLING=AUTO width=100% height=700px SRC="welcome"></IFRAME>
					</TD>
				</TR>
			</TABLE>
		</div>
	</body>

</html>
3、后台:

package com.ifytek.controller;

import java.io.IOException;

import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.ifytek.domain.Message;
import com.ifytek.domain.User;

import com.ifytek.service.UserService;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
	

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("login post");
		req.setCharacterEncoding("utf-8");
		resp.setContentType("text/html;charset=utf-8");
		
        	String username = req.getParameter("username");
    		String pwd = req.getParameter("pwd");
    		String code = req.getParameter("authcode");
    		String authcode = (String) req.getSession().getAttribute("authCode");
    		User user = new User();
    		user.setName(username);
    		user.setPwd(pwd);
    		if (authcode.equals(code)) {
    			UserService service=new UserService();
    			Message message = service.checkLogin(user);
    			System.out.println(message.getMsg());
    			if(message.isRes()){
    				HttpSession httpSession=req.getSession();
    				httpSession.setAttribute("username", username);
    				username=URLEncoder.encode(username, "utf-8");
    				
    				Cookie cookie=new Cookie("username", username);
    				cookie.setMaxAge(60*60);
    				resp.addCookie(cookie);
    			}
    			resp.getWriter().write(message.getMsg());
    		} else {
    			resp.getWriter().write("验证码错误");
    		}
        }  
		
		
		
		
	}


package com.ifytek.controller;

import java.io.IOException;


import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import com.ifytek.service.UserService;

@WebServlet("/getmenu")
public class GetMenuServlet extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		resp.setContentType("text/html;charset=utf-8");
		HttpSession session=req.getSession();
		String username=(String) session.getAttribute("username");
		UserService service=new UserService();
		String menujson=service.getMenuJson(username);
		//System.out.println(menujson);
		resp.getWriter().write(menujson);
	}
}
4、获取树形组件service:

public String getMenuJson(String username) {
		UserDao dao=new UserDao();
		int uid=getIdByName(username);
		List<Menu> menus = dao.getMenuByUserId(uid);
		System.out.println("获取的list集合为"+menus);
		System.out.println("获取的list集合长度为"+menus.size());
		ArrayList<Menu> fmenu = new ArrayList<>();
		for (Menu menu : menus) {
			if (menu.getPid() == 0) {
				// 一级菜单
				//System.out.println("..." + menu.getId());
				//System.out.println("一级菜单:  " + menu.getName());
				fmenu.add(menu);
			} else {
				// 非一级菜单

			}
		}
		for (Menu menu : menus) {
			if (menu.getPid() != 0) {
				//System.out.println("。。。" + menu.getId());
				for (Menu fm : fmenu) {
					if (menu.getPid() == fm.getId()) {
						fm.getChildren().add(menu);
					}
				}
			}
		}
		System.out.println(fmenu);
		String json=JSON.toJSONString(fmenu,true);
		return json;
	}

dao:

public List<Menu> getMenuByUserId(int uid) {
		//System.out.println("用户id为"+uid);
		Session session=HibernateUtil.getSessionFactory().openSession();
		
		String hql="from User u where u.id=?";
		Query query=session.createQuery(hql);
		query.setInteger(0, uid);
		User user=(User) query.uniqueResult();
		List<Menu> list=(List<Menu>) user.getRole().getMenulist();
		//ArrayList<Menu> list= (ArrayList<Menu>) ;
		//System.out.println("list为"+list.size());
		session.close();
		return list;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值