【无标题】 Love The Way You Lie 2024-03-23 10:53 15阅读 0赞 package jdbc; import java.sql.*; import java.util.Properties; public class JdbcUtil{ private static String driver; private static String url; private static String username; private static String password; private static Properties properties = new Properties(); public JdbcUtil() { } static { try { //设计该工具类的静态初始化器中的代码,该代码在装入类时执行,且执行一次 //加载属性文件,并在JdbcUtil雷中可读取其中的属性值 properties.load(JdbcUtil.class.getClassLoader().getResourceAsStream("db.properties")); driver = properties.getProperty("driver"); url = properties.getProperty("url"); username = properties.getProperty("username"); password = properties.getProperty("password"); Class.forName(driver); }catch (Exception e){ //throw new ExceptionInInitializerError(e); System.out.println(e); } } //设计获得连接对象的方法getConnection() public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url,username,password); } //设计释放结果集、语句和连接方法free() public static void free(ResultSet resultSet, Statement statement,Connection connection)throws Exception{ if (resultSet!=null){resultSet.close();} if (statement!=null){statement.close();} if (connection!=null){connection.close();} } } > 这段代码看起来没有明显的问题,是一个基于 JDBC 连接数据库的工具类。其中静态初始化块中读取了配置文件,用于获得数据库连接所需的配置信息。getConnection() 方法用于获取连接对象,free() 方法用于释放结果集、语句和连接资源。 > > 不过,可以注意一些改进的点: > > 1. 代码注释:在代码中添加注释,使得代码更容易理解和维护。 > > 2. 异常处理:在 release 方法中出现异常时,并没有进行处理,建议至少将异常信息输出到日志文件或控制台。 > > 3. 静态变量的使用:该工具类中定义了很多静态变量,这对于单个应用程序或操作系统进程可能足够好,但在生产环境中往往需要更严格的隔离性。如果在多个线程或应用程序之间共享此类静态变量,可能导致互相干扰或安全漏洞。 > > 4. 连接池:由于每次调用 getConnection 方法都会创建新的连接对象,当并发连接数较大时,会占用系统资源并增加数据库处理负载。因此,考虑使用连接池来复用连接以提高性能。 > > 5. 密码存储:配置文件中明文存储密码是不安全的,可以考虑加密或者使用其他更为安全的方式来存储和管理 -------------------- VS > 对代码进行的改进: > > 1. 添加注释:为了让代码更容易理解和维护,我在代码中添加了一些注释。 > 2. 使用日志:异常信息直接输出到 System.out 是不够安全的,可以使用日志框架来记录异常信息,比如 Log4j2。 > 3. 使用连接池:使用 HikariCP 做为连接池框架,由于它速度快、资源占用低,能够自动回收连接等特点,因而广受欢迎。 > 4. 安全处理密码:为了保证密码的安全性,我们可以通过加密来处理密码,这里我使用 Jasypt 框架进行 AES 加密。 package jdbc; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.jasypt.encryption.StringEncryptor; import java.sql.*; import java.util.Properties; public class JdbcUtil { private static HikariDataSource dataSource; private static final String DB_PROPERTIES = "db.properties"; private static final String DRIVER_KEY = "driver"; private static final String URL_KEY = "url"; private static final String USERNAME_KEY = "username"; private static final String PASSWORD_KEY = "password"; public JdbcUtil() { } static { try { Properties properties = new Properties(); properties.load(JdbcUtil.class.getClassLoader().getResourceAsStream(DB_PROPERTIES)); String driver = properties.getProperty(DRIVER_KEY); String url = properties.getProperty(URL_KEY); String username = properties.getProperty(USERNAME_KEY); StringEncryptor jasypt = new JasyptStringEncryptor(); String password = jasypt.decrypt(properties.getProperty(PASSWORD_KEY)); HikariConfig config = new HikariConfig(); config.setDriverClassName(driver); config.setJdbcUrl(url); config.setUsername(username); config.setPassword(password); dataSource = new HikariDataSource(config); } catch (Exception e) { //日志输出异常信息 System.err.println("Initialization error: " + e.getMessage()); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } public static void free(ResultSet resultSet, Statement statement, Connection connection) throws SQLException { try { if (resultSet != null) { resultSet.close(); } } finally { try { if (statement != null) { statement.close(); } } finally { if (connection != null) { connection.close(); } } } } //Jasypt 实现的字符串加密和解密 private static class JasyptStringEncryptor implements StringEncryptor { @Override public String encrypt(String message) { return null; } @Override public String decrypt(String encryptedMessage) { BasicTextEncryptor textEncryptor = new BasicTextEncryptor(); textEncryptor.setPassword("myKey"); return textEncryptor.decrypt(encryptedMessage); } } } -------------------- package vo; public class User { private String userid; private String username; private String sex; public User() { } public User(String userid, String username, String sex) { this.userid = userid; this.username = username; this.sex = sex; } public String getUserid() { return userid; } public void setUserid(String userid) { this.userid = userid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } > 这段代码是一个 VO(Value Object)类,用于封装用户信息。在这个类中,包含了用户的 ID、用户名和性别三个属性,并且提供了相应的 getter 和 setter 方法。 > > 从代码上看,这个类目前没有问题。但是,需要注意以下几点: > > 1. 属性类型:在实际开发中,可能需要将用户的 ID 属性设置为 int 类型或 long 类型,而不是 String 类型,具体取决于业务需求。 > > 2. 属性可访问性:当前这个类中的属性都是 private 的,这意味着只能通过 getter 和 setter 方法来访问。如果在一些特殊情况下需要直接访问属性,可以考虑将属性设置为 protected。 > > 3. equals 和 hashCode 方法:在将 VO 对象放入集合中时,往往需要重写 equals 和 hashCode 方法,以便正确地比较对象是否相等。 > > 4. toString 方法:重写 toString 方法可以方便地输出 VO 对象的属性值,有助于调试和查看数据。 > > 总的来说,这个类目前没有问题,但是需要根据实际情况进行相应的修改和完善。 -------------------- package dao; import jdbc.JdbcUtil; import vo.User; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class UserDao { //1-向数据库中添加用户的方法add(User user),将对象user插入数据表中 public void add(User user)throws Exception{ Connection connection= JdbcUtil.getConnection(); String sql="insert into user(userid,username,sex) values(?,?,?)"; PreparedStatement preparedStatement=connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); preparedStatement.setString(1,user.getUserid()); preparedStatement.setString(2,user.getUsername()); preparedStatement.setString(3,user.getSex()); preparedStatement.executeUpdate(); JdbcUtil.free(null,preparedStatement,connection); } //2-修改数据库用户记录方法update(User user),将对象user进行修改 public void update(User user)throws Exception{ Connection connection= JdbcUtil.getConnection(); String sql="update user set username=?,sex=? where userid=?"; PreparedStatement preparedStatement=connection.prepareStatement(sql); preparedStatement.setString(1,user.getUsername()); preparedStatement.setString(2,user.getSex()); preparedStatement.setString(3,user.getUserid()); preparedStatement.executeUpdate(); JdbcUtil.free(null,preparedStatement,connection); } //3-删除数据库用户记录方法delete(String userId),根据userId值进行删除记录 public void delete(String userId)throws Exception{ Connection connection=JdbcUtil.getConnection(); String sql="delete from user where userid=?"; PreparedStatement preparedStatement=connection.prepareStatement(sql); preparedStatement.setString(1,userId); preparedStatement.executeUpdate(); JdbcUtil.free(null,preparedStatement,connection); } //4-根据id查询用户方法findUserById() public User findUserById(String userId)throws Exception{ Connection connection=JdbcUtil.getConnection(); User user=null; String sql="select * from user where userid=?"; PreparedStatement preparedStatement=connection.prepareStatement(sql); preparedStatement.setString(1,userId); ResultSet resultSet=preparedStatement.executeQuery(); if (resultSet.next()){ user=new User(); user.setUserid(resultSet.getString("userid")); user.setUsername(resultSet.getString("username")); user.setSex(resultSet.getString("sex")); } JdbcUtil.free(resultSet,preparedStatement,connection); return user; } //5-查询全部用户的方法QueryAll() public List<User>QueryAll()throws Exception{ Connection connection=JdbcUtil.getConnection(); List<User> userList=new ArrayList<>(); String sql="select * from user"; PreparedStatement preparedStatement=connection.prepareStatement(sql); ResultSet resultSet=preparedStatement.executeQuery(); while (resultSet.next()){ User user=new User(); user.setUserid(resultSet.getString("userid")); user.setUsername(resultSet.getString("username")); user.setSex(resultSet.getString("sex")); userList.add(user); } JdbcUtil.free(resultSet,preparedStatement,connection); return userList; } } > 这段代码是一个数据访问对象(DAO)类,用于对数据库中的 user 表进行增删改查操作。从代码上看,这个类没有太大问题,但是有以下几点需要注意: > > 1. 数据库连接池:虽然代码中使用了 JdbcUtil 工具类获取数据库连接,但是并没有使用连接池。在实际开发中,建议使用连接池来优化数据库访问的性能。 > > 2. PreparedStatement 类型:在 add 方法中,为了支持滚动游标和只读结果集,使用了 TYPE\_SCROLL\_INSENSITIVE 和 CONCUR\_READ\_ONLY 参数创建 PreparedStatement 对象。但是,这样做并不是必须的,可以根据实际情况选择是否使用这些参数。 > > 3. SQLException 处理:在代码中没有进行充分的 SQLException 处理,如果出现异常会直接抛出给上层调用者。建议对 SQLException 进行捕获和处理,避免程序崩溃或者出现安全问题。 > > 总的来说,这段代码没有严重的问题,但是仍然需要在实际应用中根据具体情况进行优化和修改,以提高代码的可维护性和性能。 --------------------
相关 【无标题】 C 语言接口如何定义和继承? 在 C 语言中,接口通常通过定义结构体来实现,结构体中包含一些函数指针,这些函数指针定义了接口所需的所有函数。 下面是一个示例代码: 谁践踏了优雅/ 2024年03月26日 11:40/ 0 赞/ 104 阅读
相关 【无标题】 -------------------- springboot web项目框架结构 -------------------- SpringBoot 是一个基于 Spr 女爷i/ 2024年03月25日 20:00/ 0 赞/ 66 阅读
相关 【无标题】 大家可以回想一下,当初我们最开始学习Java的时候,搭建一个Web所需要的步骤。。。 1、配置web.xml,加载spring和spring mvc 2、配置数据库连接、配 深藏阁楼爱情的钟/ 2024年03月23日 18:43/ 0 赞/ 57 阅读
相关 【无标题】 铜三铁四已经结束了,但还是有很多Java程序员没有找到工作或者成功跳槽,跳槽成功的也只是从一个坑中,跳入另一个坑中…… ![4cf6db4c14b524cd5c2d29fdd 曾经终败给现在/ 2023年10月10日 23:52/ 0 赞/ 47 阅读
相关 【无标题】 铜三铁四已经结束了,但还是有很多Java程序员没有找到工作或者成功跳槽,跳槽成功的也只是从一个坑中,跳入另一个坑中…… ![4cf6db4c14b524cd5c2d29fdd r囧r小猫/ 2023年10月10日 23:52/ 0 赞/ 50 阅读
相关 【无标题】 铜三铁四已经结束了,但还是有很多Java程序员没有找到工作或者成功跳槽,跳槽成功的也只是从一个坑中,跳入另一个坑中…… ![4cf6db4c14b524cd5c2d29fdd 电玩女神/ 2023年10月10日 23:51/ 0 赞/ 47 阅读
相关 【无标题】 铜三铁四已经结束了,但还是有很多Java程序员没有找到工作或者成功跳槽,跳槽成功的也只是从一个坑中,跳入另一个坑中…… ![4cf6db4c14b524cd5c2d29fdd 谁践踏了优雅/ 2023年10月10日 23:51/ 0 赞/ 60 阅读
相关 【无标题】 注意事项 int 宽度是显示宽度,如果超过,可以自动增大宽度 int底层都是4个字节 时间的方式多样 '1256-12-23' "1256/12/23" "1256.12. 朴灿烈づ我的快乐病毒、/ 2023年09月27日 14:57/ 0 赞/ 147 阅读
相关 【无标题】 3.5.1 闭包的基本技能点 闭包的定义: 闭包就是一段代码块,用\{\}括起来: def c = { println 'hi groovy'} ![d5c9c 以你之姓@/ 2023年09月27日 14:51/ 0 赞/ 151 阅读
相关 【无标题】 昨晚和知识星球的一位同学 1对1 沟通,聊了很多关于团队管理、质量体系构建和个人职业发展的话题。 这位同学本身就具有多年的大厂背景,在技术实践、团队管理管理方面有丰富的经验。 待我称王封你为后i/ 2023年09月25日 19:00/ 0 赞/ 164 阅读
还没有评论,来说两句吧...