1. Mybatis基础

1. Mybatis 简介

MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发。
官方文档:https://mybatis.org/mybatis-3/zh/index.html

持久层:操作数据库的那些代码。
JavaEE三层架构:表现层(页面展示)、业务层(逻辑处理)、持久层。

框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础之上构建软件编写更加高效、规范、通用、可扩展。

2. Mybatis 快速入门

在这里插入图片描述

(1) 用 Navicat 连接 MySQL 创建 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) 创建模块,导入坐标

<dependencies>
    <!--mybatis依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!--要连接数据库就得需要mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</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:日志相关-->
    <!--添加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>

(3) 编写 MyBatis 核心配置文件,替换连接信息,解决硬编码问题
(mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--mybatis:数据库名-->
                <!--jdbc:mysql:///mybatis?useSSL=false"也可以-->
                <property name="url" value="jdbc:mysql://localhost/mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载sql映射文件-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

(4) 编写 SQL 映射文件,统一管理 SQL 语句,解决硬编码问题
(UserMapper.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:名称空间。不同名称空间里的同名id不冲突-->
<mapper namespace="test">
    <!--resultType:返回类型,应该是User,所以要定义一个User类-->
    <select id="selectAll" resultType="com.itheima.pojo.User">
        select * from tb_user;
    </select>
</mapper>

(5) 编码

① 定义 POJO 类

public class User {
    private Integer id;
    private String username;
    private String password;
    private String gender;
    private String addr;
    //getter、setter 方法
    //toString 方法
}

② 加载核心配置文件,获取 SqlSessionFactory 对象
③ 获取 SqlSession 对象,执行 SQL 语句
④ 释放资源

public class MybatisDemo {
    public static void main(String[] args) throws IOException {
        //加载mybatis核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取SqlSession对象,用它来执行SQL
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行SQL
        List<User> users = sqlSession.selectList("test.selectAll");
        System.out.println(users);
        //释放资源
        sqlSession.close();
    }
}

附:日志相关的配置文件(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.itheima" level="DEBUG" additivity="false">
        <appender-ref ref="Console"/>
    </logger>


    <!--

      level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
     , 默认debug
      <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
      -->
    <root level="DEBUG">
        <appender-ref ref="Console"/>
    </root>
</configuration>

输出结果:
在这里插入图片描述

3. 使用 idea 写 SQL

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. Mapper 代理开发

目的:解决原生方式中的硬编码,简化后期执行 SQL。

(1) 定义与 SQL 映射文件同名的 Mapper 接口,并且将 Mapper 接口和 SQL 映射文件放置在同一目录下。

public interface UserMapper {
}

在项目中,由于 Java 代码和配置文件一般是分开的,所以简单地将 UserMapper 接口和 UserMapper.xml(SQL 映射文件)放在一起是不合理的。

编译 module 后发现,class 文件和 UserMapper.xml(SQL 映射文件)同在 target/classes/com/ 目录下。
在这里插入图片描述

所以编写代码时,可以在 resources 目录下也新建 com/itheima/mapper 目录,并把 UserMapper.xml 放入其中。这样编译后,class 文件就能与 UserMapper.xml 同在 mapper 目录下,也就相当于满足了 “Mapper 接口和 SQL 映射文件放置在同一目录下” 的条件。

在这里插入图片描述

注意:在 resources 中新建目录时,只能 new directory,分隔符不能用 “·”,要用 “/”:
在这里插入图片描述

既然更改了 SQL 映射文件所在目录,就要更改 MyBatis 核心配置文件中加载该文件的路径:
(mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--mybatis:数据库名-->
                <!--jdbc:mysql:///mybatis?useSSL=false"也可以-->
                <property name="url" value="jdbc:mysql://localhost/mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--更改sql映射文件路径-->
        <!--注意:resource下新建的是dictionary,
        分隔符用“/”,不能用“.”-->
        <mapper resource="com/itheima/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

(2) 设置 SQL 映射文件的 namespace 属性为 Mapper 接口全限定名。
(UserMapper.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:名称空间。不同名称空间里的同名id不冲突-->
<!--设置SQL映射文件的namespace属性为Mapper接口全限定名-->
<mapper namespace="com.itheima.mapper.UserMapper">
    <!--resultType:返回类型,应该是User,所以要定义一个User类-->
    <select id="selectAll" resultType="com.itheima.pojo.User">
        select * from tb_user;
    </select>
</mapper>

(3) 在 Mapper 接口中定义方法,方法名就是 SQL 映射文件中 sql 语句的 id,并保持参数类型和返回值类型一致。
(UserMapper 接口)

public interface UserMapper {
    List<User> selectAll();
}

(4) 编码
① 通过 SqlSession 的 getMapper 方法获取 Mapper 接口的代理对象
② 调用对应方法完成 SQL 的执行

public class MybatisDemo {
    public static void main(String[] args) throws IOException {
        //加载mybatis核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取SqlSession对象,用它来执行SQL
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取UserMapper接口的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //调用对应方法完成 SQL 的执行
        List<User> users = userMapper.selectAll();
        System.out.println(users);
        //释放资源
        sqlSession.close();
    }
}

在 mybatis-config.xml 核心配置文件里,需要加载 SQL 映射文件,现在的加载方式要写 SQL 映射文件的路径,一旦映射文件变多(UserMapper.xml,OrderMapper.xml,GoodsMapper.xml…),就会很繁琐。

但是,如果用了 Mapper 代理的方式,就可以用包扫描的简单方式来加载 SQL 映射文件。

<mappers>
     <!--用包扫描的方式来加载 SQL 映射文件-->
     <!--通过接口来找,所以路径中的分隔符用"."-->
     <package name="com.itheima.mapper"/>
 </mappers>

输出结果:

在这里插入图片描述

5. MyBatis 核心配置文件

在 mybatis-config 中,environments 用于配置数据库连接环境信息。它的内部可以配置多个 environment,通过 default 属性切换不同的 environment。

<environments default="test">

    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <!--mybatis:数据库名-->
            <!--jdbc:mysql:///mybatis?useSSL=false"也可以-->
            <property name="url" value="jdbc:mysql://localhost/mybatis?useSSL=false"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </dataSource>
    </environment>
    
    <environment id="test">
        <!--...-->
    </environment>
    
</environments>

在 UserMapper.xml 中,select 语句的 resultType 原本是 com.itheima.pojo.User,可以进行简化,方法是:
先在 mybatis-config.xml 中设置类型别名,相当于给 pojo下面的所有实体类都取了别名。别名默认是类名,不区分大小写,使用时可以不带所在包的名称。

在这里插入图片描述

下面是一些为常见的 Java 类型内建的类型别名,都是不区分大小写的。
注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在 mybatis 核心配置文件(mybatis-config.xml)中,各个标签要遵守的前后顺序:

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,所报的异常 org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'distinct' in 'class tk.mybatis.mapper.entity.Example$Criteria' 是由于在类 tk.mybatis.mapper.entity.Example$Criteria 中没有名为 'distinct' 的属性的 getter 方法。在您的代码中,您正在使用通用mapper接口的 selectByExample 方法,并且传递了一个 Example 类型的参数。在这个例子中,似乎尝试访问一个名为 'distinct' 的属性,但是在 tk.mybatis.mapper.entity.Example$Criteria 类中找不到该属性的 getter 方法。 对于这个问题,有两种解决方案。一种是修改 selectByExample 方法传递的参数类型,将其改为 Example 类型参数。在您的代码中,您可以使用 Example 类的构造函数来创建一个 Example 对象,并将其作为参数传递给 selectByExample 方法。另一种方案是在原有的代码基础上添加一个条件,使用 Example.Criteria 对象的 andEqualTo 方法来设置条件。在您的代码中,您可以使用 Example.Criteria 对象的 andEqualTo 方法来设置一个名为 'domain' 的条件,值为传入的 domain 参数。 解决方案1: ```java public TCmsSite findByDomain(String domain) { TCmsSite site = new TCmsSite(); Example example = new Example(TCmsSite.class); List<TCmsSite> tCmsSites = siteMapper.selectByExample(example); if (tCmsSites.size() > 0) { site = tCmsSites.get(0); } return site; } ``` 解决方案2: ```java public TCmsSite findByDomain(String domain) { TCmsSite site = new TCmsSite(); Example example = new Example(TCmsSite.class); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("domain", domain); List<TCmsSite> tCmsSites = siteMapper.selectByExample(example); if (tCmsSites.size() > 0) { site = tCmsSites.get(0); } return site; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值