Skip to content

第十一章 MyBatis v1.0 ​

IDEA相关插件:MyBatisX是一款基于IDEA的快速开发Mybatis的插件,为效率而生

第一部分 MyBatis基础 ​

一、依赖项 ​

1.核心依赖 ​

MyBatis Framework

2.MySQL连接依赖 ​

MySQL Driver

二、快速入门 ​

1.准备工作 ​

创建SpringBoot工程、数据库表、数据表的实体类

java
public class Result {
    <修饰符> <包装数据类型> <字段名>;  //字段名转化为标准小驼峰命名(user_id->userId)
    ...  //构造函数,toString等
}

2.配置MyBatis ​

bash
#配置数据库的连接信息-四要素
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接url:jdbc:mysql://<host>:<port>/<database>
spring.datasource.url=<数据库连接url>
#连接数据库的用户名
spring.datasource.username=<数据库用户名>
#连接数据库的密码
spring.datasource.password=<数据库密码>

3.数据封装 ​

MyBatis中使用驼峰命名或其他情况下导致实体类属性名与数据库列名不一致的情况解决方案

  1. 在SQL语句中为不一样的列起别名
java
@Select("select id, username, password, job, dept_id deptId, update_time updateTime from emp where id = #{id}")
public Emp getById(Integer id);
  1. 手动结果映射(通过@Results及@Result进行手动结果映射)
java
@Select("select * from emp where id = #{id}")
@Results({
    @Result(column = "dept_id", property = "deptId"),
    @Result(column = "update_time", property = "updateTime")
})
public Emp getById(Integer id);
  1. 开启驼峰命名自动映射
java
#开启驼峰命名自动映射,即从数据库字段名a_column映射到Java属性名aColumn
mybatis.configuration.map-underscore-to-camel-case=true

4.执行查询语句 ​

java
@Mapper
public interface MyMapper {
    @Select("<select语句>")
    public List<Result> list();  //Result为结果的实体类
}

5.单元测试 ​

java
@SpringBootTest
class ApplicationTests {
    @Autowired
    private MyMapper myMapper;
    
    @Test
    public void test1(){
        List<Result> myList = myMapper.list();
        myList.stream().forEach(result -> {
        	System.out.println(result);
        });
    }
}

三、配置SQL提示 ​

[配置流程]
  1. 选中SQL语句部分->右键点击->显示上下文操作

image.png

  1. 引入语言或引用

image.png

  1. 选中MySQL

image.png

四、数据库连接池 ​

数据库连接池是个容器,负责分配、管理数据库连接(Connection)

1.作用 ​

  1. 数据库连接池允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
  2. 数据库连接池会释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏

2.优势 ​

  1. 资源重用
  2. 提升系统响应速度
  3. 避免数据库连接遗漏

3.使用数据库连接池 ​

标准接口:DataSource

接口功能:getConnection()

常见产品:Hikari(SpringBoot默认)、Druid(阿里巴巴开源)、DBCP(不常用)、C3P0(不常用)

切换数据库连接池:引入数据库连接池起步依赖(以Druid为例)

xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>

五、日志输出配置 ​

bash
#制定mybatis输出日志的位置,输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

六、MyBatis 优点 ​

  1. 避免了JDBC频繁建立连接与释放连接造成的资源浪费与性能消耗(数据库连接池)
  2. 避免了JDBC建立连接使用硬编码的问题
  3. 避免了繁琐的操作

第二部分 MyBatis操作数据库 ​

一、Lombok ​

1.作用 ​

动态生成缺失的getter、setter、equals、hashCode、toString等方法,节省空间,提高开发效率

2.常用注解 ​

二、MyBatis通过注解使用SQL ​

1.使用示例 ​

java
@Mapper
public interface MyMapper {
    @Delete("sql语句")  //使用"#{参数名}"作为占位符,当只有一个参数时参数名可以为任意字符
    public int 函数名(参数列表);  //返回类型为int时表示操作影响的记录行数

    @Select("sql语句")
    public List<Result> 函数名(参数列表);

    //早期写法,参数大于1个时需要使用@param显式指定参数名
    @Select("sql语句")
    public List<Result> 函数名(@Param("参数名")参数类型 参数名,...);
}
java
@Autowired  //@Autowired注解表示自动装配
private myMapper MyMapper;
//...
public static void main(String[] args){
    int result = myMapper.函数名(...);  //进行操作
}

2.参数占位符 ​

  1. #{参数名}:生成预编译SQL,会自动设置参数值,可以防止SQL注入,在参数传递时使用
  2. ${参数名}:拼接SQL,将参数在SQL语句中直接拼接(有SQL注入风险),在对表名、列名动态设置时使用
[示例]

使用${参数名}进行模糊查询(原因:占位符?不能出现在''中):

@Select("select * from user where name like '%${name}%'") //查询名字中含有张的用户

存在问题:性能低、不安全,存在SQL注入问题

使用#{参数名}修改模糊查询(使用MySQL中concat()函数进行字符串拼接)

@Select("select * from user where name like concat('%',#{name},'%')")

3.操作相关注解 ​

4.预编译的优势 ​

  1. 性能更高(缓存编译的SQL语句,在执行SQL语句时进行调用)
  2. 更加安全(可以防止SQL注入)

