目录
一、理解程序设计分层的思想
二、DAO设计模式的组成以及各部分的开发
2.1 概述
2.2 DAO模式作用
2.3 DAO模式组成
三、DAO模式实现图书信息管理系统控制台版本之增删改查
3.1 编写流程
3.2 代码实现
分层的思想在日常生活中随处可见,比如医院中按照科室进行分层,每个科室都是完全独立的,但是也可以与其它科室进行完整的沟通。而本文介绍的程序设计分层也是如此。
DAO(Data Access Object,数据访问对象),主要的功能是用于进行数据操作的,在程序的标准开发框架中属于数据层的操作。
- 隔离业务逻辑代码和数据访问代码
- 隔离不同数据库的实现
java实现数据库连接后增删改查操作如果没有借助分层优化,那是一件很头痛的事情,一个错误需要找很久而且出现的问题也会很多,而DAO模式的出现就是将程序按照特定的规则以及模式将代码进行区分管理,方便使用。区分管理的模式是通过不同的包package来区分。
(1)数据库连接和关闭工具类:避免了数据库连接和关闭代码的重复使用,方便修改。
(2)实体类:用于存放与传输对象数据
(3)DAO接口:把对数据库的所有操作定义为抽象方法,可以提供多种实现
(4)DAO实现类:针对不同数据库给出DAO接口定义方法的具体实现测试测
(5)显示类:处于显示层,显示数据
(6)测试类:测试增删改查等操作
根据上述得知,如需使用DAO模式实现数据库链接后的增删改查,需要在创建项目建立不同的包来管理程序;并且在使用DAO时对包有严格的命名(com.公司名.项目名.模块名)如下格式:
com.公司名.项目名.utils;——数据库连接和关闭工具类
com.公司名.项目名.entity;——用于存放与传输对象数据
com.公司名.项目名.dao;——DAO接口与DAO实现类
com.公司名.项目名.ui;——显示类
com.公司名.项目名.test;——测试类
打开eclipse后,新建Java项目为bookManager,最终的项目文件结构如下:
DBHelper:数据库帮助类(1.加载驱动2.建立数据库连接3.关闭连接)
Book:实体对象,用于存放与传输对象数据。
IBookDao和BookDaoImpl:DAO接口及实现类,主要负责数据的增删改查
建库、建表
创建项目,新建文件夹,命名lib,复制sqljdbc4.jar,右击builder path--add
在指定项目中创建5个包com.公司名.项目名.包名;
工具包 com.zz.bookmanager.utils;
实体包 com.zz.bookmanager.entity;
数据访问层包com.zz.bookmanager.dao;
显示层包com.zz.bookmanager.ui;
测试包com.zz.bookmanager.test;
编写com.zz.bookmanager.utils包,在该包下创建数据库帮助类DBHelper类
com.zz.bookmanager.entity包,在该包下创建实体类Book类
com.zz.bookmanager.dao包,在该包下创建BookDAO类实现增删改查。
com.zz.bookmanager.ui包,在该包下创建UI类调用BookDAO类的增删改查方法。
com.zz.bookmanager.test包,调用UI包中下封装的方法。
1.建库、建表、加数据
--创建图书管理系统 create database db_bookManager_1206; --使用当前数据库 use db_bookManager_1206; --创建图书信息表 create table tb_book ( bid int primary key identity(1,1), bname varchar(200), btype varchar(100), bprice int, bauthor varchar(100), ) insert into tb_book values ('康总爱上霸道女总裁','校园言情',99,'唐三'), ('黄回重回2009','玄幻',99,'邓婷'), ('午夜凶铃','恐怖',99,'廖俊'), ('回到1900','穿越',99,'隔壁老王');
2.创建项目,新建文件夹,命名lib,复制sqljdbc4.jar,右击builder path--add
3.在指定项目中新建5个包
com.zz.bookManager.utils 数据库工具包
com.zz.bookManager.entity 实体包
com.zz.bookManager.dao 数据访问层包
com.zz.bookManager.ui 显示层包
com.zz.bookManager.test 测试包
4.编写com.zz.bookManager.utils包,在该包下创建数据库帮助类DBHelper
package com.zz.bookManager.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; /** * 数据库帮助类 * * @author zz * */ public class DBHelper { private static final String URL = "jdbc:sqlserver://localhost:1433;DatabaseName=db_bookManager_1206"; private static final String USER = "sa"; private static final String PASSWORD = "123"; /** * 加载驱动 */ static { try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); ; } catch (Exception e) { e.printStackTrace(); } } /** * 方法功能:与数据库建立连接 */ public static Connection getConn() { Connection conn = null; try { conn = DriverManager.getConnection(URL, USER, PASSWORD); } catch (Exception e) { e.printStackTrace(); } return conn; } /** * 方法功能:关闭连接 * * @param Connection * conn 连接对象 * @param PreparedStatement * ps 执行对象 * @param ResultSet * rs 结果集对象 * @return 无返回类型 */ public static void myClose(Connection conn, PreparedStatement ps, ResultSet rs) { try { if (conn != null && !conn.isClosed()) { conn.close(); } if (ps != null) { ps.close(); } if (rs != null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } } }
5.com.zz.bookManager.entity包,在该包下创建实体类Book
package com.zz.bookManager.entity; /** * 实体 * * @author zz * */ public class Book { private int bid; private String bname; private String btype; private int bprice; private String bauthor; public Book() { // TODO Auto-generated constructor stub } public Book(String bname, String btype, int bprice, String bauthor) { super(); this.bname = bname; this.btype = btype; this.bprice = bprice; this.bauthor = bauthor; } public Book(int bid, String bname, String btype, int bprice, String bauthor) { super(); this.bid = bid; this.bname = bname; this.btype = btype; this.bprice = bprice; this.bauthor = bauthor; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getBname() { return bname; } public void setBname(String bname) { this.bname = bname; } public String getBtype() { return btype; } public void setBtype(String btype) { this.btype = btype; } public int getBprice() { return bprice; } public void setBprice(int bprice) { this.bprice = bprice; } public String getBauthor() { return bauthor; } public void setBauthor(String bauthor) { this.bauthor = bauthor; } @Override public String toString() { return "Book [bid=" + bid + ", bname=" + bname + ", btype=" + btype + ", bprice=" + bprice + ", bauthor=" + bauthor + "]"; } }
6.com.zz.bookManager.dao包,在该包下创建IBookDao接口及BookDaoImpl类实现增删改查。
IBookDao接口
package com.zz.bookManager.dao; import java.util.List; import com.zz.bookManager.entity.Book; import com.zz.bookManager.utils.DBHelper; public interface IBookDao { public int addBook(Book book); public int deleteBookByBid(int bid); public int editBookByBid(int bid, Book book); public List<Book> queryBookAll(); public List<Book> queryBookAll(String strName); public Book queryBookAll(int bid); }
BookDaoImpl实现类:
package com.zz.bookManager.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import com.zz.bookManager.entity.Book; import com.zz.bookManager.utils.DBHelper; /** * 针对图书的DAO层类(增删改查) */ public class BookDao implements IBookDao { /** * 方法功能:新增操作 * * @param book * @return */ public int addBook(Book book) { /** 1.将增删改查中所有需要的变量及数据对象全部声明 */ int n = 0;// 影响的行数 Connection conn = null;// 连接对象 PreparedStatement ps = null;// 执行对象 String sql = "";// sql语句 /** 2.为上面定义的变量及数据库对象进行相关的赋值和获取 */ try { // (1)获取数据库连接对象 conn = DBHelper.getConn(); // (2)给sql赋值(新增语句) sql = "insert into tb_book values (?,?,?,?)"; // (3)将sql语句传入通过conn调用的方法中并返回其ps对象 ps = conn.prepareStatement(sql); // (4)给对应的占位符进行赋值 ps.setString(1, book.getBname()); ps.setString(2, book.getBtype()); ps.setInt(3, book.getBprice()); ps.setString(4, book.getBauthor()); // (5)开车(返回影响的行数) n = ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { DBHelper.myClose(conn, ps, null);// 关闭连接 } return n; } /** * 方法功能:删除图书 * * @param bid * @return */ public int deleteBookByBid(int bid) { /** 1.将增删改查中所有需要的变量及数据对象全部声明 */ int n = 0;// 影响的行数 Connection conn = null;// 连接对象 PreparedStatement ps = null;// 执行对象 String sql = "";// sql语句 /** 2.为上面定义的变量及数据库对象进行相关的赋值和获取 */ try { // (1)获取数据库连接对象 conn = DBHelper.getConn(); // (2)给sql赋值(删除语句) sql = "delete from tb_book where bid = ?"; // (3)将sql语句传入通过conn调用的方法中并返回其ps对象 ps = conn.prepareStatement(sql); // (4)给对应的占位符进行赋值 ps.setInt(1, bid); // (5)开车(返回影响的行数) n = ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { DBHelper.myClose(conn, ps, null);// 关闭连接 } return n; } /** * 方法功能:修改 * * @param bid * @param book * @return */ public int editBookByBid(int bid, Book book) { /** 1.将增删改查中所有需要的变量及数据对象全部声明 */ int n = 0;// 影响的行数 Connection conn = null;// 连接对象 PreparedStatement ps = null;// 执行对象 String sql = "";// sql语句 /** 2.为上面定义的变量及数据库对象进行相关的赋值和获取 */ try { // (1)获取数据库连接对象 conn = DBHelper.getConn(); // (2)给sql赋值(修改语句) sql = "update tb_book set bname = ? , btype = ? , bprice = ? , bauthor = ? where bid = ?"; // (3)将sql语句传入通过conn调用的方法中并返回其ps对象 ps = conn.prepareStatement(sql); // (4)给对应的占位符进行赋值 ps.setString(1, book.getBname()); ps.setString(2, book.getBtype()); ps.setInt(3, book.getBprice()); ps.setString(4, book.getBauthor()); ps.setInt(5, bid); // (5)开车(返回影响的行数) n = ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { DBHelper.myClose(conn, ps, null);// 关闭连接 } return n; } /** * 查询所有 */ public List<Book> queryBookAll() { /** 1.将增删改查中所有需要的变量及数据对象全部声明 */ Connection conn = null;// 连接对象 PreparedStatement ps = null;// 执行对象 String sql = "";// sql语句 // 针对查询 ResultSet rs = null;// 结果集对象 List<Book> list = new ArrayList<Book>();// 集合类对象 Book b = null;// 实体 /** 2.为上面定义的变量及数据库对象进行相关的赋值和获取 */ try { // (1)获取数据库连接对象 conn = DBHelper.getConn(); // (2)给sql赋值(新增语句) sql = "select * from tb_book"; // (3)将sql语句传入通过conn调用的方法中并返回其ps对象 ps = conn.prepareStatement(sql); // (4) 卸货(返回结果集对象) rs = ps.executeQuery(); // (5)遍历 while (rs.next()) { b = new Book(rs.getInt("bid"), rs.getString("bname"), rs.getString("btype"), rs.getInt("bprice"), rs.getString("bauthor")); list.add(b); } } catch (Exception e) { e.printStackTrace(); } finally { DBHelper.myClose(conn, ps, rs);// 关闭连接 } return list; } /** * 按照书名进行模糊查询 * * @param strName * @return */ public List<Book> queryBookAll(String strName) { /** 1.将增删改查中所有需要的变量及数据对象全部声明 */ Connection conn = null;// 连接对象 PreparedStatement ps = null;// 执行对象 String sql = "";// sql语句 // 针对查询 ResultSet rs = null;// 结果集对象 List<Book> list = new ArrayList<Book>();// 集合类对象 Book b = null;// 实体 /** 2.为上面定义的变量及数据库对象进行相关的赋值和获取 */ try { // (1)获取数据库连接对象 conn = DBHelper.getConn(); // (2)给sql赋值(新增语句) sql = "select * from tb_book where bname like '%" + strName + "%'"; // (3)将sql语句传入通过conn调用的方法中并返回其ps对象 ps = conn.prepareStatement(sql); // (4) 卸货(返回结果集对象) rs = ps.executeQuery(); // (5)遍历 while (rs.next()) { b = new Book(rs.getInt("bid"), rs.getString("bname"), rs.getString("btype"), rs.getInt("bprice"), rs.getString("bauthor")); list.add(b); } } catch (Exception e) { e.printStackTrace(); } finally { DBHelper.myClose(conn, ps, rs);// 关闭连接 } return list; } /** * 查询单个 */ public Book queryBookAll(int bid) { /** 1.将增删改查中所有需要的变量及数据对象全部声明 */ Connection conn = null;// 连接对象 PreparedStatement ps = null;// 执行对象 String sql = "";// sql语句 // 针对查询 ResultSet rs = null;// 结果集对象 Book b = null;// 实体 /** 2.为上面定义的变量及数据库对象进行相关的赋值和获取 */ try { // (1)获取数据库连接对象 conn = DBHelper.getConn(); // (2)给sql赋值(新增语句) sql = "select * from tb_book where bid = " + bid; // (3)将sql语句传入通过conn调用的方法中并返回其ps对象 ps = conn.prepareStatement(sql); // (4) 卸货(返回结果集对象) rs = ps.executeQuery(); // (5)遍历 if (rs.next()) { b = new Book(rs.getInt("bid"), rs.getString("bname"), rs.getString("btype"), rs.getInt("bprice"), rs.getString("bauthor")); } } catch (Exception e) { e.printStackTrace(); } finally { DBHelper.myClose(conn, ps, null);// 关闭连接 } return b; } }
7.com.zz.bookManager.ui包,在该包下创建UI类调用BookDAO类的增删改查方法。
package com.zz.bookManager.ui; import java.util.List; import java.util.Scanner; import com.zz.bookManager.dao.BookDao; import com.zz.bookManager.entity.Book; public class MainPageUI { private Scanner sc = new Scanner(System.in); //实例化数据访问层BookDAOL类 BookDao bd = new BookDao(); public void myShow() { 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("请选择: "); int num = sc.nextInt(); if(num == 1) { System.out.println("您选择的是新增操作"); System.out.println("请输入图书名称: "); String bname = sc.next(); System.out.println("请输入类型: "); String btype = sc.next(); System.out.println("请输入价格: "); int bprice = sc.nextInt(); System.out.println("请输入作者: "); String bauthor = sc.next(); //将输入的属性用Book对象进行封装成一个整体 Book Book = new Book(bname, btype, bprice, bauthor); int n = bd.addBook(Book); if(n >0 ) { System.out.println("OK"); }else { System.out.println("NO"); } }else if(num == 2) { System.out.println("您选择的是删除操作"); System.out.println("请输入删除的图书的学号"); int bid = sc.nextInt(); int n = bd.deleteBookByBid(bid); System.out.println(n>0?"OK":"NO"); }else if(num == 3) { System.out.println("您选择的是修改操作"); System.out.println("请输入要修改的图书的编号"); int bid = sc.nextInt(); System.out.println("请输入图书名称: "); String bname = sc.next(); System.out.println("请输入类型: "); String btype = sc.next(); System.out.println("请输入价格: "); int bprice = sc.nextInt(); System.out.println("请输入作者: "); String bauthor = sc.next(); //将输入的属性用Book对象进行封装成一个整体 Book Book = new Book(bname, btype, bprice, bauthor); //调用DAO中的修改的方法 int n = bd.editBookByBid(bid, Book); System.out.println(n>0?"OK":"NO"); }else if(num == 4) { System.out.println("您选择的是查询所有操作"); //直接调用查询所有的DAO方法 List<Book> queryBookAll = bd.queryBookAll(); for (Book Book : queryBookAll) { System.out.println(Book); } }else if(num == 5) { System.exit(0); }else { System.out.println("该功能尚未开发,敬请期待"); } } } }
8.com.zz.bookManager.test包,调用UI包中下封装的方法。
package com.zz.bookManager.test; import com.zz.bookManager.ui.MainPageUI; public class Test { public static void main(String[] args) { new MainPageUI().myShow(); } }
效果图: