学生管理系统(用maven来导入jar包)

    技术2024-01-26  122

    不废话,直接上

    先看一下项目列表:

    首先创建一个maven工程,然后导入相应的jar包,请参考:使用maven导入jar包
    接着在Source Folder创建具体的项目:

    Main类(客户端)

    package com.zzu.client; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; import com.zzu.tool.db.DBLink; import com.zzu.tool.db.IRowMapper; public class Main { public static void main(String[] args) { System.out.println("*********************************"); System.out.println("*\t\t\t\t*"); System.out.println("*\t欢迎使用学生信息管理系统\t*"); System.out.println("*\t\t\t\t*"); System.out.println("*********************************"); while (true) { menu(); } } static void menu() { System.out.println("1、添加学生信息"); System.out.println("2、删除学生信息");//学号 System.out.println("3、修改学生信息");//地址传递 System.out.println("4、查询学生信息");//name System.out.println("请输入操作,以Enter键结束:"); Scanner scanner = new Scanner(System.in); int option = scanner.nextInt(); switch (option) { case 1:{ System.out.println("请输入学号:"); String id = scanner.next(); String sql = "select id from student where id = ?"; if(new DBLink().exist(sql, id)) { System.out.println("学号已存在,无法添加!"); return; } System.out.println("请输入姓名:"); String name = scanner.next(); System.out.println("请输入手机号:"); String mobile = scanner.next(); System.out.println("请输入家庭住址:"); String address = scanner.next(); sql = "insert into student (id,name,mobile,address) values (?,?,?,?)"; if(new DBLink().update(sql, id,name,mobile,address)) { System.out.println("添加成功!"); return; } System.out.println("添加失败!"); break; } case 2:{ System.out.println("请输入要删除学生的学号:"); String id = scanner.next(); String sql = "delete from student where id = ?"; if(new DBLink().update(sql, id)) { System.out.println("删除成功!"); return; } System.out.println("删除失败!"); break; } case 3:{ System.out.println("请输入要修改学生的学号:"); String id = scanner.next(); String sql = "select id from student where id = ?"; if(new DBLink().exist(sql, id)) { System.out.println("请输入新的姓名:"); String name = scanner.next(); System.out.println("请输入新的手机号:"); String mobile = scanner.next(); System.out.println("请输入新的家庭住址:"); String address = scanner.next(); sql = "update student set name = ?,mobile = ?, address = ? where id = ?"; if(new DBLink().update(sql, name,mobile,address,id)) { System.out.println("修改成功!"); return; } System.out.println("修改失败!"); return; } System.out.println("未查询到要修改学生的学号!"); break; } case 4:{ System.out.println("请输入要查询学生的学号:"); String id = scanner.next(); String sql = "select id from student where id = ?"; if(!new DBLink().exist(sql, id)) { System.out.println("学号不存在,无法查询!"); } sql = "select id,name,mobile,address from student where id = ?"; //有名内部类 class RowMapper implements IRowMapper{ public void rowMapper(ResultSet rs) { try { if(rs.next()) { String id1 = rs.getString("id"); String name = rs.getString("name"); String mobile = rs.getString("mobile"); String address = rs.getString("address"); System.out.println("学号:"+id1+",姓名:"+name+",手机号:"+mobile+",家庭住址:"+address); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; RowMapper rowMapper = new RowMapper(); new DBLink().select(sql, rowMapper,id); //Lambda表达式 /*new DBLink().select(sql, (ResultSet rs)->{ try { if(rs.next()) { String id1 = rs.getString("id"); String name = rs.getString("name"); String mobile = rs.getString("mobile"); String address = rs.getString("address"); System.out.println("学号:"+id1+",姓名:"+name+",手机号:"+mobile+",家庭住址:"+address); } } catch (SQLException e) { e.printStackTrace(); } },id);*/ break; } default: System.out.println("I'm Sorry,there is not the "+option+" option,please try again."); } } }
    DBLink(工具类)
    package com.zzu.tool.db; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.apache.log4j.Logger; import com.zzu.tool.PropertiesTool; /** * 数据库管理(增删改查) * * @author ZhaoZhengyi */ public class DBLink { private Logger logger = Logger.getLogger(DBLink.class); /** * 获取数据库连接 * * @author ZhaoZhengyi */ public Connection getConnection() { try { String driver = PropertiesTool.getValue("db.driver"); String url = PropertiesTool.getValue("db.url"); String userName = PropertiesTool.getValue("db.userName"); String password = PropertiesTool.getValue("db.password"); Class.forName(driver); return DriverManager.getConnection(url, userName, password); } catch (Exception e) { logger.debug(e.getMessage(), e); } return null; } /** * 该方法用于判断某个用户是否存在,若存在返回该用户数据,否则返回false * @param sql 是指要执行的SQL语句 * @return */ /*public boolean exist(String sql) { //初始化变量为null Connection connection = null; Statement statement = null; ResultSet resultset = null; try { connection = getConnection(); statement = connection.createStatement();//创建SQL语句对象 resultset = statement.executeQuery(sql);//executeQuery用于查询用户的数据,并将其存入ResultSet类型的resultset变量中去 return resultset.next();//若有则返回该用户数据 } catch (Exception e) { logger.debug(e.getMessage(), e); } finally {//即便有异常也会执行代码 close(resultset,statement,connection);//释放资源 } return false; }*/ /** * 判断某条数据是否存在 * * @author ZhaoZhengyi */ public boolean exist(String sql,Object ...params) { //初始化变量为null Connection connection = null; PreparedStatement prepareStatement = null; ResultSet resultset = null; try { connection = getConnection(); prepareStatement = connection.prepareStatement(sql);//此时prepareStatement为含有?的sql语句 for (int i = 0; i < params.length; i++) { //为?赋值,这里之所以为i+1,是因为该方法是从1开始的 prepareStatement.setObject(i+1, params[i]); } resultset = prepareStatement.executeQuery();//executeQuery用于查询用户的数据,并将其存入ResultSet类型的resultset变量中去 return resultset.next();//若有则返回该用户数据 } catch (Exception e) { logger.debug(e.getMessage(), e); } finally {//即便有异常也会执行代码 close(resultset,prepareStatement,connection);//释放资源 } return false;//若没有则返回false } /** * 该方法用于insert(添加)、delete(删除)、update(修改)用户信息 * 至于选哪一个来操作用户信息因sql语句而定 * @param sql 是指要操作的SQL语句 * @return 若成功则返回影响的行数,否则返回false */ public boolean update(String sql) { Connection connection = null; Statement statement = null; try { connection = getConnection(); statement = connection.createStatement();//创建SQL语句对象 int affect = statement.executeUpdate(sql);//执行sql语句,返回影响的行数,仅限于insert delete update /*statement.close(); connection.close();*///如果上面代码出现异常,则该行代码及其下面代码无法执行,所以资源无法释放;比如sql语句语法错误,则statement和connection无法释放 return affect>0; /* * 这里我想说明一下,由于finally的特殊性,会先执行完finally里的释放资源,再执行上一语句:返回一个affect值 * 总之就是在结束方法之前无论如何都要先释放资源才可以 */ } catch (Exception e) { logger.debug(e.getMessage(), e); } finally {//即便有异常也会执行代码 close(statement,connection);//释放资源 } return false; } /** * 用于添加、删除、修改用户信息 * * @author ZhaoZhengyi */ public boolean update(String sql, Object ...params) { Connection connection = null; PreparedStatement prepareStatement = null; try { connection = getConnection(); prepareStatement = connection.prepareStatement(sql);//含有?的sql语句 赋值给prepareStatement for(int i = 0; i < params.length; i++) { prepareStatement.setObject(i+1, params[i]);//用参数替换掉? } int affect = prepareStatement.executeUpdate();//执行sql语句,并返回影响的行数 return affect>0; } catch (Exception e) { logger.debug(e.getMessage(), e); } finally { close(prepareStatement,connection); } return false; } //获取某个表中的总行数(分页使用) public Object getValue(String sql,String columnName) { Connection connection = null; Statement statement = null; ResultSet resultset = null; try { connection = getConnection(); statement = connection.createStatement(); resultset = statement.executeQuery(sql); if(resultset.next()) { return resultset.getObject(columnName); } } catch (Exception e) { logger.debug(e.getMessage(), e); } finally { close(resultset,statement,connection); } return null; } //获取某个表中的总行数(分页使用)(防止sql注入) public Object getValue(String sql,String columnName,Object ...params) { Connection connection = null; PreparedStatement prepareStatement = null; ResultSet resultset = null; try { connection = getConnection(); prepareStatement = connection.prepareStatement(sql); for (int i = 0; i < params.length; i++) { prepareStatement.setObject(i+1, params[i]); } resultset = prepareStatement.executeQuery(); if(resultset.next()) { return resultset.getObject(columnName); } } catch (Exception e) { logger.debug(e.getMessage(), e); } finally { close(resultset,prepareStatement,connection); } return null; } /** * 该方法用于查询用户信息 * @param sql 要执行的SQL语句 * @param rowMapper 接口是无法创建对象的,所以参数rowMapper一定指向接口(IRowMapper)实现类对象 */ public void select(String sql,IRowMapper rowMapper) { Connection connection = null; Statement statement = null; ResultSet resultset = null; try { connection = getConnection(); statement = connection.createStatement();//创建SQL语句对象 resultset = statement.executeQuery(sql);//执行SQL语句,此时用户数据都在resultset里面 rowMapper.rowMapper(resultset);//因为rowMapper参数指向IRowMapper接口实现类对象,所以此处将调用接口实现类中所实现的rowMapper方法 多态 } catch (Exception e) { logger.debug(e.getMessage(), e); } finally { close(resultset,statement,connection);//释放资源 } } /** * 查询用户数据 * * @author ZhaoZhengyi */ public void select(String sql,IRowMapper rowMapper,Object ...params) { Connection connection = null; PreparedStatement prepareStatement = null; ResultSet resultset = null; try { connection = getConnection(); prepareStatement = connection.prepareStatement(sql); for (int i = 0; i < params.length; i++) { prepareStatement.setObject(i+1, params[i]); } resultset = prepareStatement.executeQuery();//执行SQL语句,此时用户数据都在resultset里面 rowMapper.rowMapper(resultset);//因为rowMapper参数指向IRowMapper接口实现类对象,所以此处将调用接口实现类中所实现的rowMapper方法 多态 } catch (Exception e) { logger.debug(e.getMessage(), e); } finally { close(resultset,prepareStatement,connection);//释放资源 } } /** * 释放资源 * * @author ZhaoZhengyi */ private void close(Statement statement,Connection connection) { try { if (statement != null) {//有可能由于异常导致statement没有赋值(譬如url出错),此时不必释放资源(多余),不然会报空指针异常 statement.close(); } } catch (SQLException e) { logger.debug(e.getMessage(), e); } try { if (connection != null) { connection.close(); } } catch (SQLException e) { logger.debug(e.getMessage(), e); } } /** * 与上一方法是重载 * * @author ZhaoZhengyi */ private void close(ResultSet resultset,Statement statement,Connection connection) { try { if (resultset != null) { resultset.close(); } } catch (SQLException e) { logger.debug(e.getMessage(), e); } close(statement,connection); } }

    IRowMapper接口:

    package com.zzu.tool.db; import java.sql.ResultSet; @FunctionalInterface public interface IRowMapper { /** * 定义一个抽象方法(参数类型为ResultSet) * * @author ZhaoZhengyi */ void rowMapper (ResultSet rs); }
    PropertiesTool类(获取数据库连接的桥梁):
    package com.zzu.tool; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class PropertiesTool { private static Properties properties = new Properties(); /** * 联系db.properties文件和properties * * 静态代码块先于main方法先执行 */ static { InputStream inputStream = PropertiesTool.class.getClassLoader().getResourceAsStream("db.properties");//将db.properties变为javaIO流对传入到inputStream中 //此时db.properties文件中的数据就保存到了inputStream中 try { properties.load(inputStream);//将inputStream中的key和value放到load方法中进行解析再存到properties中 } catch (IOException e) { e.printStackTrace(); } } /** * 我们创建一个getVaule方法来便于调用文件(此时也就是properties)中的数据 */ public static String getValue(String key) { return properties.getProperty(key);//返回properties中的key值 } /** * 我们来测试一下: */ public static void main(String [] ages) { String userName = getValue("db.userName"); String password = getValue("db.password"); String url = getValue("db.url"); String driver = getValue("db.driver"); System.out.println(userName); System.out.println(password); System.out.println(url); System.out.println(driver); } }

    要使用的资源:

    db.properties(连接数据库的一些必要信息):
    db.userName = root db.password = root db.url = jdbc:mysql://127.0.0.1:3306/test db.driver = com.mysql.jdbc.Driver
    log4j.properties(收集异常信息所需要的一些配置):
    # DEBUG\u8BBE\u7F6E\u8F93\u51FA\u65E5\u5FD7\u7EA7\u522B\uFF0C\u7531\u4E8E\u4E3ADEBUG\uFF0C\u6240\u4EE5ERROR\u3001WARN\u548CINFO \u7EA7\u522B\u65E5\u5FD7\u4FE1\u606F\u4E5F\u4F1A\u663E\u793A\u51FA\u6765 log4j.rootLogger=DEBUG,Console,RollingFile #\u5C06\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u5230\u63A7\u5236\u53F0 log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern= [%-5p]-[%d{yyyy-MM-dd HH:mm:ss}] -%l -%m%n #\u5C06\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u5230\u64CD\u4F5C\u7CFB\u7EDFD\u76D8\u6839\u76EE\u5F55\u4E0B\u7684log.log\u6587\u4EF6\u4E2D log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.RollingFile.File=D://log.log log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n

    slf4j-log4j:

    # DEBUG设置输出日志级别,由于为DEBUG,所以ERROR、WARN和INFO 级别日志信息也会显示出来 log4j.rootLogger=DEBUG,RollingFile #每天产生一个日志文件(RollingFile) log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender #当天的日志文件全路径 log4j.appender.RollingFile.File=d:/logs/sirius.log #服务器启动日志是追加,false:服务器启动后会生成日志文件把老的覆盖掉 log4j.appender.RollingFile.Append=true #日志文件格式 log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n log4j.appender.RollingFile.Threshold=DEBUG #设置每天生成一个文件名后添加的名称,备份名称:sirius.log.年月日时分.log log4j.appender.RollingFile.DatePattern='.'yyyy-MM-dd-HH-mm'.log'
    Processed: 0.017, SQL: 9