三、MyBatis通过XML映射文件使用SQL ​

使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句, Java 注解不仅力不从心,还会让你本就复杂的SQL语句更加混乱不堪。因此,如果你需要做一些很复杂的操作,最好用XML来映射语句

1.规范 ​

  1. XML映射文件名称与Mapper接口名称一致,且将XML映射文件和Mapper接口放置在相同包下(同包同名)。
  2. XML映射文件的namespace属性为Mapper接口全限定名一致。
  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

2.SQL语句配置文件 ​

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="Mapper接口全限定名">
  <select id="方法名" resultType="单条记录的返回类型">
    select * from Blog where id = #{id}
  </select>
</mapper>

3.在XML中使用动态SQL ​

随着用户的输入或外部条件的变化而变化的SQL语句

a.动态条件查询——(<if>标签) ​

<if>用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL语句

<where>只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR

<set>会动态地在行首插入SET关键字,并会删掉额外的逗号(与where写法一致,用于update语句中)

xml
<if test="测试条件">
  待拼接语句
</if>
xml
select * from user
<where><!-- 若全为false,不生成if语句;否则按if条件,自动去除子句的开头的AND或OR进行连接 -->
  <if test="name != null">
    name = #{name}
  </if>
  <if test="age != null">
    and age = #{age}
  </if>
</where>
xml
update user
<set>
  <if test="username!=null">
    username=#{username},
  </if>
  <if test="password!=null">
    password=#{password},
  </if>
  <if test="status!=null">
    status=#{status},
  </if>
</set>
WHERE user_id=1;
b.动态条件查询——choose标签 ​

与if标签不同,choose标签类似于if ... else if ... else结构,若判定成功不再次拼接后续语句

xml
<where>
  <choose>
    <when test="id!=null">
      id=#{id}
    </when>
    <when test="LastName!=null and !&quot; &quot;.equals(LastName)">
      last_name=#{lastName}
    </when>
    <otherwise>
      1= 1
    </otherwise>
  </choose>
</where >
c.批量操作数据——(<foreach>标签) ​
xml
<foreach collection="遍历的集合" item="遍历元素名" separator="分隔符" 
  open="遍历前拼接的SQL片段" close="遍历后拼接的SQL片段">
  #{遍历元素名}
</foreach>
xml
<foreach collection="ids" item="id" separator="," open="(" close=")">
  #{id}
</foreach>
<!-- ids={1,2,3}时遍历结果:(1,2,3) -->
d.代码复用——(<sql>、<include>标签) ​

<sql>用于抽取需要复用的sql片段,<include>则用于引入抽取的sql片段以重复使用

xml
<sql id="唯一标识">
  sql片段
</sql>
xml
<include refid="唯一标识"/>

第三部分 原生MyBatis部分 ​

一、配置MyBatis ​

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">
<!--mybatis配置文件根标签-->
<configuration>
  <!--设置控制台SQL输出-->
  <settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
  </settings>

  <environments default="development">
    <environment id="development">
      <!-- 使用jdbc事务管理,目前由mybatis来管理 -->
      <transactionManager type="JDBC"/>
      <!-- 数据库连接池,目前由mybatis来管理 -->
      <dataSource type="POOLED">
        <!--驱动字符串-->
        <property name="driver" value="com.mysql.jdbc.Driver" />
        <!--URL连接地址-->
        <property name="url" value="jdbc:mysql://localhost:3306/db?characterEncoding=UTF-8" />
        <!--用户-->
        <property name="username" value="root" />
        <!--密码-->
        <property name="password" value="123456" />
      </dataSource>
    </environment>
  </environments>
  <!--映射文件配置-->
  <mappers>
    <!-- <mapper>标签用来配置映射文件的,可以有多个 -->
    <mapper resource="mapper/empMapper.xml"/>
  </mappers>
</configuration>

二、相关操作 ​

java
//得到配置文件的流
InputStream inputStream=Resources.getResourceAsStream("config.xml");
//创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//通过工厂得到SqlSession
SqlSession session = factory.openSession();
//增伤改查操作
//第一个参数:映射文件中statement的id,= namespace + statement的id
//第二个参数:指定和映射文件中所匹配的parameterType类型的参数
session.insert(“test.insertDept”, d);//新增
session.update(“test.updateDept”, d);//修改
session.delete(“test.deleteDept”, 60);//删除
session.selectOne(“test.findDeptById”,10);//查询返回单行
session.selectList(“test.findDeptByName”, “C”);//查询返回多行
session.commit();//提交
//释放资源
session.close();
java
//读取配置文件
InputStream inputStream = Resources.getResourceAsStream("configuration.xml");
//创建会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//打开会话
SqlSession session = factory.openSession(true);
//获取Mapper接口
EmpMapper mapper = session.getMapper(EmpMapper.class);
//使用Mapper操作
//...
//关闭
session.close();

二、分页插件 ​

1.修改配置文件加入分页插件 ​

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">
<!--mybatis配置文件根标签-->
<configuration>
  <plugins>
    <plugin interceptor="com.github.pagehelper.PageHelper">
      <!-- 设置数据库类型Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
			<property name="dialect" value="mysql"/>
    </plugin>
  </plugins>
</configuration>

2.使用分页插件 ​

image.png