MyBatis 快速入门
- 前言
- 什么是 MyBatis
- 简介
- 核心特性
- 使用示例
- 配置文件
- Mapper 接口
- SQL 映射文件
- 使用 MyBatis
- = = = = = = = = 如果大家对以上的导读很懵怎么办!没关系 往下阅读! = = = = = = = = =
- 1. MyBatis 介绍
- 1.1. 什么是MyBatis
- 1.2. 持久层
- 1.3. 框架
- 1.4. JDBC 弊端
- 1.5. MyBatis 简化
- 2. MyBatis 快速入门
- 2.1. 查询user表中所有数据
- 2.2. 解决 SQL 映射文件的警告提示
- 3. Mapper 代理开发
- 3.1. 目的
- 3.2. 使用 Mapper 代理方式完成入门案例
- 4. MyBatis 核心配置文件
- 4.1. 类型别名(typeAliasess)
- 4.2. 数据库配置连接环境信息
- 5. 配置文件完成增删改查
- 5.1. 准备环境
- 5.1.1. 数据库表 tb_brand
- 5.1.2. 实体类 Brand
- 5.1.3. 测试用例
- 5.1.4. 安装MyBatiisX 插件
- 5.2. 查询
- 5.2.1. 查询所有数据
- 5.2.2. 查看详情
- 5.2.3. 条件查询
- 1.多条件查询
- 2.多条件-动态条件查询
- 3.单条件-动态条件查询
- 5.3. 添加
- 5.3.1. 主键返回
- 5.4. 修改
- 5.4.1. 修改全部字段
- 5.4.2. 修改动态字段
- 5.5. 删除
- 5.5.1. 删除一个
- 5.5.2. 批量删除
- 6. 参数传递
- 6.1. 单个参数
- 6.2. 多个参数
- 7. 注解完成增删改查
前言
跟着B站学:黑马mybatis教程全套视频教程,2天Mybatis框架从入门到精通
什么是 MyBatis
简介
MyBatis 是一种开源的持久层框架,它简化了数据库交互的过程,使得与数据库的交互更加灵活和高效。MyBatis 通过将 SQL 语句与 Java 代码进行分离,提供了一种直观的、面向对象的数据库访问方式。
核心特性
-
简化数据库访问:MyBatis 使用简单的 XML 或注解配置,将 SQL 语句和 Java 对象映射关系定义在配置文件中,从而实现了数据操作的解耦。
-
灵活的 SQL 编写:MyBatis 支持使用原生的 SQL 语句,可以根据需求编写复杂的查询语句,同时也提供了动态 SQL 的功能,使得在运行时动态生成 SQL 语句成为可能。
-
对象关系映射(ORM):通过配置文件或注解,MyBatis 能够将数据库中的记录映射到 Java 对象上,实现了对象和数据库表之间的简单映射,减少了手动处理数据转换的工作。
-
缓存机制:MyBatis 提供了一级缓存和二级缓存的支持,可以提高查询性能,避免不必要的数据库交互。
-
插件机制:MyBatis 允许用户编写插件,扩展框架的功能,例如自定义拦截器来实现日志记录、性能监控等功能。
使用示例
配置文件
<!-- mybatis-config.xml -->
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis"/><property name="username" value="root"/><property name="password" value="password"/></dataSource></environment></environments><mappers><mapper resource="com/example/mapper/UserMapper.xml"/></mappers>
</configuration>
Mapper 接口
// UserMapper.java
public interface UserMapper {User getUserById(int id);List<User> getAllUsers();void insertUser(User user);void updateUser(User user);void deleteUser(int id);
}
SQL 映射文件
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper"><select id="getUserById" resultType="User" parameterType="int">SELECT * FROM users WHERE id = #{id}</select><select id="getAllUsers" resultType="User">SELECT * FROM users</select><insert id="insertUser" parameterType="User">INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})</insert><update id="updateUser" parameterType="User">UPDATE users SET username=#{username}, email=#{email} WHERE id=#{id}</update><delete id="deleteUser" parameterType="int">DELETE FROM users WHERE id=#{id}</delete>
</mapper>
使用 MyBatis
// 使用 MyBatis 进行数据库操作
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 查询用户
User user = userMapper.getUserById(1);
System.out.println(user);// 查询所有用户
List<User> userList = userMapper.getAllUsers();
System.out.println(userList);// 插入用户
User newUser = new User(4, "NewUser", "newuser@example.com");
userMapper.insertUser(newUser);
sqlSession.commit();// 更新用户
User updatedUser = new User(4, "UpdatedUser", "updateduser@example.com");
userMapper.updateUser(updatedUser);
sqlSession.commit();// 删除用户
userMapper.deleteUser(4);
sqlSession.commit();// 关闭会话
sqlSession.close();
以上示例演示了 MyBatis 的基本用法,通过配置文件定义数据源、Mapper 接口定义数据操作,以及 SQL 映射文件将 SQL 语句与 Java 方法进行映射。MyBatis 的灵活性和简洁性使得它成为许多 Java 项目中首选的持久层框架之一。
= = = = = = = = 如果大家对以上的导读很懵怎么办!没关系 往下阅读! = = = = = = = = =
1. MyBatis 介绍
1.1. 什么是MyBatis
- MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发
- MyBatis 本是 Apache 的一个开源项目 iBatis,2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis。2013 年 11 月迁移到 Github
- 官网:点击前往
1.2. 持久层
- 负责将数据到保存到数据库的那一层代码
- JavaEE三层架构:表现层、业务层、持久层
1.3. 框架
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展
1.4. JDBC 弊端
1.5. MyBatis 简化
注册驱动——写到配置文件中
SQL硬编码——写到配置文件中
操作繁琐
MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作
来看看对持久层框架优化!
2. MyBatis 快速入门
2.1. 查询user表中所有数据
- 创建user表,添加数据
- 创建模块, 导入坐标
- 编写MyBatis核心配置文件→替换连接信息解决硬编码问题
- 编写SQL映射文件→统一管理sq|语句,解决硬编码问题
- 编码
- 定义POJO类
- 加载核心配置文件,获取SqlSessionFactory 对象
- 获取SqlSession对象,执行SQL语句
- 释放资源
1)创建 user 表,添加数据
create database mybatis;
use mybatis;
drop table if exists tb_user;create table tb_user(id int primary key auto_increment,username varchar(20),password varchar(20),gender char(1),addr varchar(30)
);INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');
2)创建模块,导入坐标
模块创建结束
引入mybatic
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>mybatis-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!--mybatis 依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!--mysql 驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><!--junit 单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><!-- 添加slf4j日志api --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.20</version></dependency><!-- 添加logback-classic依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- 添加logback-core依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency></dependencies></project>
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- console表示当前日志信息是可以输出到控制台的--><appender name="Console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>[%level] %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern></encoder></appender><logger name="com.Carter_x" level="DEBUG" additivity="false"><appender-ref ref="Console"/></logger>
</configuration>
从XML中构建SqlSessionFactory
每个基纡MyBatis的应用都是以一个Sq|SessionFactory的实例为核心的。SqlSessionFactory 的实例可以通过Sq|SessionFactoryBuilder获得。而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先配置的Configuration实例来构建出SqlISessionFactory实例。
从XML文件中构建SqlSessionFactory的实例非常简单,建议使用类路径下的资源文件进行配置。但也可以使用任意的输入流 (InputStream) 实例,比如用文件路径字符串或fle:// URL构造的输入流。MyBatis 包含一个名叫 Resources的工具类,它包含一实用方法,使得从类路径或其它位置加载资源文件更加容易。
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
3)编写 MyBatis 核心
XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。后面会再探讨 XML 配置文件的详细内容,这里先给出一个简单的示例:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="com.itheima.pojo"/></typeAliases><!--environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--数据库连接信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment><environment id="test"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--数据库连接信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/><property name="username" value="root"/><property name="password" value="1234"/></dataSource></environment></environments><mappers><!--加载sql映射文件--><!-- <mapper resource="com/itheima/mapper/UserMapper.xml"/>--><!--Mapper代理方式--><package name="com.itheima.mapper"/></mappers>
</configuration>
4)编写 SQL 映射文件,统一管理 sql 语句,解决编码问题
探究已映射的 SQL 语句
现在你可能很想知道 SqlSession 和 Mapper 到底具体执行了些什么操作,但 SQL 语句映射是个相当广泛的话题,可能会占去文档的大部分篇幅。 但为了让你能够了解个大概,这里先给出几个例子。
在上面提到的例子中,一个语句既可以通过 XML 定义,也可以通过注解定义。我们先看看 XML 定义语句的方式,事实上 MyBatis 提供的所有特性都可以利用基于 XML 的映射语言来实现,这使得 MyBatis 在过去的数年间得以流行。如果你用过旧版本的 MyBatis,你应该对这个概念比较熟悉。 但相比于之前的版本,新版本改进了许多 XML 的配置,后面我们会提到这些改进。这里给出一个基于 XML 映射语句的示例,它应该可以满足上个示例中 SqlSession 的调用。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间
--><mapper namespace="com.itheima.mapper.UserMapper"><!--statement--><select id="selectAll" resultType="user">select * from tb_user;</select>
<!-- <select id="selectById" resultType="user">select *from tb_user where id = #{id};</select>--><select id="select" resultType="user">select *from tb_userwhereusername = #{arg0}and password = #{param2}</select></mapper>
5)编码
5-1. 定义 POJO 类
package com.itheima.pojo;// alt + 鼠标左键 整列编辑
public class User {private Integer id;private String username;private String password;private String gender;private String addr;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getAddr() {return addr;}public void setAddr(String addr) {this.addr = addr;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", gender='" + gender + '\'' +", addr='" + addr + '\'' +'}';}
}
5-2. 加载核心配置文件,获取 SqlSessionFactory 对象
//1. 获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
5-3. 获取 SqlSession 对象,执行 SQL 语句
public class App
{public static void main( String[] args ) throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();List<User> users = sqlSession.selectList("test.selectAll");System.out.println(users);//5. 释放资源sqlSession.close();}
}
5-4. 释放资源
//5. 释放资源
sqlSession.close();
2.2. 解决 SQL 映射文件的警告提示
- 产生原因:Idea 和数据库没有建立连接,不识别表信息
- 解决方式:在 Idea 中配置 MySQL 数据库连接
3. Mapper 代理开发
3.1. 目的
List<User> users = sqlSession.selectList("test.selectAll");
"test.selectAll"
又写si了…
- 解决原生方式中的硬编码
- 简化后期执行 SQL
3.2. 使用 Mapper 代理方式完成入门案例
- 定义与SQL映射文件同名的Mapper接口, 并且将Mapper接口和SQL映射文件放置在同一目录下
- 设置SQL映射文件的namespace属性为Mapper接口全限定名
- 在Mapper接口中定义方法,方法名就是SQL映射文件中sq|语句的id,并保持参数类型和返回值类型一致
- 编码
- 通过SqlSession 的getMapper方法获取Mapper接口的代理对象
- 调用对应方法完成sq的执行
1.定义与 SQL 映射文件同名的 Mapper 接口,并且将 Mapper 接口和 SQL 映射文件放置在同一目录下
不方便管理!!!
要配置文件与代码 分开!那怎么办啊
那我是不是只需要建立相同层级!
——注意:Mapper文件的包容易出错,建包时可写成 " com/itheima/mapper "
但是 现在我们显示的还是
我们把xml文件拖进来
编译!我们发现确实在一起了
2.设置 SQL 映射文件的 namespace 属性为 Mapper 接口全限定名
3.在 Mapper 接口中定义方法,方法名就是 SQL 映射文件中sql语句的 id,并保持参数类型和返回值类型一致
4.编码
- 通过 SqlSession 的 getMapper 方式获取 Mapper 接口的代理对象
- 调用对应方法完成 sql 的执行
public class App
{public static void main( String[] args ) throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象UserMapper uesrmapper = sqlSession.getMapper(UserMapper.class);List<User> users = uesrmapper.selectAll();System.out.println(users);//5. 释放资源sqlSession.close();}
}
包扫描!
到现在位置!
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间
--><mapper namespace="org.example.mapper.UserMapper"><!--statement--><select id="selectAll" resultType="org.example.pojo.User">select * from tb_user;</select></mapper>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="org.example.pojo"/></typeAliases><!--environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--数据库连接信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/><property name="username" value="root"/><property name="password" value="1186981212xxx!"/></dataSource></environment><environment id="test"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--数据库连接信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/><property name="username" value="root"/><property name="password" value="1186981212xxx!"/></dataSource></environment></environments><mappers><!--加载sql映射文件-->
<!-- <mapper resource="UserMapper.xml"/>--><!--Mapper代理方式--><package name="org.example.mapper"/></mappers>
</configuration>
UserMapper.java
package org.example.mapper;import org.example.pojo.User;import java.util.List;public interface UserMapper {List<User> selectAll();
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>mybatistest</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>mybatistest</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!--mysql 驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!-- 添加slf4j日志api --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.20</version></dependency><!-- 添加logback-classic依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- 添加logback-core依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency></dependencies>
</project>
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- console表示当前日志信息是可以输出到控制台的--><appender name="Console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>[%level] %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern></encoder></appender><logger name="com.Carter_x" level="DEBUG" additivity="false"><appender-ref ref="Console"/></logger>
</configuration>
User.java
package org.example.pojo;public class User {private Integer id;private String username;private String password;private String gender;private String addr;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getAddr() {return addr;}public void setAddr(String addr) {this.addr = addr;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", gender='" + gender + '\'' +", addr='" + addr + '\'' +'}';}
}
App.java
package org.example;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.example.mapper.UserMapper;
import org.example.pojo.User;import java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** Hello world!**/
public class App
{public static void main( String[] args ) throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象UserMapper uesrmapper = sqlSession.getMapper(UserMapper.class);List<User> users = uesrmapper.selectAll();System.out.println(users);//5. 释放资源sqlSession.close();}
}
4. MyBatis 核心配置文件
配置
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
- 官网:点击前往
注意:配置各个标签,需要遵循前后顺序
4.1. 类型别名(typeAliasess)
<typeAliases><package name="org.example.pojo"/></typeAliases>
相当于 给POJO下的实体类起了个别名 默认的情况下 就是 类本身的名不区分大小写 且不用带包
细节:配置各个标签时,需要遵守前后顺序
4.2. 数据库配置连接环境信息
5. 配置文件完成增删改查
5.1. 准备环境
- 数据库表tb brand
- 实体类Brand
- 测试用例
- 安装MyBatisX插件
5.1.1. 数据库表 tb_brand
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20),-- 排序字段ordered int,-- 描述信息description varchar(100),-- 状态:0:禁用 1:启用status int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),('小米', '小米科技有限公司', 50, 'are you ok', 1);
SELECT * FROM tb_brand;
5.1.2. 实体类 Brand
package org.example.pojo;public class Band {// id 主键private Integer id;// 品牌名称private String brandName;// 企业名称private String companyName;// 排序字段private Integer ordered;// 描述信息private String description;// 状态:0:禁用 1:启用private Integer status;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getBrandName() {return brandName;}public void setBrandName(String brandName) {this.brandName = brandName;}public String getCompanyName() {return companyName;}public void setCompanyName(String companyName) {this.companyName = companyName;}public Integer getOrdered() {return ordered;}public void setOrdered(Integer ordered) {this.ordered = ordered;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}@Overridepublic String toString() {return "Brand{" +"id=" + id +", brandName='" + brandName + '\'' +", companyName='" + companyName + '\'' +", ordered=" + ordered +", description='" + description + '\'' +", status=" + status +'}';}
}
当前的层级关系
5.1.3. 测试用例
我直接再主函数里写就好
5.1.4. 安装MyBatiisX 插件
- MybatisX是一款基于IDEA的快速开发插件,为效率而生。
- 主要功能:
- XML和接口方法相互跳转.
- 根据接口方法生成 statement
- 安装:
MyBatis 本身是一个用于在 Java 中进行持久性数据访问的开源框架。如果 “MyBatiisX” 是 MyBatis 的插件,那么安装它可能会带来一些好处,具体取决于该插件提供的功能。
一般来说,MyBatis 插件可以提供以下一些好处:
-
增强功能: 插件可以扩展或增强 MyBatis 的功能,为开发人员提供更多的选项和工具来简化开发过程。
-
性能优化: 一些插件可能专注于提高 MyBatis 的性能,通过优化查询或缓存策略,以提高应用程序的响应速度。
-
简化配置: 插件可能提供一些简化配置的功能,使得在使用 MyBatis 的过程中更加方便。
-
集成其他技术: 插件可以用于集成其他技术或框架,使得 MyBatis 能够更好地与其他组件协同工作。
-
代码生成: 一些插件可能提供代码生成的功能,可以减少手动编写重复性代码的工作。
请注意,具体的好处取决于插件的具体功能和你的项目需求。在考虑安装任何插件之前,建议查看插件的文档,了解它提供了什么功能以及它是否适合你的项目。此外,插件的稳定性、维护情况以及社区支持也是考虑的因素之一。
5.2. 查询
5.2.1. 查询所有数据
-
编写接口方法: Mapper接口
- 参数:无
- 结果: List< Brand>
List<Brand> selectAll();
-
编写SQL语句: SQL映射文件
<select id="selectAll" resultType="brand">select * from tb_brand;
</select>
- 执行方法,测试
package org.example;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.example.mapper.UserMapper;
import org.example.pojo.Brand;
import org.example.pojo.User;import java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** Hello world!**/
public class App
{public static void main( String[] args ) throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象UserMapper uesrmapper = sqlSession.getMapper(UserMapper.class);List<Brand> brands = uesrmapper.selectAll();System.out.println(brands);//5. 释放资源sqlSession.close();}
}
package org.example.pojo;public class Brand {// id 主键private Integer id;// 品牌名称private String brandName;// 企业名称private String companyName;// 排序字段private Integer ordered;// 描述信息private String description;// 状态:0:禁用 1:启用private Integer status;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getBrandName() {return brandName;}public void setBrandName(String brandName) {this.brandName = brandName;}public String getCompanyName() {return companyName;}public void setCompanyName(String companyName) {this.companyName = companyName;}public Integer getOrdered() {return ordered;}public void setOrdered(Integer ordered) {this.ordered = ordered;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}@Overridepublic String toString() {return "Brand{" +"id=" + id +", brandName='" + brandName + '\'' +", companyName='" + companyName + '\'' +", ordered=" + ordered +", description='" + description + '\'' +", status=" + status +'}';}
}
怎么办!!!!!!!
属性名与列名不一致
1)起别名:在 SQL 语句中,对不一样的类名起别名,别名与实体类属性名一样。可以定义 < sql> 片段,提升复用性。
<!-- * 起别名:对不一样的列名起别名,让别名和实体类的属性名一样* 缺点:每次查询都要定义一次别名
* sql片段* 缺点:不灵活
-->
<!-- sql片段 --><sql id="brand_column">id, brand_name as brandName, company_name as companyName, ordered, description, status</sql><select id="selectAll" resultType="brand">select<include refid="brand_column" />from tb_brand;</select>
2)resultMap:定义了 < resultMap> 完成不一致的属性名和列名的映射。
<!--id:唯一标识type:映射的类型,支持别名
--><resultMap id="brandResultMap" type="brand"><!--id:完成主键字段的映射column:表的列名property:实体类的属性名result:完成一般字段的映射column:表的列名property:实体类的属性名--><result column="brand_name" property="brandName"/><result column="company_name" property="companyName"/>
</resultMap><select id="selectAll" resultMap="brandResultMap">select *from tb_brand;
</select>
5.2.2. 查看详情
- 编写接口方法: Mapper接口
- 参数: id
- 结果: Brand
Brand selectByld(int id);
- 编写SQL语句: SQL 映射文件
<select id="selectById" parameterType="int" resultType="brand">select * from tb_brand where id = #{id};</select>
- 执行方法,测试
package org.example.mapper;import org.example.pojo.Brand;import java.util.List;public interface UserMapper {List<Brand> selectAll();Brand selectById(int id);
}
package org.example;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.example.mapper.UserMapper;
import org.example.pojo.Brand;
import org.example.pojo.User;import java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** Hello world!**/
public class App
{public static void main( String[] args ) throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象UserMapper uesrmapper = sqlSession.getMapper(UserMapper.class);//4. 执行方法Brand brand = uesrmapper.selectById(1);System.out.println(brand);//5. 释放资源sqlSession.close();}
}
使用细节
-
参数占位符:
- 1)
#{}
: 执行SQL时,会将#{}
占位符替换为?
,将来自动设置参数值 -
${}
: 拼SQL。会存在SQL注入问题
-
- 使用时机:
- 参数传递,都使用
#{}
- 如果要对表名、列名不固定 ,进行动态设置,只能使用
${}
进行sq|拼接。
- 1)
-
parameterType:
- 用于设置参数类型,该参数可以省略
-
SQL语句中特殊字符处理:
- 转义字符
<
- <![CDATA[内容]]>: `CD提示`
- 转义字符
5.2.3. 条件查询
1.多条件查询
- 编写接口方法: Mapper接口
- 参数:所有查询条件
- 结果: List < Brand>
List<Brand> selectByCondition(@Param("status')int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
List<Brand> selectByCondition(Brand brand);
List<Brand> selectByCondition(Map map);
- 编写SQL语句: SQL映射文件
- 执行方法,测试
<select id="selectByCondition" resultMap="brandResultMap">select *from tb brandwherestatus = #{status}and company_ name like #{companyName}and brand_ name like #{brandName}
</select>
SQL 语句设置多个参数的三种方式
1)散装参数:需要使用 @Param (" SQL 中的参数占位符名称")
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
2)实体类封装参数:只需要保证 SQL 中的参数名和实体类属性名对应上,即可设置成功
List<Brand> selectByCondition(Brand brand);
3)map 集合:只需要保证 SQL 中的参数名和 map 集合的键的名称对应上,即可设置成功
List<Brand> selectByConditionSingle(Brand brand);
测试代码:
MyBatisTest
@Testpublic void testSelectByCondition() throws IOException {//接收参数int status = 1;String companyName = "华为";String brandName = "华为";// 处理参数companyName = "%" + companyName + "%";brandName = "%" + brandName + "%";//封装对象/* Brand brand = new Brand();brand.setStatus(status);brand.setCompanyName(companyName);brand.setBrandName(brandName);*/Map map = new HashMap();// map.put("status" , status);map.put("companyName", companyName);// map.put("brandName" , brandName);//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法//List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
// List<Brand> brands = brandMapper.selectByCondition(brand);List<Brand> brands = brandMapper.selectByCondition(map);System.out.println(brands);//5. 释放资源sqlSession.close();}
2.多条件-动态条件查询
动态 SQL
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
<!--动态条件查询* if: 条件判断* test:逻辑表达式* 问题:* 恒等式 where 1 = 1* <where> 替换 where 关键字--><select id="selectByCondition" resultMap="brandResultMap">select *from tb_brand/* where 1 = 1*/<where><if test="status != null">and status = #{status}</if><if test="companyName != null and companyName != '' ">and company_name like #{companyName}</if><if test="brandName != null and brandName != '' ">and brand_name like #{brandName}</if></where></select>
where 就是我们之前说的到的 可以灵活的去掉and
3.单条件-动态条件查询
<select id="selectByConditionSingle" resultMap="brandResultMap">select *from tb_brand<where><choose><!--相当于switch--><when test="status != null"><!--相当于case-->status = #{status}</when><when test="companyName != null and companyName != '' "><!--相当于case-->company_name like #{companyName}</when><when test="brandName != null and brandName != ''"><!--相当于case-->brand_name like #{brandName}</when></choose></where></select>
5.3. 添加
5.3.1. 主键返回
返回添加主键返回
<insert useGeneratedKeys="true" keyProperty="id">
<insert id="addOrderltem" >insert into tb_order_item (goods_name, goods_price, count,order_id)values (#{goodsName}, #{goodsPrice},#{count}, #{orderld});</insert>
生成了 但是没有绑定到对象上面!
<insert id="addOrder" useGeneratedKeys="true" keyProperty="id">insert into tb_order (payment, payment_type, status)Ivalues (#{payment},#{paymentType},#{status});
</insert>
5.4. 修改
5.4.1. 修改全部字段
-
编写接口方法: Mapper接口
- 参数:所有数据
- 结果: void
void update(Brand brand);
-
编写SQL语句: SQL映射文件
-
执行方法,测试
<update id="update">update tb_brandset brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status}where id = #{id};
</update>
5.4.2. 修改动态字段
- 编写接口方法: Mapper接口
- 参数:部分数据,封装到对象中
- 结果: void
- 编写SQL语句: SQL映射文件
- 执行方法,测试
<update id="update">update tb_usersetusername = #{username},password = #{password},gender = #{gender},addr = #{addr}whereid = #{id}
</update>
不能用到通用性,因为只能全改 否则就是赋值成null了
到👇
<update id="update">update tb_brand<set><if test="brandName != null and brandName !=" ">brand_ name = #{brandName},</if><if test="companyName != null and companyName !="">company_ name = #{companyName},</if><if test="ordered != null">ordered = #{ordered},</if><if test="description != null and description !="">description = #{description},</if><if test="status != null">status = #{status},</if></set>where id = #{id};
</update>
5.5. 删除
5.5.1. 删除一个
-
编写接口方法: Mapper接口
- 参数: id
- 结果: void
void deleteByld(int id);
-
编写SQL语句: SQL映射文件
-
执行方法,测试
<delete id="deleteByld">delete from tb_brand where id = #{id}
</delete>
5.5.2. 批量删除
- 编写接口方法: Mapper接口
- 参数: id数组
- 结果: void
void deleteBylds(@Param("ids") int[] ids);
- 编写SQL语句: SQL映射文件
- 执行方法,测试
<delete id="deleteBylds">delete from tb_brandwhere id in (?,?,?)
</delete>
不知道用几个问号啊!
所以要动态!!!!
<!--mybatis会将数组参数,封装为一个Map集合。* 默认:array = 数组* 使用@Param注解改变map集合的默认key的名称--><delete id="deleteByIds">delete from tb_brand where idin<foreach collection="array" item="id" separator="," open="(" close=")">#{id}</foreach>;</delete>
6. 参数传递
建议:将来都使用 @Param 注解来修改 Map 集合中默认的键名,并使用修改后的名称获取值,这样可读性更高
6.1. 单个参数
- POJO类型:直接使用,属性名 和 参数占位符名称一致
- Map集合:直接使用,键名 和 参数占位符名称一致
- Collection:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",collection集合);
map.put("collection",collection集合);
List:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",list集合);
map.put("collection",list集合);
map.put("list",list集合);
Array:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",数组);
map.put("array",数组);
其他类型:直接使用
6.2. 多个参数
多封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",参数值1)map.put("param1",参数值1)map.put("param2",参数值2)map.put("agr1",参数值2)---------------@Param("username")map.put("username",参数值1)map.put("param1",参数值1)map.put("param2",参数值2)map.put("agr1",参数值2)
7. 注解完成增删改查
使用注解开发会比配置文件开发更加方便
写了注解 就不需要写xml的配置文件了
@Select("select * from tb_user where id = #{id}")
public User selectByld(int id);
- 查询: @Select
- 添加: @Insert
- 修改: @Update
- 删除:@Delete
提示:
- 注解完成简单功能
- 配置文件完成复杂功能 ;
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句, Java 注解不仅力不从心,还会让你本就复杂的SQL语句更加混乱不堪。因此, 如果你需要做一些很复杂的操作, 最好用XML来映射语句。
选择何种方式来配置映射,以及认为是否应该要统映射语句定义的形式,完全取决于你和你的团队。换句话说,永远不要拘泥于一种方式, 你可以很轻松的在基于注解和XML的语句映射方式间自由移植和切换。