CSDN话题挑战赛第2期
参赛话题:学习笔记
学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢?
设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。而MVC(Model View Controller,模型-视图-控制器)是JavaWeb中常用的一种设计模式,用于应用程序的分层开发——将封装数据的模型、显示用户界面的视图、协调调度的控制器分开,实现各个组件耦合降低与单独维护,方便于前后端对接。
MVC设计模式与MVC框架的区别:
打个比方,MVC设计模式是设计师手中的图纸;MVC框架是工程师以设计师的图纸建造出来的产品。MVC一般指的是MVC框架。
其中,MVC(Model View Controller,模型-视图-控制器)如下:
Model层:是一个存取数据的对象或 JAVA POJO。一般包括业务逻辑层Service与数据访问层Dao。Service主要是用作将从Controller层获取的数据和数据库的数据进行桥接;Dao主要是用作对数据库操作的封装。
View层:是页面的显示,与用户进行交互。
Controller层:作用于模型和视图上。它控制数据流向Model层,并在数据变化时更新View层。它使Model层与View层分离开。
基于MVC设计模式的Web应用程序的处理流程如图:首先,用户在客户端(浏览器)中发起请求,然后HTTP请求传给Controller层中对应的Servlet,再由Servlet负责调用Model层中的业务逻辑层进行业务逻辑处理,其后业务逻辑层通过调用数据访问层的方法进行对数据的操作,最后由业务逻辑层将结果返回给Controller层,Controller层将数据变化时更新View层,View层将结果响应给用户。
基于 Java Web 与 MVC 的学生信息管理的 Web 应用例子:
其中,实现了对MySQL数据库的student表的增删改查。通过姓名可以进行模糊查询也可以直接点击查询全部学生信息;点击添加跳转到添加学生信息页面,学号自增,其他信息手动添加,错误添加将会在控制台进行反馈;点击修改跳转到修改学生信息页面,错误修改也会在控制台进行反馈;点击删除,弹出确认框再次确定便会删除。另外,管理员登录后期会进行实现,同时也会对其他页面进行简单的设计与美化。
定义一个JDBCUtils类,数据库的连接:
package cn.edu.MVCcase.JDBC.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
//JDBC工具类
public class JDBCUtils {
//数据库连接池C3P0,需导入c3p0、mchange.jar包
private static DataSource dataSource = null;
//静态代码块
static {
//对应c3p0-config的named-config的name
dataSource = new ComboPooledDataSource("MySQL");
}
//数据库MySQL连接
public static Connection getCon() {
Connection con = null;
try {
con = dataSource.getConnection();
return con;
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//关闭数据库连接
public static void closeCon(Connection con) {
if(con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//回滚事务
public static void rollbackTransation(Connection con) {
if (con != null) {
try {
con.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
测试:
package cn.edu.MVCcase.Test.test;
import cn.edu.MVCcase.JDBC.utils.JDBCUtils;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
//数据库连接测试
public class JDBCutilsTest {
@Test
void TestGetCon () {
Connection con = JDBCUtils.getCon();
System.out.println(con);
}
}
在 model包中,定义一个与数据库student表相映射的学生类Student:
package cn.edu.MVCcase.Model.model;
public class Student {
private int id ; //学号
private String name ; //姓名
private String sex ; //性别
private String grade ; //班级
private String telephone ; //手机号
public Student() {
super();
}
public Student(int id, String name, String sex, String grade, String telephone) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.grade = grade;
this.telephone = telephone;
}
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", grade='" + grade + '\'' +
", telephone='" + telephone + '\'' +
'}';
}
}
在dao包中,首先,定义一个泛型CurrencyDao,通过类型参数来实现代码复用以提高代码的编写效率。
再定义一个接口StudentDao,声明一系列操作学生信息的方法:
package cn.edu.MVCcase.Model.dao;
import cn.edu.MVCcase.Model.model.Student;
import java.sql.Connection;
import java.util.List;
//接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现
//创建接口实现类,按 alt+enter
public interface StudentDao {
//添加学生信息的方法
public int Add(Student student);
//删除学生信息的方法
public int Delete(int id);
//修改学生信息的方法
public int Update(Student student);
//不支持事务,查询学生信息的方法,获取一条用户数据,封装成类Student的一个对象
public Student Select(int id);
//支持事务
public Student Select(Connection con,int id);
//查询学生全部信息的方法
public List<Student> List();
//获取指定学生姓名的条数
public long CountName(String name);
//通过姓名进行模糊查询
public List<Student> List(String name);
}
最后创建这个接口的实现类StudentDaoImpl:
package cn.edu.MVCcase.Model.dao;
import cn.edu.MVCcase.Model.model.Student;
import java.sql.Connection;
import java.util.List;
//StudentDao接口的实现类
//StudentDaoImpl实现类的测试类,按 alt+insert
public class StudentDaoImpl extends CurrencyDao<Student> implements StudentDao {
@Override
public int Add(Student student) {
String sql = "INSERT INTO `student` (`name`,`sex`,`grade`,`telephone`) VALUES (?,?,?,?);";
return super.TableOperation(sql,student.getName(),student.getSex(),student.getGrade(),student.getTelephone());
}
@Override
public int Delete(int id){
String sql = "DELETE FROM `student` WHERE `id`=?;";
return super.TableOperation(sql,id);
}
@Override
public int Update(Student student){
String sql = "UPDATE `student` SET `name`=?,`sex`=?,`grade`=?,`telephone`=? WHERE `id`=?;";
return super.TableOperation(sql,student.getName(),student.getSex(),student.getGrade(),student.getTelephone(),student.getId());
}
//不支持事务
@Override
public Student Select(int id) {
String sql = "SELECT `id`,`name`,`sex`,`grade`,`telephone` FROM `student` WHERE `id`=?;";
return super.getSelect(sql,id);
}
//支持事务
@Override
public Student Select(Connection con,int id) {
String sql = "SELECT `id`,`name`,`sex`,`grade`,`telephone` FROM `student` WHERE `id`=?;";
return super.getSelect(con,sql,id);
}
@Override
public List<Student> List() {
String sql = "SELECT `id`,`name`,`sex`,`grade`,`telephone` FROM `student`;";
return super.getList(sql);
}
@Override
public long CountName(String name){
String sql = "SELECT COUNT(`id`) FROM `student` WHERE `name`=?;";
return (int)super.getCount(sql,name);
}
@Override
public List<Student> List(String name) {
String sql = "SELECT `id`,`name`,`sex`,`grade`,`telephone` FROM `student` WHERE 1=1 ";
if(name != null && !"".equals(name)) {
sql = sql + " AND name like '%"+name+"%'"; //拼接成SQL语句,存在注入攻击风险(用户恶意注入特殊字符)
}
return super.getList(sql);
}
}
另外,定义一个类FactoryDao,解耦,降低模块间的依赖性,提高程序的独立性:
package cn.edu.MVCcase.Model.dao;
public class FactoryDao {
public static StudentDao getStudentDao() {
return new StudentDaoImpl();
}
}
在service包中,首先,定义一个接口StudentService,然后,同样地,创建一个接口的实现类与定义一个类FactoryService。service层的方法相较于dao层的方法是在基础的操作上又增加了一层包装的,实现的是相对高级的操作。
package cn.edu.MVCcase.Model.service;
import cn.edu.MVCcase.Model.model.Student;
import java.util.List;
public interface StudentService {
//添加学生信息的方法
public int Add(Student student);
//删除学生信息的方法
public int Delete(int id);
//修改学生信息的方法
public int Update(Student student);
//不支持事务,查询学生信息的方法,获取一条用户数据,封装成类Student的一个对象
public Student Select(int id);
//支持事务
public Student SelectTransation(int id);
//查询学生全部信息的方法
public List<Student> List();
//获取指定学生姓名的条数
public long CountName(String name);
//通过姓名进行模糊查询
public List<Student> List(String name);
}
如图是需要用到的jar包,同时需要add to build path : File – Project Structure… – Libraies – 点击“加号” – Java – 选择好你项目中lib下的驱动jar包 – ok