news 2026/2/2 17:34:58

第8章:从jdbc到MyBatis

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第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 : === 请求处理完成 ===
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/1 17:21:22

智慧作为文明宪章:《贾子普世智慧公理》的界定、裁决与终极警示

智慧作为文明宪章&#xff1a;《贾子普世智慧公理》的界定、裁决与终极警示摘要&#xff1a; 《贾子普世智慧公理》是一部文明级规范体系&#xff0c;其核心是“智慧本体条款”&#xff0c;以四大公理&#xff08;思想主权、普世中道、本源探究、悟空跃迁&#xff09;精确定义了…

作者头像 李华
网站建设 2026/2/2 15:57:01

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

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

作者头像 李华
网站建设 2026/2/1 2:45:32

Java泛型详解

Java 泛型详解&#xff08;2025–2026 面试/实战最实用版&#xff09; 泛型&#xff08;Generics&#xff09;是 Java 5 引入的最重要特性之一&#xff0c;到今天仍然是面试、代码审查、框架源码阅读中最常考察的点。 下面按从基础到高阶的顺序&#xff0c;把最容易混淆、最常…

作者头像 李华
网站建设 2026/2/2 7:20:57

不用背理论!5 个新手设计技巧,快速提升作品质感

新手做设计&#xff0c;总怕自己没基础做不出好作品——要么版面乱成一团&#xff0c;要么配色丑到辣眼&#xff0c;要么重点根本不突出。其实不用学PS高级功能&#xff0c;不用背配色理论&#xff0c;抓住这5个能直接落地的技巧&#xff0c;几分钟就能做出有质感的作品。 技巧…

作者头像 李华
网站建设 2026/1/31 7:22:19

【大数据毕设全套源码+文档】基于Djangod+协同过滤算法的经济型酒店推荐系统大数据的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/2/2 8:37:00

快速验证:用中文Cursor一小时打造天气APP

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个基于Python的天气查询应用原型&#xff0c;要求&#xff1a;1. 全程使用中文版Cursor 2. 展示AI生成代码过程 3. 包含API调用和UI设计 4. 可一键运行的完整项目。使用Flas…

作者头像 李华