一、数据表与简单Java类映射
在之前已经给出了简单Java类一定要和数据表的结构对应上,同时外键需要依靠引用来进行关联,于是本次将针对于简单Java类做一个功能上的扩充。
要求通过Java程序描述出dept-emp关系,使用字段:
· dept:deptno、dname、loc;
· emp:empno、ename、job、sal、comm、deptno、mgr。
在dept-emp表的关系里面存在有如下关联:
· 一个部门有多个雇员;
· 一个雇员有一个或零个领导。
第一步:实现基本字段的转换
class Dept {
private int deptno;
private String dname;
private String loc;
public Dept(int dertno, String dname, String loc) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public String getInfo() {
return "部门编号:" + this.deptno + ",名称:" + this.dname + ",位置:" + this.loc;
}
}
class Emp {
private int empno;
private String ename;
private String job;
private double sal;
private double comm;
public Emp(int empno, String ename, String job, double sal, double comm) {
this.empno = empno;
this.ename = ename;
this.job = job;
this.sal = sal;
this.comm = comm;
}
public String getInfo() {
return "雇员编号:" + this.empno + ",姓名:" + this.ename + ",职位:" + this.job + ",工资:" + this.sal + ",佣金:" + this.comm;
}
}
第二步:解决外键关系
· 一个雇员属于一个部门,应该在雇员里面保存部门信息
|-修改Emp类;
private Dept dept;// 表示对应的部门信息
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return this.dept;
}
|-一个部门有多个雇员,如果要描述多这个概念应该使用数组完成,修改Dept类;
private Emp emps[];
public void setEmps(Emp[] emps) {
this.emps = emps;
}
public Emp[] getEmps() {
return this.emps;
}
· 一个雇员有一个领导
private Emp mgr;//表示雇员对应的领导
public void setMgr(Emp mgr) {
this.mgr = mgr;
}
public Emp getMgr() {
return this.mgr;
}
所有的匹配映射关系都已成功描述出来。
第三步:设置并取得数据
对于这种映射的方式一定要分两步完成,第一步根据结构设置数据,第二步根据结构取出数据。
· 设置数据
public class TestDemo {
public static void main(String args[]) {
// 第一步:设置数据
// 1、产生各自的独立对象
Dept dept = new Dept(10, "ACCOUNTING", "New York");// 部门信息
Emp ea = new Emp(7369, "SMITH", "CLERK", 800.0, 0.0);// 雇员信息
Emp eb = new Emp(7905, "FORD", "MANAGER", 2450.0, 0.0);// 雇员信息
Emp ec = new Emp(4230, "KING", "PRESIDENT", 5000.0, 0.0);// 雇员信息
// 2、设置雇员和领导关系
ea.setMgr(eb);
eb.setMgr(ec);
// 3、设置雇员和部门关系
ea.setDept(dept);// 雇员部门
eb.setDept(dept);// 雇员部门
ec.setDept(dept);// 雇员部门
dept.setEmps(new Emp[] { ea, eb, ec });
}
}
· 取出数据:根据给定的结构取出数据,要求如下:
|-可以根据一个雇员查询他所对应的领导信息和部门信息;
|-可以根据一个部门取出所有雇员以及每个雇员的领导信息;
// 1、通过雇员找到领导信息和部门信息
System.out.println(ea.getInfo());
System.out.println("\t|-" + ea.getMgr().getInfo());
System.out.println("\t|-" + ea.getDept().getInfo());
// 2、根据部门找到所有雇员以及每个雇员的领导信息
System.out.println("-------------------------");
System.out.println(dept.getInfo());
for (int x = 0; x < dept.getEmps().length; x++) {
System.out.println("\t|-" + dept.getEmps()[x].getInfo());
if (dept.getEmps()[x].getMgr() != null) {
System.out.println("\t\t|-" + dept.getEmps()[x].getMgr().getInfo());
}
}
整个代码之中都是依靠代码链进行数据取出的。
二、一对多映射(省份-城市)
第一个面向对象的学习之中就是以数据表与简单Java类的转换操作作为终点,也是下一个起点。
实例:省份:省份ID,名称
城市:城市ID,省份ID,名称
要求:1、可以通过一个城市找到它所对应的省份的信息
2、可以通过一个省份找到所有城市的信息
第一步:先写出基本字段
class Province {
private int pid;
private String name;
public Province(int pid, String name) {
this.pid = pid;
this.name = name;
}
public String getInfo() {
return "省份编号:" + this.pid + ",省份名称:" + this.name;
}
}
class City {
private int cid;
private String name;
public City(int cid, String name) {
this.cid = cid;
this.name = name;
}
public String getInfo() {
return "城市编号:" + this.cid + ",城市名称:" + this.name;
}
}
第二步:设置关联字段(引用)
class Province {
private int pid;
private String name;
private City cities[];
public Province(int pid, String name) {
this.pid = pid;
this.name = name;
}
public void setCities(City cities[]) {
this.cities = cities;
}
public City[] getCities() {
return this.cities;
}
public String getInfo() {
return "省份编号:" + this.pid + ",省份名称:" + this.name;
}
}
class City {
private int cid;
private String name;
private Province province;
public City(int cid, String name) {
this.cid = cid;
this.name = name;
}
public void setProvince(Province province) {
this.province = province;
}
public Province getProvince() {
return this.province;
}
public String getInfo() {
return "城市编号:" + this.cid + ",城市名称:" + this.name;
}
}
第三步:进行代码测试
按照两步完成:设置数据和根据结构取出数据
public class TestPC {
public static void main(String args[]) {
// 第一步:设置关系数据
// 1、设置好各自独立的对象
Province pro = new Province(1, "河北省");
City c1 = new City(1001, "唐山");
City c2 = new City(1002, "秦皇岛");
City c3 = new City(1003, "石家庄");
// 2、设置关系
c1.setProvince(pro);// 一个城市属于一个省份
c2.setProvince(pro);
c3.setProvince(pro);
pro.setCities(new City[] { c1, c2, c3 });// 一个省份包含多个城市
// 第二步:取出关系数据
System.out.println(c2.getProvince().getInfo());
for (int x = 0; x < pro.getCities().length; x++) {
System.out.println("\t" + pro.getCities()[x].getInfo());
}
}
}
以上确实是实现了一个基础的一对多的关系,但是思考一下,以上的代码会存在哪些功能上的不足呢?
· 如果现在想要再增加几个城市,就一定要修改数组的引用关系;
· 如果现在删除了两个城市信息,后面又增加了两个城市信息;
· 要查询某个城市的信息是否存在,遍历数组;
· 查询某一个城市的数组的保存索引号,遍历数组;
· 替换掉某一个城市的内容。
造成所有困难的关键就在于数组的使用上,但是又不能不使用数组。
三、双向一对多映射(类型-子类型-商品)
实例:
类型:类型ID、名称、描述
子类型:子类型ID、类型ID、名称、描述
商品:商品ID、类型ID、子类型ID、名称、价格
要求:
1、可以通过一个类型找到它对应的全部子类型
2、可以通过一个类型找到它所对应的全部商品,以及每个商品所对应的子类型
3、可以通过一个子类型找到所对应的全部商品
不管以后开发多么复杂的关系,按照步骤设计。
第一步:设置基本字段
class Item {// 父栏目
private int iid;
private String name;
private String note;
public Item(int iid, String name, String note) {
this.iid = iid;
this.name = name;
this.note = note;
}
public String getInfo() {
return "栏目标号:" + this.iid + ",名称:" + this.name + ",描述:" + this.note;
}
}
class Subitem {// 子栏目
private int sid;
private String name;
private String note;
public Subitem(int sid, String name, String note) {
this.sid = sid;
this.name = name;
this.note = note;
}
public String getInfo() {
return "子栏目编号:" + this.sid + ",名称:" + this.name + ",描述:" + this.note;
}
}
class Product {// 商品
private int pid;
private String name;
private double price;
public Product(int pid, String name, double price) {
this.pid = pid;
this.name = name;
this.price = price;
}
public String getInfo() {
return "商品编号:" + this.pid + ",名称:" + this.name + ",价格:" + this.price;
}
}
第二步:设置关系
class Item {// 父栏目
private int iid;
private String name;
private String note;
private Subitem subitems[];
private Product products[];
public Item(int iid, String name, String note) {
this.iid = iid;
this.name = name;
this.note = note;
}
public void setSubitems(Subitem subitems[]) {
this.subitems = subitems;
}
public Subitem[] getSubitems() {
return this.subitems;
}
public void setProducts(Product products[]) {
this.products = products;
}
public Product[] getProducts() {
return this.products;
}
public String getInfo() {
return "栏目标号:" + this.iid + ",名称:" + this.name + ",描述:" + this.note;
}
}
class Subitem {// 子栏目
private int sid;
private String name;
private String note;
private Item item;
private Product products[];
public Subitem(int sid, String name, String note) {
this.sid = sid;
this.name = name;
this.note = note;
}
public void setItem(Item item) {
this.item = item;
}
public Item getItem() {
return this.item;
}
public void setProduct(Product products[]) {
this.products = products;
}
public Product[] getProduct() {
return this.products;
}
public String getInfo() {
return "子栏目编号:" + this.sid + ",名称:" + this.name + ",描述:" + this.note;
}
}
class Product {// 商品
private int pid;
private String name;
private double price;
private Item item;
private Subitem subitem;
public Product(int pid, String name, double price) {
this.pid = pid;
this.name = name;
this.price = price;
}
public void setItem(Item item) {
this.item = item;
}
public Item getItem() {
return this.item;
}
public void setSubitem(Subitem subitem) {
this.subitem = subitem;
}
public Subitem getSubitem() {
return this.subitem;
}
public String getInfo() {
return "商品编号:" + this.pid + ",名称:" + this.name + ",价格:" + this.price;
}
}
第三步:设置关系以及数据的取出
public class TestISP {
public static void main(String[] args) {
// 第一步:设置数据信息
// 1、准备出单独的类对象
Item item = new Item(1, "厨房用具", "-");
Subitem suba = new Subitem(1001, "厨具", "-");
Subitem subb = new Subitem(1002, "刀具", "-");
Subitem subc = new Subitem(1002, "餐具", "-");
Product proa = new Product(90001, "蒸锅", 251.0);
Product prob = new Product(90002, "炒锅", 510.0);
Product proc = new Product(90003, "菜刀", 25.0);
Product prod = new Product(90004, "水果刀", 15.0);
Product proe = new Product(90005, "瓷碗", 12.0);
Product prof = new Product(90006, "竹筷子", 5.0);
// 2、设置对象间的引用关系
suba.setItem(item);
subb.setItem(item);
subc.setItem(item);
item.setSubitems(new Subitem[] { suba, subb, subc });
proa.setSubitem(suba);
proa.setItem(item);
prob.setSubitem(suba);
prob.setItem(item);
proc.setSubitem(subb);
proc.setItem(item);
prod.setSubitem(subb);
prod.setItem(item);
proe.setSubitem(subc);
proe.setItem(item);
prof.setSubitem(subc);
prof.setItem(item);
suba.setProducts(new Product[] { proa, prob });
subb.setProducts(new Product[] { proc, prod });
subc.setProducts(new Product[] { proe, prof });
item.setProducts(new Product[] { proa, prob, proc, prod, proe, prof });
// 第二步:取出数据
// 1、通过一个类型找到对应的全部子类型
System.out.println(item.getInfo());
for (int x = 0; x < item.getSubitems().length; x++) {
System.out.println("\t|-" + item.getSubitems()[x].getInfo());
}
System.out.println("-----------------------------------");
// 2、根据一个类型找到全部商品以及子类型
System.out.println(item.getInfo());
for (int x = 0; x < item.getProducts().length; x++) {
System.out.println("\t|-" + item.getProducts()[x].getInfo());
System.out.println("\t|-" + item.getProducts()[x].getSubitem().getInfo());
}
System.out.println("-----------------------------------");
// 3、根据一个子类型找到其对应的商品
System.out.println(subb.getInfo());
for (int x = 0; x < subb.getProducts().length; x++) {
System.out.println("\t|-" + subb.getProducts()[x].getInfo());
}
}
}
在开发之中设置关系的时候,中立的做法是根据类的结构将完整的数据取出来并且配置好引用关系。
四、多对多映射(管理员-角色-组-权限)
实例:
管理员:管理员ID、角色ID、密码、上次登陆时间
角色:角色ID、名称
权限组:权限组ID、名称
权限:权限ID、权限组ID、名称、路径
角色-权限组:角色ID、权限组ID
要求:
可以根据一个管理员找到它所对应的角色,以及每个角色包含的权限组的信息,以及每个权限组所包含的所有权限的内容;
可以根据一个权限组找到所有具备此权限组的角色以及每个角色所拥有的管理员信息;
在本次的设计之中的“角色-权限组”表实际上属于一张关系表,它保存的只是两个外键的关联关系,这样的关系表不需要为其生成映射类。
生成的只能是实体表的转换操作,而多对多的中间转换表只需要通过类属性的关系配置即可。
第一步:生成基本字段映射
class Admin {
private String aid;
private String password;
public Admin(String aid, String password) {
this.aid = aid;
this.password = password;
}
public String getInfo() {
return "管理员编号:" + this.aid + ",密码:" + this.password;
}
}
class Role {
private int rid;
private String title;
public Role(int rid, String title) {
this.rid = rid;
this.title = title;
}
public String getInfo() {
return "角色编号:" + this.rid + ",名称:" + this.title;
}
}
class Group {
private int gid;
private String title;
public Group(int gid, String title) {
this.gid = gid;
this.title = title;
}
public String getInfo() {
return "权限组编号:" + this.gid + ",名称:" + this.title;
}
}
class Action {
private int aid;
private String title;
private String url;
public Action(int aid, String title, String url) {
this.aid = aid;
this.title = title;
this.url = url;
}
public String getInfo() {
return "权限编号:" + this.aid + ",名称:" + this.title + ",路径:" + this.url;
}
}
第二步:设置引用关系
class Admin {
private String aid;
private String password;
private Role role;
public Admin(String aid, String password) {
this.aid = aid;
this.password = password;
}
public void setRole(Role role) {
this.role = role;
}
public Role getRole() {
return this.role;
}
public String getInfo() {
return "管理员编号:" + this.aid + ",密码:" + this.password;
}
}
class Role {
private int rid;
private String title;
private Admin[] admins;
private Group[] groups;
public Role(int rid, String title) {
this.rid = rid;
this.title = title;
}
public void setAdmins(Admin[] admins) {
this.admins = admins;
}
public Admin[] getAdmins() {
return this.admins;
}
public void setGroups(Group[] groups) {
this.groups = groups;
}
public Group[] getGroups() {
return this.groups;
}
public String getInfo() {
return "角色编号:" + this.rid + ",名称:" + this.title;
}
}
class Group {
private int gid;
private String title;
private Role[] role;
private Action[] actions;
public Group(int gid, String title) {
this.gid = gid;
this.title = title;
}
public void setRoles(Role[] role) {
this.role = role;
}
public Role[] getRoles() {
return this.role;
}
public void setActions(Action[] actions) {
this.actions = actions;
}
public Action[] getActions() {
return this.actions;
}
public String getInfo() {
return "权限组编号:" + this.gid + ",名称:" + this.title;
}
}
class Action {
private int aid;
private String title;
private String url;
private Group group;
public Group getGroup() {
return this.group;
}
public void setGroup(Group group) {
this.group = group;
}
public Action(int aid, String title, String url) {
this.aid = aid;
this.title = title;
this.url = url;
}
public String getInfo() {
return "权限编码:" + this.aid + ",名称:" + this.title + ",路径:" + this.url;
}
}
实际上一对多和多对多从类的定义上来讲区别不是很大。
第三步:设置并取得数据
public class TestAdmin {
public static void main(String[] args) {
// 第一步:设置完整关系
// 1.准备若干个对象
Admin a1 = new Admin("admin", "hello");
Admin a2 = new Admin("jing", "hello");
Admin a3 = new Admin("yv", "hello");
Role r1 = new Role(1, "系统管理员");
Role r2 = new Role(2, "信息管理员");
Group g1 = new Group(10, "信息管理");
Group g2 = new Group(11, "用户管理");
Group g3 = new Group(12, "数据管理");
Group g4 = new Group(13, "接口管理");
Group g5 = new Group(14, "备份管理");
Action at01 = new Action(1001, "新闻发布", "-");
Action at02 = new Action(1002, "新闻列表", "-");
Action at03 = new Action(1003, "新闻审核", "-");
Action at04 = new Action(1004, "增加用户", "-");
Action at05 = new Action(1005, "用户列表", "-");
Action at06 = new Action(1006, "登陆日志", "-");
Action at07 = new Action(1007, "雇员数据", "-");
Action at08 = new Action(1008, "部门数据", "-");
Action at09 = new Action(1009, "公司数据", "-");
Action at10 = new Action(1010, "服务传输", "-");
Action at11 = new Action(1011, "短信平台", "-");
Action at12 = new Action(1012, "全部备份", "-");
Action at13 = new Action(1013, "局部备份", "-");
// 2.设置这些对象的关系
// 设置管理员与角色
a1.setRole(r1);
a2.setRole(r2);
a3.setRole(r2);
r1.setAdmins(new Admin[] { a1 });
r2.setAdmins(new Admin[] { a2, a3 });
// 设置角色和管理员组
r1.setGroups(new Group[] { g1, g2, g3, g4, g5 });
r2.setGroups(new Group[] { g1, g2 });
g1.setRoles(new Role[] { r1, r2 });
g2.setRoles(new Role[] { r1, r2 });
g3.setRoles(new Role[] { r1 });
g4.setRoles(new Role[] { r1 });
g5.setRoles(new Role[] { r1 });
// 设置管理员组与权限
g1.setActions(new Action[] { at01, at02, at03 });
g2.setActions(new Action[] { at04, at05, at06 });
g3.setActions(new Action[] { at07, at08, at09 });
g4.setActions(new Action[] { at10, at11 });
g5.setActions(new Action[] { at12, at13 });
at01.setGroup(g1);
at02.setGroup(g1);
at03.setGroup(g1);
at04.setGroup(g2);
at05.setGroup(g2);
at06.setGroup(g2);
at07.setGroup(g3);
at08.setGroup(g3);
at09.setGroup(g3);
at10.setGroup(g4);
at11.setGroup(g4);
at12.setGroup(g5);
at13.setGroup(g5);
// 取出数据
System.out.println("----------------------------------");
System.out.println(a1.getInfo());
System.out.println("\t|-" + a1.getRole().getInfo());
for (int i = 0; i < a1.getRole().getGroups().length; i++) {
System.out.println(a1.getRole().getGroups()[i].getInfo());
for (int j = 0; j < a1.getRole().getGroups()[i].getActions().length; j++) {
System.out.println("\t\t\t|-" + a1.getRole().getGroups()[i].getActions()[j].getInfo());
}
}
System.out.println("-------------------------------");
System.out.println("-------------------------------");
System.out.println(g1.getInfo());
for (int i = 0; i < g1.getRoles().length; i++) {
System.out.println(g1.getRoles()[i].getInfo());
for (int j = 0; j < g1.getRoles()[i].getAdmins().length; j++) {
System.out.println("\t\t|-" + g1.getRoles()[i].getAdmins()[j].getInfo());
}
}
}
}