当前位置: 首页 > news >正文

第8章:从jdbc到MyBatis

文章目录

  • 第8章:从jdbc到MyBatis
    • JDBC操作数据库
    • 原生JDBC访问数据库缺点和ORM框架介绍
    • Mybatis基础知识
    • Spring+Mybatis快速入门

第8章:从jdbc到MyBatis

JDBC操作数据库

JDBC核心概念

  • Java Database Connectivity(Java数据库连接)
  • Java访问数据库的标准API
  • 提供统一的数据库访问接口

JDBC核心组件

  • DriverManager:驱动管理器
  • Connection:数据库连接
  • Statement/PreparedStatement:SQL语句执行器
  • ResultSet:结果集
// 原生JDBC示例publicclassJdbcExample{publicstaticvoidmain(String[]args){Connectionconn=null;PreparedStatementpstmt=null;ResultSetrs=null;try{// 1. 加载数据库驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 建立数据库连接conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test_db","root","123456");// 3. 创建PreparedStatement执行SQLStringsql="SELECT id, name, age FROM user WHERE age > ?";pstmt=conn.prepareStatement(sql);pstmt.setInt(1,18);// 4. 执行查询并处理结果集rs=pstmt.executeQuery();while(rs.next()){intid=rs.getInt("id");Stringname=rs.getString("name");intage=rs.getInt("age");System.out.printf("ID: %d, Name: %s, Age: %d%n",id,name,age);}}catch(Exceptione){e.printStackTrace();}finally{// 5. 关闭资源try{if(rs!=null)rs.close();if(pstmt!=null)pstmt.close();if(conn!=null)conn.close();}catch(SQLExceptione){e.printStackTrace();}}}}

原生JDBC访问数据库缺点和ORM框架介绍

原生JDBC的主要缺点

缺点描述影响
代码冗余重复的创建连接、关闭资源代码开发效率低,代码臃肿
硬编码SQL与Java代码混合维护困难,可读性差
手动映射需要手动将ResultSet映射为对象容易出错,工作量大
异常处理需要处理大量checked异常代码繁琐,易遗漏
连接管理手动管理数据库连接性能差,资源泄露风险

ORM框架介绍

  • Object-Relational Mapping(对象关系映射)
  • 将数据库表与Java对象建立映射关系
  • 自动完成对象与关系数据的转换

主流ORM框架对比

框架优点缺点适用场景
MyBatisSQL灵活,学习成本低需要手动编写SQL复杂SQL,性能要求高
Hibernate全自动,功能强大学习曲线陡峭,SQL优化难简单CRUD,快速开发
JPA标准规范,移植性好功能相对简单标准企业应用

Mybatis基础知识

MyBatis核心概念

  • SqlSessionFactory:会话工厂,创建SqlSession
  • SqlSession:数据库会话,执行SQL操作
  • Mapper接口:数据访问接口
  • Mapper XML:SQL映射文件

MyBatis架构层次

应用程序 ↓ Mapper接口 ↓ SqlSession ↓ Executor(执行器) ↓ StatementHandler ↓ 数据库

MyBatis核心配置文件结构

<!-- mybatis-config.xml --><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><settings><!-- 开启驼峰命名自动映射 --><settingname="mapUnderscoreToCamelCase"value="true"/></settings><typeAliases><!-- 类型别名配置 --><typeAliasalias="User"type="com.example.entity.User"/></typeAliases><environmentsdefault="development"><environmentid="development"><transactionManagertype="JDBC"/><dataSourcetype="POOLED"><propertyname="driver"value="com.mysql.cj.jdbc.Driver"/><propertyname="url"value="jdbc:mysql://localhost:3306/test_db"/><propertyname="username"value="root"/><propertyname="password"value="123456"/></dataSource></environment></environments><mappers><!-- Mapper文件配置 --><mapperresource="mapper/UserMapper.xml"/></mappers></configuration>

Spring+Mybatis快速入门

项目配置

<!-- pom.xml --><dependencies><!-- SpringBoot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MyBatis SpringBoot Starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!-- MySQL驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>

创建表和添加数据

