欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > MyBatis框架(入门)

MyBatis框架(入门)

2025/5/19 5:42:25 来源:https://blog.csdn.net/2301_77071977/article/details/148031131  浏览:    关键词:MyBatis框架(入门)

引言

在 Java 开发中,持久层框架起着至关重要的作用,它帮助开发者更高效地与数据库进行交互。MyBatis 作为一个优秀的基于 Java 的持久层框架,因其简单易用、灵活高效的特点,受到了广大开发者的喜爱。本文将结合笔记内容,对 MyBatis 的相关知识进行系统的整理和详细的讲解。

一、MyBatis框架概述

MyBatis 是一个优秀的基于 Java 的持久层框架,它内部对 JDBC 进行了封装,让开发者只需关注 SQL 语句,而无需关心 JDBC 的复杂代码,大大简化了开发过程。MyBatis 通过 XML 或者注解的方式配置要执行的 Statement 对象,将 Java 对象与 SQL 语句中的动态参数进行映射,最后执行 SQL 语句并将结果以 Java 对象的形式返回,采用了 ORM(对象关系映射)的思想。

 二、MyBatis 入门程序

2.1创建数据库和表结构

首先需要创建数据库和表结构,示例代码如下:

create database mybatis_db;
use mybatis_db;CREATE TABLE `user` (`id` int(11) NOT NULL auto_increment,`username` varchar(32) NOT NULL COMMENT '用户名称',`birthday` datetime default NULL COMMENT '生日',`sex` char(1) default NULL COMMENT '性别',`address` varchar(256) default NULL COMMENT '地址',PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'老王','2018-02-27 17:47:08','男','北京'),(2,'熊大','2018-03-02 15:09:37','女','上海'),(3,'熊二','2018-03-04 11:34:34','女','深圳'),(4,'光头强','2018-03-04 12:04:06','男','广州');

 2.2 MyBatis 入门步骤

 创建 Maven 项目:创建一个 Maven Java 工程,并引入相关坐标。

<dependencies><!--mybatis核心包--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!--mysql驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- 单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency><!-- 日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
</dependencies>

编写User实现类:定义User类,属性尽量使用包装类型

为什么使用包装类型而不是基本类型?

1、 NULL 与 0 的本质区别

基本类型 (int) 默认值问题

private int age;  // 默认值为0

当 age=0 时,无法区分:

  • 用户确实输入了0岁

  • 用户根本没有输入年龄(此时应该为null)

 包装类型 (Integer) 的明确语义

private Integer age;  // 默认值为null
  • null 明确表示"未设置"或"未知"

  • 0 表示明确的0值

基本类型会强制将数据库NULL转换为默认值(如0),导致数据失真。

package cn.tx.domain;import java.io.Serializable;
import java.util.Date;public class User implements Serializable{private static final long serialVersionUID = 525400707336671154L;private Integer id;private String username;private Date birthday;private String sex;private String address;// 省略 getter 和 setter 方法以及 toString 方法
}

编写 UserMapper 接口和方法:定义 UserMapper 接口,包含查询所有用户的方法。

package cn.tx.mapper;import java.util.List;
import cn.tx.domain.User;public interface UserMapper {public List<User> findAll();
}

编写 UserMapper.xml 配置文件:在 resources 目录下创建 mapper 文件夹,并编写 UserMapper.xml 配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qcbyjy.mapper.UserMapper"><select id="findAll" resultType="com.qcbyjy.domain.User">select * from user;</select>
</mapper>

其中,namespace 表示名称空间,用于查找 UserMapper 接口中的方法;id 属性对应 UserMapper 接口中的方法名;resultType 表示方法的返回值类型。

 编写主配置文件:在 resources 目录下创建 SqlMapConfig.xml 配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 配置环境们 --><environments default="mysql"><!-- 配置具体的环境 --><environment id="mysql"><!-- 配置事务管理类型 --><transactionManager type="JDBC"/><!-- 配置是否需要使用连接池,POOLED使用,UNPOOLED不使用 --><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis_db"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!-- 加载映射的配置文件 --><mappers><mapper resource="mappers/UserMapper.xml"/></mappers>
</configuration>

编写入门程序:编写测试类,测试查询所有用户的方法。

