当前位置:首页 > 问答 > 正文

Java里头怎么把数据库操作包起来,写代码更快更顺手一点

在Java里把数据库操作包起来,说白了就是想让自己写代码的时候更省事儿、更不容易出错,想象一下,如果你每次要跟数据库打交道,都得写一遍连接数据库、写SQL语句、处理异常、关闭连接这一大串重复的代码,那得多烦人,而且很容易在某个地方忘了关连接,把数据库拖垮,我们的目标就是把这些啰嗦的、重复的活儿,封装到一个“工具”或者几个“方法”里,以后用到的时候,直接调这个工具就行了。

最基础的做法就是自己写一个JdbcUtils这样的工具类,这个类干嘛用呢?它主要管两件事:一是帮你搞定数据库连接,二是帮你把连接关掉,确保资源不泄露,你可以把数据库的地址、用户名、密码这些信息写在一个配置文件里(比如db.properties),让工具类启动的时候就去读,这样,哪天数据库密码换了,你都不用改Java代码,直接改配置文件就行了,你提供两个静态方法,一个叫getConnection(),专门负责给你一个新的数据库连接;另一个叫close(Connection conn),负责帮你把连接关掉,这样,你在任何地方需要数据库连接,就直接Connection conn = JdbcUtils.getConnection();,用完了就JdbcUtils.close(conn);,这就比原来每次都要写一大串DriverManager.getConnection(...)清爽多了,这是最基本的一步,能帮你省掉很多重复的连接代码。

光这样还不够顺手,因为最麻烦的部分其实是处理ResultSet(就是查询回来的结果集)和PreparedStatement(用来执行SQL语句的对象),你会发现,即便用了上面的工具类,写一个查询方法还是得写很多行:创建语句对象、设置参数、执行查询、遍历结果集把数据一个个拿出来塞进Java对象里、最后还得挨个关闭结果集和语句对象,这个过程非常模板化,这时候,我们就可以再进一步,写一个QueryRunner风格的封装,这个思路来自Apache的DbUtils组件(来源:Apache Commons DbUtils)。

Java里头怎么把数据库操作包起来,写代码更快更顺手一点

它的核心思想是,把你“做什么”(比如查询用户ById)和“怎么做”(那些重复的步骤)分离开,你告诉它SQL语句是什么,SQL参数是什么,以及如何处理结果集,它来帮你完成中间所有的繁琐步骤,你可以写一个query方法,它接受SQL、参数和一个叫ResultSetHandler的接口实现,这个ResultSetHandler就专门负责怎么把一行数据变成你想要的Java对象,你在调用的时候,只需要关心这三样东西就行了,query方法内部会帮你处理创建语句、设置参数、执行、异常处理和关闭资源所有这些事,这样一来,你查询一个用户可能只需要几行代码,而不是几十行,这就像是你雇了一个助手,你把任务要求说清楚,他帮你把执行的细节全部搞定。

再往上走,为了更顺手,你就会接触到像MyBatis这样的“持久层框架”,MyBatis做的事情,其实就是把上面这种“封装”做到了极致,而且提供了更多方便的功能(来源:MyBatis官方文档),它最核心的两个概念是Mapper接口和SQL映射文件,你不需要写QueryRunner那样的工具类了,你只需要定义一个Java接口,比如UserMapper,里面声明方法,比如User findById(int id),在一个XML文件里,你写上这个方法对应的SQL语句SELECT * FROM user WHERE id = #{id},MyBatis会通过一些配置,在程序运行的时候,自动为你这个接口生成一个实现类!你直接调用userMapper.findById(1),它就返回一个User对象给你了,它背后帮你完成了所有的事情:获取连接、创建PreparedStatement、设置参数、执行SQL、把结果集映射成Java对象、关闭资源,你完全不用碰JDBC那些底层的API了,写代码的速度和顺滑度是质的飞跃。

Java里头怎么把数据库操作包起来,写代码更快更顺手一点

那MyBatis是怎么把数据库字段和Java对象属性对应起来的呢?它有两种主要方式,一种是“自动映射”,如果你的数据库字段名(比如user_name)和Java对象的属性名(比如userName)能对应上(它有一些智能的匹配规则,比如下划线转驼峰),它就会自动帮你填充,你什么都不用做,另一种是当名字对不上或者查询很复杂时,你可以在XML里写<resultMap>来手动指定哪个字段映射到哪个属性,这种方式非常灵活,让你能应对各种复杂的场景。

提到封装数据库操作,绝对不能绕开Spring框架提供的JdbcTemplate(来源:Spring Framework官方文档),它是Spring对JDBC的一个非常经典的封装,可以看作是上面提到的QueryRunner的一个更强大、更完善的官方版本。JdbcTemplate的好处是,它已经帮你处理了资源的获取和释放、异常转换(把检查异常转换成运行时异常,让你代码更干净)等所有底层细节,你用它来写查询,代码非常简洁,比如List<User> users = jdbcTemplate.query("SELECT * FROM user WHERE age > ?", new Object[]{18}, new BeanPropertyRowMapper<>(User.class)); 这一行代码就替代了之前一二十行的JDBC代码。BeanPropertyRowMapper就是帮我们自动映射的利器。JdbcTemplate在不想引入完整的MyBatis框架,但又想获得简洁数据库操作体验的项目中,是一个非常受欢迎的选择。

从自己写工具类封装连接,到写通用类封装整个操作流程,再到使用MyBatis或JdbcTemplate这样的成熟框架,本质上都是一层一层地把重复、繁琐、易错的代码包起来,只暴露给你最简单、最直观的接口,这样做的目的,就是让你能把精力集中在业务逻辑本身,而不是底层的数据访问细节上,从而写代码更快、更顺手、更不容易出错。