CREATETABLEuser(id BIGINT AUTO_INCREMENTPRIMARYKEY,usernameVARCHAR(50)NOTNULLUNIQUE,emailVARCHAR(100)NOTNULLUNIQUE,age INT,create_timeDATETIME(6)DEFAULTCURRENT_TIMESTAMP(6),update_timeDATETIME(6)DEFAULTCURRENT_TIMESTAMP(6)ONUPDATECURRENT_TIMESTAMP(6),INDEXidx_username(username),INDEXidx_email(email),INDEXidx_create_time(create_time))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;INSERTINTOuser(username,email,age)VALUES('zhangsan', 'zhangsan@example.com',25);INSERTINTOuser(username,email,age)VALUES('lisi','lisi@example.com',30);INSERTINTOuser(username,email,age)VALUES('wangwu','wangwu@example.com',28);INSERTINTOuser(username,email)VALUES('zhaoliu', 'zhaoliu@example.com');INSERTINTOuser(username,email,age)VALUES('sunqi','sunqi@example.com',35),('zhouba','zhouba@example.com',22),('wujiu','wujiu@example.com',29);

应用配置文件

# application.ymlspring:datasource:url:jdbc:mysql://localhost:3306/mybatis_demousername:rootpassword:123456driver-class-name:com.mysql.cj.jdbc.Driver# MyBatis配置mybatis:# Mapper XML文件位置mapper-locations:classpath:mapper/*.xml# 实体类包路径type-aliases-package:com.example.entityconfiguration:# 开启驼峰命名自动映射map-underscore-to-camel-case:true# 控制台打印SQLlog-impl:org.apache.ibatis.logging.stdout.StdOutImpl

实体类

// 用户实体类@DatapublicclassUser{privateLongid;privateStringusername;privateStringemail;privateIntegerage;privateLocalDateTimecreateTime;privateLocalDateTimeupdateTime;}

mapper接口定义

@MapperpublicinterfaceUserMapper{/** * 根据ID查询用户 */UserfindById(Longid);/** * 查询所有用户 */List<User>findAll();/** * 根据用户名查询 */UserfindByUsername(Stringusername);}

mapper xml配置

<!-- src/main/resources/mapper/UserMapper.xml --><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.example.mapper.UserMapper"><!-- 根据ID查询用户 --><selectid="findById"parameterType="Long"resulType="com.xd.entity.User">SELECT id, username, email, age, create_time, update_time FROM users WHERE id = #{id}</select><!-- 查询所有用户 --><selectid="findAll"resulType="User">SELECT id, username, email, age, create_time, update_time FROM users ORDER BY id DESC</select><!-- 根据用户名查询 --><selectid="findByUsername"parameterType="String"resulType="User">SELECT id, username, email, age, create_time, update_time FROM users WHERE username = #{username}</select></mapper>

service层实现

@ServicepublicclassUserService{@AutowiredprivateUserMapperuserMapper;/** * 根据ID获取用户 */publicUsergetUserById(Longid){returnuserMapper.findById(id);}/** * 获取所有用户 */publicList<User>getAllUsers(){returnuserMapper.findAll();}/** * 根据用户名查询用户 */publicUsergetUserByUsername(Stringusername){returnuserMapper.findByUsername(username);}}

controller层实现

@RestController@RequestMapping("/api/users")publicclassUserController{@AutowiredprivateUserServiceuserService;/** * 根据ID查询用户 */@GetMapping("/{id}")publicResponseEntity<User>getUserById(@PathVariableLongid){Useruser=userService.getUserById(id);returnResponseEntity.ok(user);}/** * 查询所有用户 */@GetMappingpublicResponseEntity<List<User>>getAllUsers(){List<User>users=userService.getAllUsers();returnResponseEntity.ok(users);}}

配置SQLSessionFactory

