三层结构解释:
视图层:主要是用于与用户进行交互,比如接收用户输入的内容将返回结果向用户展示等。
业务逻辑层:实现每个功能的特定的逻辑方法。
数据访问层:主要是与数据库进行连接,然后对数据库进行增删改查工作。
包的层级结构:
三层结构目录架构:
命名规则为公司域名反写 eg:com.li.xxx
bean:存放JavaBean,一张表对应一个类,一个字段对应一个属性
dao:存放连接数据库及对数据库进行增删改查的操作的接口
dao.impl:存放dao接口的实现类
service:存放逻辑层的接口
service.impl:存放逻辑层的接口的实现类
view:用户交互层的接口
view.impl:用户交互层的接口的实现类
包内的实现类:
CREATE TABLE `student` (
`Sid` int NOT NULL AUTO_INCREMENT,
`Sname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
`birthday` datetime DEFAULT NULL,
`ssex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '男',
`classid` int DEFAULT NULL,
PRIMARY KEY (`Sid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;
以学生类为例下面是实现代码:
Student的JavaBean:
public class Student {
//JavaBean实体类
private int sid;
private String sname;
private Date birthday;
private String ssex;
private int classid;
public Student(){
}
public Student(int sid,String sname,Date birthday,String ssex,int classid){
this.sid = sid;
this.sname = sname;
this.birthday = birthday;
this.ssex = ssex;
this.classid = classid;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSsex() {
return ssex;
}
public void setSsex(String ssex) {
this.ssex = ssex;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", birthday=" + birthday +
", ssex='" + ssex + '\'' +
", classid=" + classid +
'}';
}
Dao层的接口:
稍作赘述:接口的出现实际上是为了制定规则,代码编写三要素:方法名、参数、返回值类型;而在接口中定义这三个东西然后让子类实现,当某一层未开发时也不影响其他层的开发。
public interface IStudentDao {
//增加
public int addStudent(Student s);
//删除
public int deleteStudent(int sid);
//修改
public int updateStudent(Student s);
//查询
public Student findStudentBySid(int sid);
//全查
public List<Student> findAllStudent();
}
Dao层接口的实现类:
//增加记录
@Override
public int addStudent(Student s) {
Connection conn = null;
PreparedStatement presta = null;
int update = 0;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myschool?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "123456";
conn = DriverManager.getConnection(url, user, pwd);
String sql = "insert into student(sname,birthday,ssex,classid) values (?,?,?,?)";
presta = conn.prepareStatement(sql);
// presta.setObject(1,s.getSid());
presta.setObject(1,s.getSname());
presta.setObject(2,s.getBirthday());
presta.setObject(3,s.getSsex());
presta.setObject(4,s.getClassid());
update = presta.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if (presta != null){
try {
presta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return update;
}
//删除记录
@Override
public int deleteStudent(int sid) {
int update = 0;
PreparedStatement presta = null;
Connection conn = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myschool?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "123456";
conn = DriverManager.getConnection(url, user, pwd);
String sql = "delete from student where sid = ?";
presta = conn.prepareStatement(sql);
presta.setObject(1,sid);
update = presta.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(presta != null){
try {
presta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return update;
}
//修改记录
@Override
public int updateStudent(Student s) {
int update = 0;
PreparedStatement presta = null;
Connection conn = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myschool?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "123456";
conn = DriverManager.getConnection(url, user, pwd);
String sql = "update student set sname = ?,birthday = ? ,ssex = ? ,classid = ? where sid = ?";
presta = conn.prepareStatement(sql);
presta.setObject(1,s.getSname());
presta.setObject(2,s.getBirthday());
presta.setObject(3,s.getSsex());
presta.setObject(4,s.getClassid());
presta.setObject(5,s.getSid());
update = presta.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if (presta != null){
try {
presta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return update;
}
//sid查询
@Override
public Student findStudentBySid(int sid) {
Connection conn = null;
Student student = null;
PreparedStatement statement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myschool?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "123456";
conn = DriverManager.getConnection(url, user, pwd);
String sql = "select * from student where sid = ?";
statement = conn.prepareStatement(sql);
statement.setObject(1,sid);
ResultSet resultSet = statement.executeQuery();
if(resultSet.next()){
student = new Student();
student.setSid(resultSet.getInt("sid"));
student.setSname(resultSet.getString("sname"));
student.setBirthday(resultSet.getDate("birthday"));
student.setSsex(resultSet.getString("ssex"));
student.setClassid(resultSet.getInt("classid"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if (statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return student;
}
//全查
@Override
public List<Student> findAllStudent() {
Connection conn = null;
PreparedStatement statement = null;
List list = new ArrayList();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myschool?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "123456";
conn = DriverManager.getConnection(url, user, pwd);
String sql = "select * from student";
statement = conn.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()){
Student stu = new Student();
stu.setSid(resultSet.getInt("sid"));
stu.setSname(resultSet.getString("sname"));
stu.setBirthday(resultSet.getDate("birthday"));
stu.setSsex(resultSet.getString("ssex"));
stu.setClassid(resultSet.getInt("classid"));
list.add(stu);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if (statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return list;
}
service层的接口:
public interface IStudentService {
//注册(添加字段)
public boolean register(Student s);
//删除学生
public boolean deleteStu(int sid);
//修改学生信息
public boolean modifyStu(Student s);
//Sid查询学生
public Student info(int sid);
//所有学生列表
public List<Student> student();
}
service层的接口的实现类:
//添加学生字段
@Override
public boolean register(Student s) {
boolean isok = false;
IStudentDao isd = new StudentDaoImpl();
int ret = isd.addStudent(s);
if (ret > 0) {
isok = true;
}
return isok;
}
//删除学生字段
@Override
public boolean deleteStu(int sid) {
boolean isok = false;
IStudentDao isd = new StudentDaoImpl();
int ret = isd.deleteStudent(sid);
if (ret > 0){
isok = true;
}
return isok;
}
//修改学生字段
@Override
public boolean modifyStu(Student s) {
boolean isok = false;
IStudentDao isd = new StudentDaoImpl();
int i = isd.updateStudent(s);
if (i > 0){
isok = true;
}
return isok;
}
//Sid查学生字段
@Override
public Student info(int sid) {
IStudentDao isd = new StudentDaoImpl();
Student studentBySid = isd.findStudentBySid(sid);
return studentBySid;
}
//学生字段全查
@Override
public List<Student> student() {
IStudentDao isd = new StudentDaoImpl();
List<Student> allStudent = isd.findAllStudent();
return allStudent;
}
View的是接口:
public interface IStudentView {
//学生的注册
public void showstuadd();
//学生的修改
public void showstumodify();
//学生的全部查询
public void showstuinfo();
//学生的Sid查询
public void showstuinfoSid();
//学生的删除
public void showstudelete();
//学生的菜单
public void showstumenu();
}
View的是接口的实现类:
//学生的注册(添加字段)
@Override
public void showstuadd() {
SimpleDateFormat format = new SimpleDateFormat();
Scanner input = new Scanner(System.in);
System.out.println("添加学生:");
System.out.println("请输入学生姓名");
String sname = input.next();
System.out.println("请输入学生生日");
String bir = input.next();
System.out.println("请输入学生性别");
String sex = input.next();
System.out.println("请输入学生班级");
int classid = input.nextInt();
Student stu = new Student();
stu.setSname(sname);
try {
stu.setBirthday(format.parse(bir));
} catch (ParseException e) {
stu.setBirthday(new Date());
}
stu.setSsex(sex);
stu.setClassid(classid);
IStudentService iss = new StudentServiceImpI();
boolean register = iss.register(stu);
if (register){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
}
//学生的修改
@Override
public void showstumodify() {
SimpleDateFormat format = new SimpleDateFormat();
Scanner input = new Scanner(System.in);
System.out.println("修改学生信息:");
System.out.println("请输入需要修改的学生编号");
int sid = input.nextInt();
System.out.println("请输入学生新姓名");
String sname = input.next();
System.out.println("请输入学生新生日");
String bir = input.next();
System.out.println("请输入学生新性别");
String sex = input.next();
System.out.println("请输入学生新班级");
int classid = input.nextInt();
Student stu = new Student();
stu.setSname(sname);
try {
stu.setBirthday(format.parse(bir));
} catch (ParseException e) {
stu.setBirthday(new Date());
}
stu.setSsex(sex);
stu.setClassid(classid);
stu.setSid(sid);
IStudentService iss = new StudentServiceImpI();
boolean register = iss.modifyStu(stu);
if (register){
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
}
//学生的全部查询
@Override
public void showstuinfo() {
IStudentService iss = new StudentServiceImpI();
List<Student> list = iss.student();
list.forEach(System.out::println);
}
//学生的Sid查询
@Override
public void showstuinfoSid() {
Scanner scan = new Scanner(System.in);
System.out.println("请输入需要查询的ID:");
int i = scan.nextInt();
IStudentService iss = new StudentServiceImpI();
Student info = iss.info(i);
System.out.println(info);
}
//学生的删除
@Override
public void showstudelete() {
Scanner scan = new Scanner(System.in);
System.out.println("请输入要删除学生的ID:");
int anInt = scan.nextInt();
IStudentService iss = new StudentServiceImpI();
boolean deleteStu = iss.deleteStu(anInt);
if (deleteStu){
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
//学生的菜单
@Override
public void showstumenu() {
Scanner input = new Scanner(System.in);
System.out.println("欢迎使用校园系统--学生模块管理");
int key = -1;
do {
System.out.println("输入:\n1.添加学生\n2.根据ID查看信息\n3.查看所有学生\n4.修改学生\n5.开除学生\n0.退出程序");
System.out.println("请输入:");
if(input.hasNextInt()) {
key = input.nextInt();
switch(key) {
case 1:
{
showstuadd();
}
break;
case 2:
{
showstuinfoSid();
}
break;
case 3:
{
showstuinfo();
}
break;
case 4:
{
showstumodify();
}
break;
case 5:
{
showstudelete();
}
break;
default:
System.out.println("请输入正确的序号");
break;
}
}else {
System.out.println("请输入菜单中的序号,否则打死你");
input.next();
}
}while(key != 0);
System.out.println("感谢使用");
}
测试类:
public static void main(String[] args) {
IStudentView isv = new IStudentViewImpI();
isv.showstumenu();
}
结构一中,在DAO层中频繁的进行数据连接创建访问对象等,结构复杂,代码重复率高,因此结构二中对DAO层进行了抽象。
创建DaoUtil类:将加载驱动,获取连接,流的释放进行抽象。
public class DaoUtil {
//加载驱动
//驱动的加载只需加载一次,因此使用静态代码块,当加载此类时,会随着类的加载而加载一次
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConn(){
Connection conn = null;
try {
String url = "jdbc:mysql://localhost:3306/myschool?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "123456";
conn = DriverManager.getConnection(url, user, pwd);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return conn;
}
//关闭连接
public static void closeResource(Connection conn, PreparedStatement prep, ResultSet res){
if (res != null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (prep != null){
try {
prep.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
创建BaseDao:用来存放增删改和查的方法;这里需要注意的是,增删改操作时返回值是int的整数值,表示数据库中的受影响的行数。而查询操作返回的是ResultSet类型的结果,因此需要分开进行写。
public class BaseDao {
protected Connection conn;
protected PreparedStatement prepstat;
protected ResultSet rs;
//增删改
protected int update(String sql,Object...args){
int ret = 0;
try {
conn = DaoUtil.getConn();
prepstat = conn.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
prepstat.setObject(i + 1,args[i]);
}
}
ret = prepstat.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DaoUtil.closeResource(conn, prepstat, rs);
}
return ret;
}
//查询
protected ResultSet query(String sql,Object...args){
ResultSet rs = null;
try {
conn = DaoUtil.getConn();
prepstat = conn.prepareStatement(sql);
if (args != null){
for (int i = 0; i < args.length; i++) {
prepstat.setObject(i + 1,args[i]);
}
}
rs = prepstat.executeQuery();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return rs;
}
}
抽象后的实现类如下:
public class StudentDaoImpl extends BaseDao implements IStudentDao {
//增加记录
@Override
public int addStudent(Student s) {
String sql = "insert into student(sname,birthday,ssex,classid) values (?,?,?,?)";
return update(sql,s.getSname(),s.getBirthday(),s.getSsex(),s.getClass());
}
//删除记录
@Override
public int deleteStudent(int sid) {
String sql = "delete from student where sid = ?";
return update(sql,sid);
}
//修改记录
@Override
public int updateStudent(Student s) {
String sql = "update student set sname = ?,birthday = ? ,ssex = ? ,classid = ? where sid = ?";
return update(sql,s.getSname(),s.getBirthday(),s.getSsex(),s.getClassid(),s.getSid());
}
//sid查询
@Override
public Student findStudentBySid(int sid) {
Student s = null;
SimpleDateFormat format = new SimpleDateFormat();
try {
String sql = "select * from student where sid = ?";
rs = query(sql, sid);
if (rs.next()) {
s = new Student();
s.setSid(rs.getInt("sid"));
s.setSname(rs.getString("sname"));
try {
s.setBirthday(format.parse(rs.getString("birthday")));
} catch (ParseException e) {
e.printStackTrace();
}
s.setSsex(rs.getString("ssex"));
s.setClassid(rs.getInt("classid"));
s.setSid(rs.getInt("sid"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DaoUtil.closeResource(conn, prepstat, rs);
}
return s;
}
//全查
@Override
public List<Student> findAllStudent() {
Student s = null;
List list = new ArrayList();
SimpleDateFormat format = new SimpleDateFormat();
try {
String sql = "select * from student where sid = ?";
rs = query(sql);
if (rs.next()) {
s = new Student();
s.setSid(rs.getInt("sid"));
s.setSname(rs.getString("sname"));
try {
s.setBirthday(format.parse(rs.getString("birthday")));
} catch (ParseException e) {
e.printStackTrace();
}
s.setSsex(rs.getString("ssex"));
s.setClassid(rs.getInt("classid"));
s.setSid(rs.getInt("sid"));
list.add(s);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DaoUtil.closeResource(conn, prepstat, rs);
}
return list;
}
}
不同的分法可能会略微有所区别,划分程度不同,划分的层级可能也不同,但本质思想不变,将代码功能模块化,实现高内聚低耦合,例如Dao用来做数据库连接等操作,就尽量只需调方法传参就能执行即可,不要在执行的过程中还需要其他层数据的介入,主要也是为了开发的高效性,同时便于对代码进行测试。