2019北京培训:JDBC之MVC分层封装开发(MVC思想极其重要)

本文深入探讨MVC设计思想及SSM框架(Spring+SpringMVC+MyBatis)的应用,通过具体实例讲解如何分层设计提高代码复用性,减少冗余。详细介绍了MVC各层的作用及实现,包括DAO层、Service层和Controller层,并提供了基于JDBC的数据库操作封装。

MVC设计思想遵循开闭原则,SSM框架Spring+SpringMVC+Mvbatis就是MVC设计,提高代码复用性,降低代码冗余。

关于开闭原则的具体知识详情见https://blog.youkuaiyun.com/m2606707610/article/details/86490487

以一个具体的实例来解释一下MVC分层设计思想(如果真的弄明白这个几百行的小实例,将会对理解MVC以及开闭原则设计模式有很大的帮助

关于JDBC的方法的封装都再DBUtils类中,本篇主要提及了MVC设计模式和JDBC数据库操作的通用性封装。

M:model
V:View
C:Controller

包的设计:
com.bjsxt.dao(接口)           数据库层                       Model            
com.bjsxt.dao.impl(实现)                
com.bjsxt.pojo                     实体类层                     Model        
com.bjsxt.service(接口)      业务层                          Model        
com.bjsxt.service.impl(实现)
com.bjsxt.controller            控制层         Controller     程序入口
 总结:所谓MVC分层,其实说白了,就是将本来写在一起的代码,分成不同的功能模块,然后让不同的模块之间相互调用即可。降低代码的冗余,提升代码的重用性。

 

---EMPDao接口

package com.bjsxt.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.bjsxt.pojo.Emp;

public interface EmpDao {
	
		//更新员工信息
		public  int updateEnameByNo(int empno,String ename);
		//根据员工编号删除员工信息
		public int deleteEmpByNo(int empno) ;
		//新增员工信息
		public int addEmopInfo(Emp e);
		//根据员工编号获取员工信息
		public Emp getEmpByNo(int i);
		//查询所有的员工信息
		public List<Emp> getAllEmpInfo();
		
}

---EmpDaoImpl类

package com.bjsxt.dao.impl;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.bjsxt.dao.EmpDao;
import com.bjsxt.pojo.Emp;
import com.bjsxt.util.DBUtil;

public class EmpDaoImpl implements EmpDao{
	
		//更新员工信息
		public  int updateEnameByNo(int empno,String ename) {
			return DBUtil.executeDML("update emp set ename=? where empno=?",ename,empno);
		}
		//根据员工编号删除员工信息
		public int deleteEmpByNo(int empno) {
			return DBUtil.executeDML("delete from emp where empno=?",empno);
		}
		//新增员工信息
		public int addEmopInfo(Emp e) {
			
			java.util.Date date = e.getHiredate();
			java.sql.Date sd=new Date(date.getTime());
			return DBUtil.executeDML("insert into emp values(default,?,?,?,?,?,?,?)",  
					e.getEname(),
					e.getJob(),
					e.getMgr(),
					sd,
					e.getSal(),
					e.getComm(),
					e.getDeptno()
				);
		}
		//根据员工编号获取员工信息
		public Emp getEmpByNo(int i) {
			return DBUtil.executeOne("select * from emp where empno=?",new Emp(),i);
		}

		//查询所有的员工信息
		public List<Emp> getAllEmpInfo() {
			return DBUtil.executeQuery("select * from emp",new Emp(),null);
		}	
		
}

---Emp实体类

package com.bjsxt.pojo;

import java.util.Date;

/**
 * emp表的实体类
 * @author Administrator
 *
 */
public class Emp {
	private Integer empno;
	private String ename;
	private String job;
	private Integer mgr;
	private Date hiredate;
	private Double sal;
	private Double comm;
	private Integer deptno;
	
	
	public Integer getEmpno() {
		return empno;
	}
	public void setEmpno(Integer empno) {
		this.empno = empno;
	}
	public String getEname() {
		return ename;
	}
	public void setEname(String ename) {
		this.ename = ename;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public Integer getMgr() {
		return mgr;
	}
	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}
	public Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}
	public Double getSal() {
		return sal;
	}
	public void setSal(Double sal) {
		this.sal = sal;
	}
	public Double getComm() {
		return comm;
	}
	public void setComm(Double comm) {
		this.comm = comm;
	}
	public Integer getDeptno() {
		return deptno;
	}
	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}
	@Override
	public String toString() {
		return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate
				+ ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + "]";
	}
	public Emp() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double comm,
			Integer deptno) {
		super();
		this.empno = empno;
		this.ename = ename;
		this.job = job;
		this.mgr = mgr;
		this.hiredate = hiredate;
		this.sal = sal;
		this.comm = comm;
		this.deptno = deptno;
	}
		
	
}

---EmpService接口

package com.bjsxt.service;

import java.util.List;

import com.bjsxt.dao.EmpDao;
import com.bjsxt.dao.impl.EmpDaoImpl;
import com.bjsxt.pojo.Emp;

public interface EmpService {

	//查询所有员工信息
	public void getEmpInfoService();
	//根据员工编号查询员工信息
	public void getEmpByNoService(int empno);
	//增加员工信息
	public void  addEmpService(Emp e);
	//删除员工信息
	public void deleteEmpService(int empno);
	//更新员工信息
	public void updateEmpService(int empno,String ename);
}

---EmpServiceImpl类

package com.bjsxt.service.impl;

import java.util.List;

import com.bjsxt.dao.EmpDao;
import com.bjsxt.dao.impl.EmpDaoImpl;
import com.bjsxt.pojo.Emp;
import com.bjsxt.service.EmpService;

public class EmpServiceImpl implements EmpService{
	//创建Dao层对象
	EmpDao ed=new EmpDaoImpl();
	//查询所有员工信息
	public void getEmpInfoService(){
		List<Emp> list = ed.getAllEmpInfo();
		//打印数据到控制台
		System.out.println("员工编号\t员工姓名\t员工工作\t上级领导\t入职日期\t薪资\t奖金\t部门编号\t");
		for(Emp e:list){
			System.out.print(e.getEmpno());
			System.out.print("\t");
			System.out.print(e.getEname());
			System.out.print("\t");
			System.out.print(e.getJob());
			System.out.print("\t");
			System.out.print(e.getMgr());
			System.out.print("\t");
			System.out.print(e.getHiredate());
			System.out.print("\t");
			System.out.print(e.getSal());
			System.out.print("\t");
			System.out.print(e.getComm());
			System.out.print("\t");
			System.out.print(e.getDeptno());
			System.out.println();
		}
	}
	//根据员工编号查询员工信息
	public void getEmpByNoService(int empno){
		
		Emp e=ed.getEmpByNo(empno);
		if(e!=null){
			System.out.println("员工编号\t员工姓名\t员工工作\t上级领导\t入职日期\t薪资\t奖金\t部门编号\t");
			System.out.print(e.getEmpno());
			System.out.print("\t");
			System.out.print(e.getEname());
			System.out.print("\t");
			System.out.print(e.getJob());
			System.out.print("\t");
			System.out.print(e.getMgr());
			System.out.print("\t");
			System.out.print(e.getHiredate());
			System.out.print("\t");
			System.out.print(e.getSal());
			System.out.print("\t");
			System.out.print(e.getComm());
			System.out.print("\t");
			System.out.print(e.getDeptno());
			System.out.println();
		}else{
			System.out.println("员工不存在");
		}
		
	}
	//增加员工信息
	public void  addEmpService(Emp e){
		int i=ed.addEmopInfo(e);
		if(i>0){
			System.out.println("新增成功");
		}else{
			System.out.println("新增失败");
		}
	}
	//删除员工信息
	public void deleteEmpService(int empno){
		int i=ed.deleteEmpByNo(empno);
		if(i>0){
			System.out.println("删除成功");
		}else{
			System.out.println("删除失败");
		}
		
	}
	//更新员工信息
		public void updateEmpService(int empno,String ename){
			int i=ed.updateEnameByNo(empno,ename);
			if(i>0){
				System.out.println("更新成功");
			}else{
				System.out.println("更新失败");
			}
			
		}
	
	
	
}

---TestEmp类

package com.bjsxt.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;

import com.bjsxt.pojo.Emp;
import com.bjsxt.service.EmpService;
import com.bjsxt.service.impl.EmpServiceImpl;