@ConfigurationpublicclassMyBatisConfig{@BeanpublicSqlSessionFactorysqlSessionFactory(DataSourcedataSource)throwsException{SqlSessionFactoryBeansessionFactory=newSqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);// 注入数据源// 设置Mapper XML路径sessionFactory.setMapperLocations(newPathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));sessionFactory.setTypeAliasesPackage("com.xd.springbootmybatis.entity");org.apache.ibatis.session.Configurationconfiguration=neworg.apache.ibatis.session.Configuration();configuration.setMapUnderscoreToCamelCase(true);configuration.setLogImpl(StdOutImpl.class);sessionFactory.setConfiguration(configuration);returnsessionFactory.getObject();}}

请求结果

2026-01-22T10:28:36.101+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : === 进入拦截器 === 2026-01-22T10:28:36.101+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : 请求URL: /api/users 2026-01-22T10:28:36.101+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : 请求方法: GET Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2aefc5b9] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@606613140 wrapping com.mysql.cj.jdbc.ConnectionImpl@28fa08c] will not be managed by Spring ==> Preparing: SELECT id, username, email, age, create_time, update_time FROM user2 ORDER BY id DESC ==> Parameters: <== Columns: id, username, email, age, create_time, update_time <== Row: 7, wujiu, wujiu@example.com, 29, 2026-01-22 10:28:18.937905, 2026-01-22 10:28:18.937905 <== Row: 6, zhouba, zhouba@example.com, 22, 2026-01-22 10:28:18.937905, 2026-01-22 10:28:18.937905 <== Row: 5, sunqi, sunqi@example.com, 35, 2026-01-22 10:28:18.937905, 2026-01-22 10:28:18.937905 <== Row: 4, zhaoliu, zhaoliu@example.com, null, 2026-01-22 10:28:18.936642, 2026-01-22 10:28:18.936642 <== Row: 3, wangwu, wangwu@example.com, 28, 2026-01-22 10:28:18.934671, 2026-01-22 10:28:18.934671 <== Row: 2, lisi, lisi@example.com, 30, 2026-01-22 10:28:18.932989, 2026-01-22 10:28:18.932989 <== Row: 1, zhangsan, zhangsan@example.com, 25, 2026-01-22 10:28:18.926275, 2026-01-22 10:28:18.926275 <== Total: 7 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2aefc5b9] 2026-01-22T10:28:36.105+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : === 控制器执行完成 === 2026-01-22T10:28:36.105+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : === 请求处理完成 === ngsan, zhangsan@example.com, 25, 2026-01-22 10:28:18.926275, 2026-01-22 10:28:18.926275 <== Total: 7 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2aefc5b9] 2026-01-22T10:28:36.105+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : === 控制器执行完成 === 2026-01-22T10:28:36.105+08:00 INFO 17556 --- [nio-8080-exec-9] c.g.interceptor.LoginInterceptor : === 请求处理完成 ===
http://www.jsqmd.com/news/283613/

相关文章:

  • Python神经网络、随机森林、PCA、SVM、KNN及回归实现ERα拮抗剂、ADMET数据预测|附代码数据
  • 基于51/STM32单片机电机霍尔测速PWM控制PID无刷CAN总线无线设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 服务器里面多个网口,电口,光口确定
  • 携程闹乌龙,误发通知全员都被离职了。
  • Python用Ridge、Lasso、KNN、SVM、决策树、随机森林、XGBoost共享单车数据集需求预测及动态资源调配策略优化|附代码数据
  • 基于STM32单片机DDS函数信号发生器AD9850方波正弦波设计套件57(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 使用 useAgent 与 LangGraph 构建全栈 AI Agent 应用
  • Python、Flask、ECharts及MySQL疾病疫情数据可视化系统设计与实现——多模块联动实时展示优化|附代码数据
  • Java泛型详解
  • 批量校正图像方向(校正PDF页面方向)
  • 基于51/STM32单片机智能台灯路灯坐姿语音光照PWM调光无线设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 国产知识管理平台崛起:Gitee Wiki如何领跑企业数字化转型新赛道
  • Gitee领跑2026年项目管理工具市场:技术驱动与本土化优势双轮驱动
  • 2026年全球医疗行业趋势研究报告:AI医疗、创新药与医疗器械|附240+份报告PDF、数据、可视化模板汇总下载
  • 高通QCE工程实践:硬件加密加速从入门到调试
  • ClevNote安卓版(安卓手机备忘录应用)
  • 走向开放硅:Baochip-1x 的 RISC-V MCU 架构与工程实践
  • JMeter压力测试,如何“温柔”地搞垮你的服务器?
  • 技术日报|微软AI训练器登顶,X算法源码重回GitHub热榜
  • # 一个简单的提示词技巧,让我的 AI 变聪明了 200%
  • 数组算法分享 | 代码随想录(CPP+LeetCode)
  • 【大数据毕设源码分享】django基于协同过滤算法+数据可视化的电影个性化推荐系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • cuas ai相关论文 Awesome-Efficient-Agents
  • “DeepSeek 时刻” 一周年
  • Skills、Commands、Agents、Plugins——这些概念你分得清吗?
  • 【大数据毕设源码分享】django基于协同过滤算法+数据可视化的经济型酒店推荐系统大数据的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 不用背理论!5 个新手设计技巧,快速提升作品质感
  • 向量数据库 vs 知识图谱:GraphRAG 的崛起
  • 最新谷歌商店安装教程(保姆级),谷歌三件套问题汇总!闪退,无法登录等各手机解决方案
  • 数组算法-双指针