package cn.tx.test;import java.io.InputStream;
import java.util.List;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import cn.tx.domain.User;
import cn.tx.mapper.UserMapper;public class UserTest {@Testpublic void testFindAll() throws Exception {// 加载主配置文件,目的是构建SqlSessionFactory的对象InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");// 创建SqlSessionFactory对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);// 使用SqlSessionFactory工厂对象创建SqlSession对象SqlSession session = factory.openSession();// 通过session创建UserMapper接口的代理对象UserMapper mapper = session.getMapper(UserMapper.class);// 调用查询所有的方法List<User> list = mapper.findAll();// 遍历集合for (User user : list) {System.out.println(user);}// 释放资源session.close();in.close();}
}

三、代理Dao方式的CRUD操作

3.1 UserMapper 接口和 UserMapper.xml 配置文件

 在 UserMapper 接口中定义增删改查等方法:

package cn.tx.mapper;import java.util.List;
import cn.tx.domain.User;public interface UserMapper {public List<User> findAll();public User findById(Integer userId);public void insert(User user);public void update(User user);public void delete(Integer userId);public List<User> findByName(String username);public Integer findByCount();
}

在 UserMapper.xml 配置文件中实现这些方法对应的 SQL 语句:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qcbyjy.mapper.UserMapper"><select id="findAll" resultType="com.qcbyjy.domain.User">select * from user</select><select id="findById" resultType="com.qcbyjy.domain.User" parameterType="int">select * from user where id = #{id};</select><insert id="insert" parameterType="com.qcbyjy.domain.User"><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select last_insert_id();</selectKey>insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})</insert><update id="update" parameterType="com.qcbyjy.domain.User">update user set username = #{username},birthday = #{birthday},sex = #{sex},address=#{address} where id = #{id}</update><delete id="delete" parameterType="Integer">delete from user where id = #{id}</delete><select id="findByName" resultType="com.qcbyjy.domain.User" parameterType="string"><!-- 第一种方式的SQL语句  -->select * from user where username  like #{username}<!-- 第二章SQL语句的编写 强调:'%${value}%'不能修改,固定写法(不推荐使用)  --><!-- SELECT * FROM  user where username LIKE  '%${value}%'--></select><select id="findByCount" resultType="int">select count(*) from user</select>
</mapper>

 3.2 UserTest 测试类

 编写测试类,对增删改查方法进行测试:

package cn.tx.test;import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import cn.tx.domain.User;
import cn.tx.mapper.UserMapper;public class UserTest {private InputStream in;private SqlSession session;private UserMapper mapper;@Beforepublic void init() throws Exception {// 加载配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");// 创建工厂对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);// 创建Session对象session = factory.openSession();// 获取到代理对象mapper = session.getMapper(UserMapper.class);}@Afterpublic void destory() throws IOException {in.close();session.close();}@Testpublic void testFindAll() throws Exception {List<User> list = mapper.findAll();// 遍历for (User user : list) {System.out.println(user);}}@Testpublic void testFindById() throws Exception {User user = mapper.findById(41);System.out.println(user);}@Testpublic void testInsert() throws Exception {User user = new User();user.setUsername("美美");user.setBirthday(new Date());user.setSex("男");user.setAddress("顺义");mapper.insert(user);session.commit();System.out.println(user.getId());}@Testpublic void testUpdate() throws Exception {User user = mapper.findById(41);user.setUsername("小凤");mapper.update(user);session.commit();}@Testpublic void testDelete() throws Exception {mapper.delete(48);session.commit();}@Testpublic void testFindByName() throws Exception {List<User> list = mapper.findByName("王");for (User user : list) {System.out.println(user);}}@Testpublic void testFindByCount() throws Exception {Integer count = mapper.findByCount();System.out.println("总记录数:"+count);}
}

3.3 模糊查询符号使用的区别

  • #{}:可以实现 preparedStatement 向占位符中设置值,自动进行 Java 类型和 JDBC 类型转换,能有效防止 SQL 注入。可以接收简单类型值或 POJO 属性值,如果 parameterType 传输单个简单类型值,#{} 括号中可以是 value 或其它名称。
  • ${}:将传入的内容拼接在 SQL 中且不进行类型转换,只能接收简单类型值或 POJO 属性值,如果 parameterType 传输单个简单类型值,${} 括号中只能是 value。

 1. 安全查询示例

<!-- 使用#{} (推荐) -->
<select id="findUserById" parameterType="int" resultType="User">SELECT * FROM user WHERE id = #{userId}<!-- 等价于PreparedStatement: SELECT * FROM user WHERE id = ? -->
</select><!-- 使用${} (危险!) -->
<select id="findUserByName" parameterType="string" resultType="User">SELECT * FROM user WHERE username = '${value}'<!-- 等价于直接拼接: SELECT * FROM user WHERE username = '输入值' -->
</select>

攻击测试

// 如果传入: 
String name = "admin' OR '1'='1";// #{}方式执行:
SELECT * FROM user WHERE username = 'admin\' OR \'1\'=\'1'  -- 安全,作为整体字符串处理// ${}方式执行:
SELECT * FROM user WHERE username = 'admin' OR '1'='1'     -- 危险! 会返回所有用户

2、必须使用${value}的情况 

  • #{}生成的PreparedStatement可被缓存复用

  • ${}每次都会重新编译SQL

四、MyBatis参数详解

 MyBatis 中主要涉及两种参数类型:parameterType(输入参数)和 resultType(输出结果类型),下面分别介绍:

1. parameterType(输入参数类型)

用于指定 SQL 语句的输入参数类型,支持以下几类:

(1)简单数据类型
  • 类型:包括基本数据类型(如 intdoublelong)和包装类(如 IntegerString)。
  • 特点:框架支持简写,例如 intintegerInteger 等都可代表 java.lang.Integer
(2)POJO(JavaBean 实体类)对象类型
  • 场景:传入自定义的实体类(如 User)作为参数。
  • 注意:默认需使用全类名(如 com.qcbyjy.domain.User),但若在配置文件中注册了别名(见下文),可使用别名简化。
(3)POJO 包装对象类型
  • 场景:当需要传递多个实体类或附加参数时,可定义一个包装类(如 QueryVo),包含多个实体类属性(如 UserRole)。

 示例

public class QueryVo implements Serializable {private String name; // 自身属性private User user;   // 关联 User 对象private Role role;   // 关联 Role 对象// 省略 getter/setter
}
<select id="findByVo" parameterType="com.qcbyjy.domain.QueryVo" resultType="com.qcbyjy.domain.User">select * from user where username = #{user.username} <!-- 访问包装类中的 User 对象属性 -->
</select>

2. resultType(输出结果类型)

用于指定 SQL 语句执行结果的返回类型,支持以下几类:

(1)简单数据类型
  • 类型:与 parameterType 类似,如 intStringlong 等,用于统计结果(如计数)。
(2)POJO 数据类型
  • 场景:将查询结果映射为单个实体类对象(如 User)。
  • 条件:要求 SQL 查询的列名与 POJO 的属性名 完全一致,否则无法自动映射。
(3)resultMap(自定义结果映射)
  • 作用:当 SQL 列名与 POJO 属性名不一致时,通过 resultMap 手动映射列名和属性名。

示例: 

<!-- Mapper 中的查询语句 -->
<select id="findUsers" resultMap="userMap">select id _id, username _username, ... from user <!-- 列名带前缀 "_" -->
</select><!-- 定义 resultMap 映射关系 -->
<resultMap id="userMap" type="com.qcbyjy.domain.User"><result property="id" column="_id"/>       <!-- 将列 "_id" 映射到属性 "id" --><result property="username" column="_username"/><!-- 其他属性映射 -->
</resultMap>
  • 扩展resultMap 还可处理复杂映射(如一对一、一对多关系),适用于多表查询结果的封装。

 五、SqlMapConfig.xml 配置文件

 MyBatis 的核心配置文件,用于管理数据库连接、别名、映射文件等信息。以下是关键配置项:

1. 数据库信息管理(properties 标签)

  • 作用:统一管理数据库连接参数(如驱动、URL、用户名、密码),支持从外部文件读取。

 方式一:直接在配置文件中定义

<configuration><properties><property name="jdbc.driver" value="com.mysql.jdbc.Driver"/><property name="jdbc.url" value="jdbc:mysql:///mybatis_db"/><property name="jdbc.username" value="root"/><property name="jdbc.password" value="root"/></properties><!-- 其他配置 -->
</configuration>
方式二:引用外部属性文件(推荐)

1、创建 jdbc.properties 文件(放在类路径下):

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis_db
jdbc.username=root
jdbc.password=root

 2、在 SqlMapConfig.xml 中引用:

<configuration><properties resource="jdbc.properties"/> <!-- resource 为文件相对路径 --><!-- 配置数据库连接时使用 ${key} 取值 --><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource>
</configuration>

2. 类型别名(typeAliases 标签)

  • 作用:为类名设置简短别名,简化配置中的全类名书写。

 方式一:为单个类定义别名

<typeAliases><typeAlias type="com.qcbyjy.domain.User" alias="user"/> <!-- 别名不区分大小写 -->
</typeAliases>
  • 使用:在 Mapper 中可直接用 resultType="user" 代替全类名。

 方式二:为包下所有类自动生成别名

<typeAliases><package name="com.qcbyjy.domain"/> <!-- 自动将包内类名作为别名(首字母不区分大小写) -->
</typeAliases>
  • 效果:若类名为 User,别名即为 user 或 User 等(忽略大小写)。

 3. 其他关键配置

 环境配置(environments)

<environments default="mysql"> <!-- default 指定默认环境 --><environment id="mysql"><transactionManager type="JDBC"/> <!-- 事务管理类型,JDBC 表示使用数据库自带事务 --><dataSource type="POOLED"> <!-- 连接池类型,POOLED 为数据库连接池 --><!-- 数据库连接参数 --></dataSource></environment>
</environments>

映射文件加载(mappers)

<mappers><mapper resource="mappers/UserMapper.xml"/> <!-- 引用 Mapper 配置文件 -->
</mappers>

总结

  • parameterType:控制输入参数类型,简单类型可简写,复杂类型需用包装类或实体类。
  • resultType:控制输出结果类型,列名与属性名一致时直接用 resultType,不一致时用 resultMap 手动映射。
  • SqlMapConfig.xml:通过 properties 管理数据库信息,typeAliases 简化类名,mappers 加载 SQL 映射文件,提升配置的可读性和可维护性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词