/**
 * 
 * 尚学堂之员工管理系统实现
 * 
 *
 */
public class TestEmp {
	public static void main(String[] args) throws ParseException {

		Scanner sc=new Scanner(System.in);
		//创建业务层对象
		EmpService es=new EmpServiceImpl();
		while(true){
		//实现员工管理系统的菜单
		System.out.println("********************************************");
		System.out.println("1、查询所有员工信息");
		System.out.println("2、根据编号查询员工信息");
		System.out.println("3、删除员工信息");
		System.out.println("4、更新员工信息");
		System.out.println("5、增加员工信息");
		System.out.println("6、退出");
		System.out.println("********************************************");
		System.out.println("请输入你的选择:");
		int choice = sc.nextInt();
		switch (choice) {
				case 1:
					//1、查询所有的员工信息
					es.getEmpInfoService();
					break;
				case 2:
					//2、根据员工编号获取员工信息
					System.out.println("请输入员工编号:");
					int empno=sc.nextInt();
					es.getEmpByNoService(empno);	
					break;
				case 3:
					//3、根据编号删除员工信息
					System.out.println("请输入要删除的员工编号:");
					int empno2 = sc.nextInt();
					es.deleteEmpService(empno2);
					break;
				case 4:
					//4、根据编号更新员工姓名	
					System.out.println("请输入要更新的员工编号:");
					int empno3=sc.nextInt();
					System.out.println("请输入要更新的姓名:");
					String ename3=sc.next();
					es.updateEmpService(empno3, ename3);
					break;
				case 5:
					//5、新增员工信息
					//获取员工信息
					System.out.println("请输入员工姓名:");
						String ename = sc.next();
					System.out.println("请输入员工岗位:");
						String job = sc.next();
					System.out.println("请输入上级:");
						int mgr = sc.nextInt();
					System.out.println("请输入入职日期(yyyy-mm-dd):");
						String hiredate = sc.next();
						//将字符串转换为日期
						SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
						java.util.Date ud = sdf.parse(hiredate);
					System.out.println("请输入薪资:");
						double sal = sc.nextDouble();
					System.out.println("请输入奖金:");
						double comm= sc.nextDouble();
					System.out.println("请输入部门编号:");
						int deptno = sc.nextInt();
					//创建Emp对象
					Emp e=new Emp();
					e.setEname(ename);
					e.setJob(job);
					e.setMgr(mgr);
					e.setHiredate(ud);
					e.setSal(sal);
					e.setComm(comm);
					e.setDeptno(deptno);
					es.addEmpService(e);	
					break;
				case 6:
					System.out.println("退出成功,谢谢使用");
					return;
				default:
					System.out.println("输入有误,请重新输入");
					break;
			}
		}
	}
	
}

---DBUtils封装工具类

package com.bjsxt.util;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import com.bjsxt.pojo.Emp;

