From af09902c962d824407ae7f70c4a6ae12622f6737 Mon Sep 17 00:00:00 2001 From: twinkle255 Date: Fri, 5 May 2023 20:06:44 +0800 Subject: [PATCH] =?UTF-8?q?Bug=20Fixed=E3=80=82=E5=AE=8C=E6=88=90ShellUI?= =?UTF-8?q?=E3=80=81UserDAO=E3=80=81merchantsDAO=EF=BC=8C=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 30 ++- src/main/java/dao/abstractDAO.java | 2 + src/main/java/dao/merchantsAbstractDAO.java | 3 +- .../java/dao/specification/abstractDAO.java | 8 + .../java/dao/specification/merchantsDAO.java | 67 ++++--- src/main/java/dao/specification/userDAO.java | 55 ++++-- src/main/java/dao/userAbstractDAO.java | 3 +- src/main/java/entities/Merchants.java | 27 ++- src/main/java/entities/Users.java | 25 ++- src/main/java/example/shellUI.java | 172 ++++++++++++++---- src/main/java/util/SQLDatabaseConnection.java | 4 +- src/main/java/util/Toolset.java | 98 ++++++++++ 12 files changed, 388 insertions(+), 106 deletions(-) create mode 100644 src/main/java/dao/specification/abstractDAO.java create mode 100644 src/main/java/util/Toolset.java diff --git a/README.md b/README.md index 403e326..eac19f6 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,11 @@ # 2023-03-16 - 初始化项目 + # 2023-03-22 - 增加实体类 - 删除.idea文件 + # 2023-03-26 - 完善实体类 - 我靠,折腾了一晚上,提交了十几次,终于提交时把.idea这个文件给忽略了 @@ -19,20 +21,36 @@ - `update`一下远端项目 - `push`代码 - 我好菜。。。 + # 2023-03-27 - 完善了一下实体类,发现商家那一部分漏了一点东西,给它补上了 - 另外就是为什么`.idea`文件我已经取消提交了,为啥本地的`commit`里面还会有有啊……无语了 - 是不是跟`git`八字不合。。。 + # 2023-03-29 - 添加`JDBC`驱动,连接数据库 + # 2023-05-04 -- 创建数据库表,并成功连接 -- 调整实体类与数据库对应的结构,修改外键 +- 创建数据库表,测试连接成功 - 调整项目结构 + - 调整实体类与数据库对应的结构 + - 修改外键 - 完成DAO层抽象接口 -- 完成MerchantsDAO和UserDAO具体功能 -# 2023-05-05 -- Debug MerchantsDAO 按ID查询功能 + - 完成MerchantsDAO和UserDAO具体功能 + +# 2023-05-05-NO.1 +- Bug fixed: MerchantsDAO 按ID查询功能 - 搭建shellUI的大体框架 - 完成UserDAO具体功能 -- 第一次测试 \ No newline at end of file + +# 2023-05-05-NO.2 +- 实现UserDAO和MerchantsDAO所有接口功能 +- shellUI完成 +- 测试 + - UserDAO和MerchantsDAO的增加、查询、删除功能测试通过 + - shellUI功能测试通过 +- Bug Fixed + - DAO层Merchants、User类查询问题 + - 按ID查询报错 + - 全部查询只显示最后添加的行 + - 输出格式混乱问题 \ No newline at end of file diff --git a/src/main/java/dao/abstractDAO.java b/src/main/java/dao/abstractDAO.java index f167625..2b880b6 100644 --- a/src/main/java/dao/abstractDAO.java +++ b/src/main/java/dao/abstractDAO.java @@ -10,4 +10,6 @@ public interface abstractDAO { int update(T t);//改 List search(T t);//查 + + T searchID(Long id);//查 ByID } diff --git a/src/main/java/dao/merchantsAbstractDAO.java b/src/main/java/dao/merchantsAbstractDAO.java index 6e27f93..65de271 100644 --- a/src/main/java/dao/merchantsAbstractDAO.java +++ b/src/main/java/dao/merchantsAbstractDAO.java @@ -3,6 +3,5 @@ package dao; import entities.Merchants; public interface merchantsAbstractDAO extends abstractDAO { - //根据id查询商家 - Merchants searchMerchantByID(Long id); + } diff --git a/src/main/java/dao/specification/abstractDAO.java b/src/main/java/dao/specification/abstractDAO.java new file mode 100644 index 0000000..1ddd834 --- /dev/null +++ b/src/main/java/dao/specification/abstractDAO.java @@ -0,0 +1,8 @@ +package dao.specification; + +import java.util.List; + +//@TODO 重构代码 合并userDAO和merchantsDAO中重复方法 +public class abstractDAO { + +} diff --git a/src/main/java/dao/specification/merchantsDAO.java b/src/main/java/dao/specification/merchantsDAO.java index 9c222c7..8a9c713 100644 --- a/src/main/java/dao/specification/merchantsDAO.java +++ b/src/main/java/dao/specification/merchantsDAO.java @@ -16,46 +16,22 @@ public class merchantsDAO implements merchantsAbstractDAO { private PreparedStatement preparedStatement = null; private ResultSet resultSet = null; - //通过id寻找商家 - @Override - public Merchants searchMerchantByID(Long id) { - Merchants merchants = null; - String selectID_sql = "select * from Merchants where id = ?"; - try { - connection = getConnection(); - preparedStatement = connection.prepareStatement(selectID_sql); - preparedStatement.setLong(1, id); - resultSet = preparedStatement.executeQuery(); - - while (resultSet.next()) { - merchants = new Merchants(); - merchants.setId(resultSet.getLong("id")); - merchants.setName(resultSet.getString("name")); - merchants.setAddress(resultSet.getString("address")); - merchants.setDescription(resultSet.getString("description")); - merchants.setPhoneNumber(resultSet.getString("phoneNumber")); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - close(connection, preparedStatement, resultSet); - } - return merchants; - } - //新加商家 @Override public int insert(@NotNull Merchants merchants) { - int flag = 0; + int flag; try { connection = getConnection(); - String insert_sql = "insert into Merchants(name,address,description,phoneNumber) values(?,?,?,?)"; + String insert_sql = "insert into Merchants(name,address,description,phoneNumber) " + + "values(?,?,?,?)"; preparedStatement = connection.prepareStatement(insert_sql); preparedStatement.setString(1, merchants.getName()); preparedStatement.setString(2, merchants.getAddress()); preparedStatement.setString(3, merchants.getDescription()); preparedStatement.setString(4, merchants.getPhoneNumber()); + + flag = preparedStatement.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { @@ -73,6 +49,7 @@ public class merchantsDAO implements merchantsAbstractDAO { String delete_sql = "delete from Merchants where id = ?"; preparedStatement = connection.prepareStatement(delete_sql); preparedStatement.setLong(1, merchants.getId()); + flag = preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); @@ -110,13 +87,16 @@ public class merchantsDAO implements merchantsAbstractDAO { @Override public List search(Merchants merchants) { List list = new ArrayList<>(); + String selectAll_sql = "select * from Merchants"; + try { connection = getConnection(); - String selectAll_sql = "select * from Merchants"; + preparedStatement = connection.prepareStatement(selectAll_sql); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { + merchants = new Merchants(); merchants.setId(resultSet.getLong("id")); merchants.setName(resultSet.getString("name")); merchants.setPhoneNumber(resultSet.getString("phoneNumber")); @@ -133,4 +113,31 @@ public class merchantsDAO implements merchantsAbstractDAO { return list; } + + //通过id寻找商家 + @Override + public Merchants searchID(Long id) { + Merchants merchants = null; + String selectID_sql = "select * from Merchants where id = ?"; + try { + connection = getConnection(); + preparedStatement = connection.prepareStatement(selectID_sql); + preparedStatement.setLong(1, id); + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) { + merchants = new Merchants(); + merchants.setId(resultSet.getLong("id")); + merchants.setName(resultSet.getString("name")); + merchants.setAddress(resultSet.getString("address")); + merchants.setDescription(resultSet.getString("description")); + merchants.setPhoneNumber(resultSet.getString("phoneNumber")); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + close(connection, preparedStatement, resultSet); + } + return merchants; + } } diff --git a/src/main/java/dao/specification/userDAO.java b/src/main/java/dao/specification/userDAO.java index 892a061..1fd7d6b 100644 --- a/src/main/java/dao/specification/userDAO.java +++ b/src/main/java/dao/specification/userDAO.java @@ -19,13 +19,31 @@ public class userDAO implements userAbstractDAO { private PreparedStatement preparedStatement = null; private ResultSet resultSet = null; - //@TODO UserDAO 插入功能 + //新建用户 @Override - public int insert(Users users) { + public int insert(@NotNull Users users) { + int flag; + try { + connection = getConnection(); + String insert_sql = "insert into Users(name, phoneNumber, address, password) " + + "values (?,?,?,?)"; + preparedStatement = connection.prepareStatement(insert_sql); - return 0; + preparedStatement.setString(1, users.getName()); + preparedStatement.setString(2, users.getPhoneNumber()); + preparedStatement.setString(3, users.getAddress()); + preparedStatement.setString(4, users.getPassword()); + + flag = preparedStatement.executeUpdate(); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + close(connection, preparedStatement, resultSet); + } + return flag; } + //删除 @Override public int delete(@NotNull Users users) { int flag; @@ -34,8 +52,8 @@ public class userDAO implements userAbstractDAO { String delete_sql = "delete from Users where id=?"; preparedStatement = connection.prepareStatement(delete_sql); preparedStatement.setLong(1, users.getId()); - flag = preparedStatement.executeUpdate(); + flag = preparedStatement.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { @@ -45,20 +63,24 @@ public class userDAO implements userAbstractDAO { return flag; } + //更新用户个人信息 @Override public int update(@NotNull Users users) { - int flag = 0; + int flag; + String update_sql = "update Users " + + "set name = ?, phoneNumber = ?, address = ? " + + "where id = ?"; + try { connection = getConnection(); - String update_sql = "update Users " + - "set name = ?, phoneNumber = ?, address = ? " + - "where id = ?"; preparedStatement = connection.prepareStatement(update_sql); - preparedStatement.setString(1,users.getName()); - preparedStatement.setString(2,users.getPhoneNumber()); - preparedStatement.setString(3,users.getAddress()); - preparedStatement.setLong(4,users.getId()); + preparedStatement.setString(1, users.getName()); + preparedStatement.setString(2, users.getPhoneNumber()); + preparedStatement.setString(3, users.getAddress()); + preparedStatement.setLong(4, users.getId()); + + flag = preparedStatement.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } @@ -69,14 +91,17 @@ public class userDAO implements userAbstractDAO { @Override public List search(Users users) { List list = new ArrayList<>(); + String selectAll_sql = "select * from Users"; try { connection = getConnection(); - String selectAll_sql = "select * from Users"; + preparedStatement = connection.prepareStatement(selectAll_sql); - preparedStatement.executeQuery(); + resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { + users = new Users(); + users.setName(resultSet.getString("id")); users.setName(resultSet.getString("name")); users.setPhoneNumber(resultSet.getString("phoneNumber")); users.setAddress(resultSet.getString("address")); @@ -92,7 +117,7 @@ public class userDAO implements userAbstractDAO { //用ID查询用户 @Override - public Users searchUsersByID(Long id) { + public Users searchID(Long id) { Users user = null; String selectID_sql = "select * from Users where id = ?"; try { diff --git a/src/main/java/dao/userAbstractDAO.java b/src/main/java/dao/userAbstractDAO.java index 740ff21..aad238b 100644 --- a/src/main/java/dao/userAbstractDAO.java +++ b/src/main/java/dao/userAbstractDAO.java @@ -3,6 +3,5 @@ package dao; import entities.Users; public interface userAbstractDAO extends abstractDAO { - //根据ID查询用户 - Users searchUsersByID(Long id); + } diff --git a/src/main/java/entities/Merchants.java b/src/main/java/entities/Merchants.java index 3785e1b..4b2e85a 100644 --- a/src/main/java/entities/Merchants.java +++ b/src/main/java/entities/Merchants.java @@ -12,12 +12,25 @@ public class Merchants { private String description;//店铺描述 private String phoneNumber;//商家联系方式 - @Override - public String toString() { - return "\n商家编号:" + this.id + - "\n店铺名字:" + this.name + - "\n店铺地址:" + this.address + - "\n店铺描述:" + this.description + - "\n联系方式:" + this.phoneNumber; +// @Override +// public String toString() { +// return "\n商家编号:" + this.id + +// "\n店铺名字:" + this.name + +// "\n店铺地址:" + this.address + +// "\n店铺描述:" + this.description + +// "\n联系方式:" + this.phoneNumber; +// } + + public Merchants(String name, String address, + String description, String phoneNumber) { + this.name = name; + this.address = address; + this.description = description; + this.phoneNumber = phoneNumber; } + + public Merchants() { + + } + } diff --git a/src/main/java/entities/Users.java b/src/main/java/entities/Users.java index e3d54c8..48178da 100644 --- a/src/main/java/entities/Users.java +++ b/src/main/java/entities/Users.java @@ -6,17 +6,28 @@ import lombok.Data; @Data public class Users { private Long id;//主键,用户ID - private String password;//用户密码 private String name;//用户姓名 private String phoneNumber;//用户联系方式 private String address;//家庭住址 + private String password;//用户密码 + +// @Override +// public String toString() { +// return "\n用户编号:" + this.id + +// "\n用户姓名:" + this.name + +// "\n家庭地址:" + this.address + +// "\n联系方式:" + this.phoneNumber; +// } + + public Users() { - @Override - public String toString() { - return "\n用户编号:" + this.id + - "\n用户姓名:" + this.name + - "\n家庭地址:" + this.address + - "\n联系方式:" + this.phoneNumber; } + public Users(String name, String phoneNumber, + String address, String password) { + this.name = name; + this.phoneNumber = phoneNumber; + this.address = address; + this.password = password; + } } diff --git a/src/main/java/example/shellUI.java b/src/main/java/example/shellUI.java index f3fb82b..fcbbd5f 100644 --- a/src/main/java/example/shellUI.java +++ b/src/main/java/example/shellUI.java @@ -1,55 +1,157 @@ package example; -import com.microsoft.sqlserver.jdbc.StringUtils; -import dao.*; -import dao.specification.*; +import dao.merchantsAbstractDAO; +import dao.specification.merchantsDAO; +import dao.specification.userDAO; +import dao.userAbstractDAO; +import entities.Merchants; +import entities.Users; +import util.Toolset; import java.util.Scanner; public class shellUI { - public static void main(String[] args) { + public static void main(String[] args) throws IllegalAccessException { run(); } - public static void run() { - Scanner reader = new Scanner(System.in); + public static void run() throws IllegalAccessException { + System.out.println(""" ------------------------------------------ ----------------后台管理系统---------------- ------------------------------------------ """); + Chose(); + } + + //选项一 + private static void Chose() throws IllegalAccessException { System.out.println(""" - 请选择你要进行的功能 - 1.商家管理 - 2.用户管理 + 请选择你要进行的功能: + 1.商家管理\t2.用户管理\t0.退出 """); - // - int chose1; - while (true) { - if (reader.hasNextInt()) { - chose1 = reader.nextInt(); - break; - } else { - System.out.println("你的输入有误,请重新输入!"); + + switch (Toolset.option()) { + case 0 -> System.exit(0); + //商家 + case 1 -> { + System.out.println(""" + 请选择你想使用的功能: + 1.新建商家\t\t2.删除商家\t\t3.更新信息 + 4.查询所有商家\t5.根据ID查询商家\t0.退出 + """); + merchantsDB(Toolset.option()); + Chose(); + } + //用户 + case 2 -> { + System.out.println(""" + 请选择你想使用的功能: + 1.新建用户\t\t2.删除用户\t\t3.更新信息 + 4.查询所有用户\t5.根据ID查询用户\t0.退出 + """); + userDB(Toolset.option()); + Chose(); } } - //@TODO 2023-05-05 shellUI功能选择 - int chose2; - switch (chose1) { - case 1: - System.out.println(""" - 请选择你想使用的功能: - 1. - 2. - 3. - 4. - 5. - """); - - break; - case 2: - } - - } + + //商家数据库操作 + private static void merchantsDB(int chose) throws IllegalAccessException { + int flag; + Merchants merchants; + Scanner reader = new Scanner(System.in); + switch (chose) { + case 0 -> System.exit(0); + case 1 -> {//@TODO 输入格式化 不换行 + merchantsAbstractDAO DML_insert = new merchantsDAO(); + System.out.println("请输入:店铺名字|地址|描述|电话"); + merchants = new Merchants(reader.nextLine(), reader.nextLine(), reader.nextLine(), reader.nextLine()); + flag = DML_insert.insert(merchants); + System.out.println(flag + "行受影响"); + } + case 2 -> { + merchantsAbstractDAO DML_delete = new merchantsDAO(); + merchants = new Merchants(); + + System.out.println("请输入你要删除商家的ID"); + merchants.setId(reader.nextLong()); + + flag = DML_delete.delete(merchants); + System.out.println(flag + "行受影响"); + } + case 3 -> { + merchantsAbstractDAO DML_update = new merchantsDAO(); + merchants = new Merchants(); + flag = DML_update.update(merchants); + System.out.println(flag + "行受影响"); + } + case 4 -> { + merchantsAbstractDAO DQL_all = new merchantsDAO(); + merchants = new Merchants(); + //格式化输出 + for (Merchants item : DQL_all.search(merchants)) { + System.out.println(Toolset.table(Merchants.class, item)); + } + + } + case 5 -> { + merchantsAbstractDAO DQL_ID = new merchantsDAO(); + new Merchants(); + System.out.println("请输入你要查询的ID:"); + merchants = DQL_ID.searchID(reader.nextLong()); + //格式化输出 + System.out.println(Toolset.table(Merchants.class, merchants)); + } + } + } + + //用户数据库操作 + private static void userDB(int chose) throws IllegalAccessException { + int flag; + Users user; + Scanner reader = new Scanner(System.in); + + switch (chose) { + case 0 -> System.exit(0); + case 1 -> {//@TODO 非换行输入 + userAbstractDAO DML_insert = new userDAO(); + System.out.println("请输入:名字|电话|地址|密码"); + user = new Users(reader.nextLine(), reader.nextLine(), reader.nextLine(), reader.nextLine()); + flag = DML_insert.insert(user); + System.out.println(flag + "行受影响"); + } + case 2 -> { + userAbstractDAO DML_delete = new userDAO(); + user = new Users(); + flag = DML_delete.delete(user); + System.out.println(flag + "行受影响"); + } + case 3 -> { + userAbstractDAO DML_update = new userDAO(); + user = new Users(); + flag = DML_update.update(user); + System.out.println(flag + "行受影响"); + } + case 4 -> { + userAbstractDAO DQL_all = new userDAO(); + user = new Users(); + //格式化输出 + for (Users item : DQL_all.search(user)) { + System.out.println(Toolset.table(Users.class, item)); + } + + } + case 5 -> { + userAbstractDAO DQL_ID = new userDAO(); + new Users(); + System.out.println("请输入你要查询的ID:"); + user = DQL_ID.searchID(reader.nextLong()); + //格式化输出 + System.out.println(Toolset.table(Users.class, user)); + } + } + } + } diff --git a/src/main/java/util/SQLDatabaseConnection.java b/src/main/java/util/SQLDatabaseConnection.java index d44d04c..6a16325 100644 --- a/src/main/java/util/SQLDatabaseConnection.java +++ b/src/main/java/util/SQLDatabaseConnection.java @@ -7,10 +7,10 @@ public class SQLDatabaseConnection { private static final String connectionUrl = "jdbc:sqlserver://152.136.182.168:1433;" + "database=Elm;" - + "user=guest@152.136.182.168;" + + "user=guest;" + "password=20230504#Guest;" + "encrypt=true;" - + "trustServerCertificate=false;" + + "trustServerCertificate=true;" + "loginTimeout=30;"; public static Connection getConnection() { diff --git a/src/main/java/util/Toolset.java b/src/main/java/util/Toolset.java new file mode 100644 index 0000000..b7a04e6 --- /dev/null +++ b/src/main/java/util/Toolset.java @@ -0,0 +1,98 @@ +package util; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Map; +import java.util.Scanner; +import java.util.StringJoiner; +import java.util.concurrent.ConcurrentHashMap; + +public class Toolset { + public static int option() { + Scanner reader = new Scanner(System.in); + int chose; + //读取选项 + while (true) { + if (reader.hasNextInt()) { + chose = reader.nextInt(); + break; + } else { + System.out.println("你的输入有误,请重新输入~"); + } + } + return chose; + } + + //shellUI格式化输出 + private static final Map, Field[]> CLASS_2_FIELD_NAME = new ConcurrentHashMap<>(); + + /** + * 将对象打印成表格 + */ + @SafeVarargs + public static String table(Class clazz, T... objs) throws IllegalAccessException { + Field[] fields = safeGetRefCtx(clazz); + if (fields.length == 0) { + return ""; + } + // 计算每一列 + int[] maxLens = new int[fields.length]; + for (int i = 0; i < fields.length; i++) { + final int ti = i; + // 取出当前字段中最长的长度 + maxLens[i] = Arrays.stream(objs) + .map(item -> { + try { + return String.valueOf(fields[ti].get(item)); + } catch (IllegalAccessException e) { + // pass + } + return ""; + }) + .mapToInt(String::length) + .max() + .orElse(0); + } + StringJoiner result = new StringJoiner("\n"); + for (T obj : objs) { + // 竖线前后加一个空格分割 + StringJoiner sj = new StringJoiner(" | "); + for (int i = 0; i < fields.length; i++) { + sj.add(fields[i].getName() + ": " + padRight(String.valueOf(fields[i].get(obj)), maxLens[i])); + } + result.merge(sj); + } + return result.toString(); + } + + /** + * 右侧补充字符 + */ + @Contract(pure = true) + private static @NotNull String padRight(@NotNull String origin, int length) { + StringBuilder originBuilder = new StringBuilder(origin); + while (originBuilder.length() < length) { + originBuilder.append(' '); + } + origin = originBuilder.toString(); + return origin; + } + + private static Field @NotNull [] safeGetRefCtx(Class clazz) { + Field[] fields = CLASS_2_FIELD_NAME.get(clazz); + if (fields == null) { + fields = clazz.getDeclaredFields(); + for (Field field : fields) { + //打开私有访问 + field.setAccessible(true); + } + CLASS_2_FIELD_NAME.put(clazz, fields); + } + return fields; + } + + +}