先看下没有mybatis或者其他的orm框架前,使用jdbc来操作数据库的代码是怎样:
-
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/local","root","***");
connection.setAutoCommit(false);
String sql = "insert into user_info values (?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,3);
preparedStatement.setString(2,"用户3");
preparedStatement.setInt(3,31);
try {
System.out.println("开始执行");
preparedStatement.executeUpdate();
connection.commit();
System.out.println("事务提交结束");
}catch (Exception e){
connection.rollback();
e.printStackTrace();
}finally {
if(preparedStatement!=null){
preparedStatement.close();
}
if(connection!=null){
connection.close();
}
}
}
以上代码做的是一个简单的新增数据的操作。
接下来一步步的分析代码,找出原始JDBC开发会存在的问题。
1.
通过以上截图可以发现,数据库的相关参数如ip地址,用户名,密码以及sql语句存在硬编码问题,这对后续开发来说不利于扩展。
2. 通过以上截图可以发现,当设置入参时,需要考虑参数类型和位置都要对应,说实话,单单拿出这段看,谁也不知道位置几对应的是哪个字段,还得依靠上下文推断,甚至参数类型都得小心翼翼的选择,避免出现类型错误问题,还有比较关键的点是,入参的数量如果很多,那这代码写起来就更难受了。
3.使用JDBC查询数据的操作和以上新增数据的操作代码大致相同,最大的不同点在于需要处理返参,如下:
while (resultSet.next()) {
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
user.setId(id);
user.setUsername(username);
}
从处理返参的这段代码中就可以发现,首先是需要遍历结果集,然后拿出需要的结果参数,这里面还得考虑字段名和类型一一对应,最后再把数据设置进需要返回的User对象属性中,还是实打实的硬编码,同时考虑到如果后续返参对象字段如果很多,这一一设置属性值的操作想想就可怕,开发效率不言而喻。
这步主要做的操作就是关闭数据库连接,毕竟数据库连接资源宝贵,所以操作执行结束后,释放数据库连接资源是再正常不过了,不过此时可以想想,如果按照示例代码中那样,每一次的数据库操作,都会申请一次连接,用完再释放,这样合理么,要知道,为了获取数据库连接,底层其实是做了TCP的3次握手,这样是比较消耗性能的,换个角度思考,好不容易才拿到的连接,用一会就还回去了,接下来要用的,还得辛辛苦苦花时间去申请,这无形中就浪费好多时间了。
针对以上问题,提出解决思路
问题 | 解决方案 |
---|
数据库连接频繁的创建和释放,浪费系统资源,导致影响系统性能 | 采用数据库连接池方案,在系统启动时先初始化部分数据库连接资源放池子里,然后用完不释放,而是回收进池子,方便再使用,同时数据库连接池需要做到维持最小连接数和扩展最大连接数以应对业务流量的变化,现成的数据库连接池有很多,如C3P0,Druid等。 | sql查询返回对象,需要一一设置属性值 | 使用反射、内省等底层技术,通过字段名,自动的把sql返回结果和对象中的属性一一对应并赋值。 | 数据库配置文件,sql语句,sql参数等存在的硬编码问题 | 使用配置文件统一管理(不过数据库配置文件和sql配置文件建议分开,毕竟数据库配置不长改,而sql会经常需要根据业务做调整)。 |
|