public class DBUtil {
	//声明属性记录jdbc链接参数
		private static String driver;
		private static String url;
		private static String username;
		private static String password;
	//声明静态代码块儿
		static{
			//动态获取编译目录下的文件的流对象
			InputStream in = DBUtil.class.getResourceAsStream("/db.properties");
			//创建Properties对象,读取properties文件类型的内容。
			Properties p=new Properties();
			try {
				//加载   该句代码执行完毕后,配置文件中的数据已经被p对象所获取并存储。
				p.load(in);
				//获取p对象中的数据并赋值给属性
				driver=p.getProperty("driver");
				url=p.getProperty("url");
				username=p.getProperty("username");
				password=p.getProperty("password");
				//加载驱动
				Class.forName(driver);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	//获取Connection对象的方法
		public static Connection getConnection(){		
			Connection conn=null;
			try {
				//获取链接
					conn=DriverManager.getConnection(url,username,password);
				} catch (SQLException e) {
					e.printStackTrace();
			}
			return conn;
		}
	//封装公共增删改查方法
		public static int executeDML(String sql,Object...objs){
			
			//声明jdbc遍历
			Connection conn=null;
			PreparedStatement ps=null;
			try {
				//获取链接
				conn=getConnection();
				//开启事务
					conn.setAutoCommit(false);
				//创建Sql命令对象
					ps=conn.prepareStatement(sql);
				//给占位符赋值
					if(objs!=null){
						for(int i=0;i<objs.length;i++){
							ps.setObject(i+1,objs[i]);
						}
					}
				//执行
					int i = ps.executeUpdate();
					if(i>0){
						conn.commit();
					}
				//返回结果
					return i;
				
			} catch (Exception e) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
				e.printStackTrace();
			}finally {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			return -1;
		}
	//封装公共查询方法:针对结果为一条
		public static <T> T executeOne(String sql,T t,Object...objs){
			T t2=null;
			//声明jdbc变量
			Connection conn=null;
			PreparedStatement ps=null;
			ResultSet rs=null;
			try {
				//获取链接
				conn=DBUtil.getConnection();
				//创建Sql命令对象
				ps=conn.prepareStatement(sql);
				//给占位符赋值
				if(objs!=null){
					for(int i=0;i<objs.length;i++){
						ps.setObject(i+1,objs[i]);
					}
					
				}
				//执行
				rs=ps.executeQuery();
				//获取结果集的结构 
				ResultSetMetaData rm = rs.getMetaData();//rm对象中存储了结果表中的字段的名字和字段的java类型
				int count = rm.getColumnCount();//获取列的数量
				
				//遍历
				while(rs.next()){
					//获取实体类的类对象
						Class cla = t.getClass();
						t2 = (T) cla.newInstance();
					//获取数据
						for(int i=0;i<count;i++){
							//获取列名
							String columnName = rm.getColumnName(i+1);
							//拼接方法名
							String methodName="set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
							//获取字段类型
							String columnClassName = rm.getColumnClassName(i+1);// "java.lang.Integer"  "java.lang.String"
							Method m=null;
							if("java.sql.Date".equals(columnClassName)){
								 m=cla.getDeclaredMethod(methodName, Class.forName("java.util.Date"));
							}else{
								//反射获取方法对象
								 m=cla.getDeclaredMethod(methodName, Class.forName(columnClassName));
							}
							//执行方法
							m.invoke(t2, rs.getObject(columnName));
							//System.out.println(columnName+"---"+methodName+"---"+columnClassName);
						}
				}
				//关闭资源
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			return t2;
		}
	//封装公共查询方法:针对查询结果为多条
		public static <T> List<T> executeQuery(String sql,T t,Object...objs){
			//声明list集合
			List<T> list=null;
			//声明jdbc变量
			Connection conn=null;
			PreparedStatement ps=null;
			ResultSet rs=null;
			try {
				//获取链接
				conn=DBUtil.getConnection();
				//创建Sql命令对象
				ps=conn.prepareStatement(sql);
				//给占位符赋值
				if(objs!=null){
					for(int i=0;i<objs.length;i++){
						ps.setObject(i+1,objs[i]);
					}
					
				}
				//执行
				rs=ps.executeQuery();
				//获取结果集的结构 
				ResultSetMetaData rm = rs.getMetaData();//rm对象中存储了结果表中的字段的名字和字段的java类型
				int count = rm.getColumnCount();//获取列的数量
				//给list赋值
				list=new ArrayList<>();
				//遍历
				while(rs.next()){
					//获取实体类的类对象
						Class cla = t.getClass();
						T newInstance = (T) cla.newInstance();
					//获取数据
						for(int i=0;i<count;i++){
							//获取列名
							String columnName = rm.getColumnName(i+1);
							//拼接方法名
							String methodName="set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
							//获取字段类型
							String columnClassName = rm.getColumnClassName(i+1);// "java.lang.Integer"  "java.lang.String"
							Method m=null;
							if("java.sql.Date".equals(columnClassName)){
								 m=cla.getDeclaredMethod(methodName, Class.forName("java.util.Date"));
							}else{
								//反射获取方法对象
								 m=cla.getDeclaredMethod(methodName, Class.forName(columnClassName));
							}
							//执行方法
							m.invoke(newInstance, rs.getObject(columnName));
							//System.out.println(columnName+"---"+methodName+"---"+columnClassName);
						}
					//添加集合
					list.add(newInstance);
				}
				//关闭资源
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			return list;
			

			
		}
		

		
}

---db.properties配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/505
username=root
password=1234

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值