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