第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.mzph.cn/news/1199707.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时间同步服务器大型单位推荐

一次时间同步问题的排查与取舍 ——关于北斗 NTP 与本地守时的工程实践 在一个内部业务系统中,我们曾遇到一个看似不起眼、但反复出现的问题: ​不同系统日志时间存在偏差,问题复盘时很难对齐事件顺序​。 起初大家…

Python神经网络、随机森林、PCA、SVM、KNN及回归实现ERα拮抗剂、ADMET数据预测|附代码数据

全文链接&#xff1a;tecdat.cn/?p44844原文出处&#xff1a;拓端数据部落公众号关于分析师在此对Shoufu Lin对本文所作的贡献表示诚挚感谢&#xff0c;他在浙江工业大学完成了工业工程与管理专业的硕士学位&#xff0c;专注深度学习、运筹优化领域。擅长Python、深度学习、运…

基于51/STM32单片机电机霍尔测速PWM控制PID无刷CAN总线无线设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于51/STM32单片机电机霍尔测速PWM控制PID无刷CAN总线无线设计(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码基于51/STM32单片机电机霍尔测速PWM控制PID无刷CAN总线无线设计(设计源文件万字报告讲解)&#xff08;支持资料、…

服务器里面多个网口,电口,光口确定

在设备服务器上架时会涉及到配置网络和IP地址&#xff0c;确认端口的问题&#xff0c;对于有BMC系统的服务器&#xff0c;直接插入光模块和光纤后&#xff0c;可以在BMC里面确认好连接的哪个端口&#xff0c;端口会显示是否已连接光纤。 但是有时候在统信 等linux系统下面使用i…

携程闹乌龙,误发通知全员都被离职了。

1月12日晚&#xff0c;大量携程员工突然收到一条措辞正式的离职通知短信&#xff0c;内容以“XX你好&#xff0c;感谢一路相伴”开头。此次乌龙事件源于内部沟通软件trappal下线&#xff0c;在关停关联手机号绑定功能时&#xff0c;工作人员未提前关闭系统预设的短信提醒&#…

Python用Ridge、Lasso、KNN、SVM、决策树、随机森林、XGBoost共享单车数据集需求预测及动态资源调配策略优化|附代码数据

全文链接&#xff1a;tecdat.cn/?p44851原文出处&#xff1a;拓端数据部落公众号关于分析师在此对Weiduoduo Han对本文所作的贡献表示诚挚感谢&#xff0c;她深耕大数据技术领域&#xff0c;系统掌握Python、Java、Spark等技术工具&#xff0c;精通Java程序设计、数据结构、计…

基于STM32单片机DDS函数信号发生器AD9850方波正弦波设计套件57(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于STM32单片机DDS函数信号发生器AD9850方波正弦波设计套件57(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码 STM32单片机DDS函数信号发生器方波正弦波57 产品功能描述&#xff1a; 本系统由STM32F103C8T6单片机核心板、AD…

使用 useAgent 与 LangGraph 构建全栈 AI Agent 应用

AI agent 正在迅速从令人惊叹的演示演进到大规模的生产级应用&#xff0c;而 LangGraph 让这一转变比以往更顺畅。但在此之前&#xff0c;把这些 agent 接到一个 frontend&#xff08;并为用户提供实时交互&#xff09;往往需要一堆杂乱的 API、state management&#xff0c;以…

Python、Flask、ECharts及MySQL疾病疫情数据可视化系统设计与实现——多模块联动实时展示优化|附代码数据

全文链接&#xff1a;tecdat.cn/?p44846原文出处&#xff1a;拓端数据部落公众号 关于分析师 在此对Chao Xu Li对本文所作的贡献表示诚挚感谢&#xff0c;他完成了电子信息科学与技术专业的本科学位&#xff0c;专注疫情数据可视化与Web开发领域。擅长Python、MySQL、Linux、C…

基于51/STM32单片机智能台灯路灯坐姿语音光照PWM调光无线设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于51/STM32单片机智能台灯路灯坐姿语音光照PWM调光无线设计(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码 08-多功能台灯 基于51/STM32单片机智能台灯路灯坐姿语音播报光照PWM调光无线设计 光照声音插座阈值可调C51-17 光…

批量校正图像方向(校正PDF页面方向)

批量校正图像方向是一款专为扫描类文档设计的图像处理工具&#xff0c;主要用于自动识别并校正图片和PDF文档的页面方向&#xff08;如横版转竖版或竖版转横版&#xff09;。该软件通过智能算法分析页面内容&#xff0c;批量调整方向以确保文档可读性&#xff0c;适用于合同、报…

国产知识管理平台崛起:Gitee Wiki如何领跑企业数字化转型新赛道

国产知识管理平台崛起&#xff1a;Gitee Wiki如何领跑企业数字化转型新赛道 随着"十四五"规划明确提出加快数字化发展步伐&#xff0c;企业知识管理平台正迎来前所未有的战略机遇期。在信创产业蓬勃发展的背景下&#xff0c;国产Wiki系统已从单纯的内容管理工具进化为…

2026年全球医疗行业趋势研究报告:AI医疗、创新药与医疗器械|附240+份报告PDF、数据、可视化模板汇总下载

原文链接&#xff1a;tecdat.cn/?p44820原文出处&#xff1a;拓端抖音号拓端tecdat 在重症监护室的紧急抢救中&#xff0c;AI辅助诊断系统为医生精准识别病灶争取关键时间&#xff1b;在西部偏远乡村的卫生室&#xff0c;国产彩超设备让村民无需奔波县城就能完成基础疾病筛查—…

Gitee领跑2026年项目管理工具市场:技术驱动与本土化优势双轮驱动

Gitee领跑2026年项目管理工具市场&#xff1a;技术驱动与本土化优势双轮驱动 在数字化转型浪潮席卷全球的背景下&#xff0c;项目管理工具已成为企业提升效率、优化资源配置的关键基础设施。2026年的项目管理工具市场呈现出明显的技术驱动特征&#xff0c;其中Gitee作为中国最大…

ClevNote安卓版(安卓手机备忘录应用)

ClevNote是一款方便实用的Android备忘录应用。它提供了多种功能&#xff0c;可以帮助用户管理日常的备忘事项、清单、提醒和密码等。 软件功能 1.备忘录功能&#xff1a;用户可以轻松创建和管理备忘录&#xff0c;写下日常的想法、计划和提醒事项。 2.清单功能&#xff1a;用户…

高通QCE工程实践:硬件加密加速从入门到调试

本文基于高通平台硬件加密实践经验整理&#xff0c;适合应用开发者和系统工程师。通过几个典型场景&#xff0c;带你理解QCE的工作原理、验证方法和调试技巧。 为什么需要关注硬件加密加速&#xff1f; 在Android应用或系统开发中&#xff0c;你是否遇到过这些困惑&#xff1a…

走向开放硅:Baochip-1x 的 RISC-V MCU 架构与工程实践

在开源硬件领域&#xff0c;一款既有芯片级代码又可用于工程实践的项目并不多见。baochip-1x 就是这样一个鲜明例子&#xff1a;它是一个围绕 RISC-V 架构、绝大部分开源逻辑描述的 MCU&#xff08;微控制器&#xff09;项目。该项目的代码托管在 GitHub 上&#xff0c;并提供部…

JMeter压力测试,如何“温柔”地搞垮你的服务器?

大家好&#xff0c;我是小悟。 一、JMeter是何方神圣&#xff1f; 假如&#xff0c;你就是那个在黑色星期五早上8点冲向超市大门的购物狂魔&#xff0c;而JMeter就是你那支可以瞬间克隆出1000个你的神奇部队&#xff01;它不是什么神秘的黑客工具&#xff0c;而是Apache家族里…

技术日报|微软AI训练器登顶,X算法源码重回GitHub热榜

&#x1f31f; TrendForge 每日精选 - 发现最具潜力的开源项目 &#x1f4ca; 今日共收录 8 个热门项目&#xff0c;涵盖 50 种编程语言&#x1f310; 智能中文翻译版 - 项目描述已自动翻译&#xff0c;便于理解&#x1f3c6; 今日最热项目 Top 10 &#x1f947; microsoft/age…

# 一个简单的提示词技巧,让我的 AI 变聪明了 200%

让我的 AI 变“聪明”200% 的一个简单 Prompt 小技巧 为什么你的 AI 总是出错&#xff08;以及该怎么修&#xff09; 想象你在加班做项目。你问你的 AI 助手&#xff1a;“Who is the current Prime Minister of the UK?” 它笃定地答&#xff1a;“Boris Johnson.” 等等…