mybatis-3.9.9

mybatis

MyBatis 3 | 入门 – mybatis

环境:

  • JDK 1.8

  • Mysql 5.7(依赖包用8.0代替)

  • maven 3.9.9

  • IDEA

回顾:

  • JDBC

  • mysql

  • java基础

  • junit

SSM框架:配置文件的。最好的方式:看官方文档;

如何获得mybatis?

1、持久层

DAo层,Service层,Controller层

  • 完成持久化工作代码块

  • 层界限十分明显

2、为什么需要Mbatis?

  • 帮助程序员将数据存入数据库中

  • 方便

  • 传统的JDBC太复杂,简化

  • 不用Mybatis也可以,更容易上手

3、第一个Mybatis程序

思路:导入环境---》导入Mybatis--》编写代码--》测试!

3.1、搭建环境

搭建数据库:创建数据库和表

新建项目:

  1. 新建一个普通maven项目

  2. 删除src目录

  3. 导入依赖(pom.xml)

<!-- 导入依赖 -->
   <dependencies>
       <!-- mysql 驱动 -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.33</version> <!-- 最新稳定版 -->
       </dependency>
       <!-- mybatis -->
       <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.5.16</version>
       </dependency>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
       </dependency>
   </dependencies>

导入依赖出现过的错误:


删除.lastUpdated文件,重新刷新

maven仓库和阿里云mavenv仓库没有mysql5.7.19版本依赖包,用8.0版本代替

3.2、创建一个模块

创建一个普通 modul,这样,模块里面也会有pom.xml文件

  • 编写mybatis配置文件

    [](MyBatis 3 | 简介 – mybatis)

    进入网站--》点击入门--》

    • 使用xml配置mybatis

      <?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="${driver}"/>
              <property name="url" value="${url}"/>
              <property name="username" value="${username}"/>
              <property name="password" value="${password}"/>
            </dataSource>
          </environment>
        </environments>
        <mappers>
          <mapper resource="org/mybatis/example/BlogMapper.xml"/>
        </mappers>
      </configuration>
      

      创建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核心配置文件 -->
      <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?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
                      <property name="username" value="root"/>
                      <property name="password" value="123456"/>
                  </dataSource>
              </environment>
          </environments>
      
      </configuration>
      
    • IDEA与数据库连接失败

      措施:排除用户密码不匹配;检查用户权限;查看mysql服务状态;检查IDEA中主机名、端口号、用户、密码、Mysql-connector驱动是否下载。最后通过编辑mysql配置文件my.ini文件后成功连接。

      添加bind-address = 127.0.0.1 # 只允许本地连接

  • 编写mybatis工具类

    1. 创建工具类

  1. 查看网址:MyBatis 3 | 入门 – mybatis
  • 从xml构建SqlSessionFactory,从 SqlSessionFactory 中获取 SqlSession

    package com.yang.utils;
    

    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 java.io.IOException;
    import java.io.InputStream;

    //sqlSessionFactory
    public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {

       try {
           //使用mybatis第一步:获取sqlSessionFactory对象
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
       } catch (IOException e) {
           e.printStackTrace();
       }
    

    }
    //有了sqlSessionFactory,从中获取sqlSession实例。
    public static SqlSession getSqlSession(){

       return sqlSessionFactory.openSession();
    

    }

    }

3.3、编写代码

  • 实体类

    package com.yang.pojo;
    
    public class User {
        private int id;
        private String name;
        private String pwd;
    
        public User(){
    
        }
    
        public User(int id, String name, String pwd){
            this.id=id;
            this.name=name;
            this.pwd=pwd;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    
        public String getPwd() {
            return pwd;
        }
    }
    
  • Dao接口

    package com.yang.dao;
    
    import com.yang.pojo.User;
    
    import java.util.List;
    
    public interface UserDao {
        List<User> getUserList();
    }
    
  • 接口实现类(注意空间绑定接口,名字,返回类型不要写错)

    <?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=绑定一个对应的Dao/Mapper接口 -->
    <mapper namespace="com.yang.dao.UserDao">
        <!-- select 查询语句 -->
        <select id="getUserList" resultType="com.yang.pojo.User">
            select * from mybatis.user
        </select>
    </mapper>
    

3.4、测试

注意:

  • 错误org.apache.ibatis.binding.BindingException: Type interface com.yang.dao.UserDao is not known to the MapperRegistry.

措施:在mybatis核心配置文件里面注册Mapper.xml

<!--每一个Mapper.xml文件都需要在mybatis核心配置文件配置 -->
    <mappers>
        <mapper resource="com/yang/dao/UserMapper.xml"/>
    </mappers>
  • 错误二:Could not find resource com/yang/dao/UserMapper.xml

    措施:

    <!--在build中配置resources,防止我们资源导出失败的问题-->
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    
  • 错误三:

    • Maven 在构建过程中使用了平台默认编码(虽然实际是 UTF-8),这可能导致跨平台构建不一致。
      措施:在pom.xml文件加上
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
  • 清理并重建项目:删掉target目录--》打开IDEA右侧Maven界面--》展开Lifecycle--》双击clean--》双击install

junit测试代码:

package com.yang.dao;

import com.yang.pojo.User;
import com.yang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest {

    @Test
    public void test(){
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.getUserList();

        for (User user : userList){
            System.out.println(user);
        }


        //关闭SqlSession
        sqlSession.close();
    }

}

需要注意:

  • 配置文件注册

  • 绑定接口

  • 方法名

  • 返回类型

  • Maven导出资源

小结:

MybatisUtils->mybatis-cofig.xml

User

UserDao->UserMapper.xml

UserDaoTest

pom.xml

4、CPRUD

4.1、namespace

namespace中的包名要与Dao/Mapper接口包名一致

4.2、select,······

选择查询

  • id :namespace中的方法名

  • resultType :sql语句执行返回结果

  • parameterType:参数类型

  1. 编写接口

  2. 编写对应Mapper.xml的sql语句

  3. 测试

注意:增删改需要提交事务

4.3、代码

//UserMapper接口
package com.yang.dao;

import com.yang.pojo.User;

import java.util.List;

public interface UserMapper {
    //查询全部用户
    List<User> getUserList();
    //根据id查询用户信息
    User getUserById(int id);
    //插入一条用户信息
     int insertUser(User user);
     //更新一条记录
    int updateUser(User user);
    //删除一条记录
    void deleteUser(int id);


}
<?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=绑定一个对应的Dao/Mapper接口 -->
<mapper namespace="com.yang.dao.UserMapper">
    <!-- select 查询语句 -->
    <select id="getUserList" resultType="com.yang.pojo.User">
        select * from mybatis.user
    </select>

    <!--根据id查询用户信息-->
    <select id="getUserById" resultType="com.yang.pojo.User">
        select * from mybatis.user where id = #{id}
    </select>

    <!--插入一条用户信息(属性可以从User表里面获取)-->
    <insert id="insertUser" parameterType="com.yang.pojo.User">
        insert into mybatis.user (id,name,pwd) value(#{id},#{name},#{pwd})
    </insert>

    <!--更新一条记录-->
    <update id="updateUser" parameterType="com.yang.pojo.User" >
        update mybatis.user set name = #{name},pwd = #{pwd} where id = #{id}
    </update>

    <!--删除一条记录-->
    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id}
    </delete>
</mapper>
//UserMapperTest测试
package com.yang.dao;

import com.yang.pojo.User;
import com.yang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserMapperTest {

    @Test
    public void test(){
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserList();

        for (User user : userList){
            System.out.println(user);
        }


        //关闭SqlSession
        sqlSession.close();
    }

    @Test
    public void UserByIdTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //获得接口
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(6);
        System.out.println(user);


        sqlSession.close();
    }

    @Test
    public void insertUserTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.insertUser(new User(6,"shishi","123456"));
        //提交事务
        sqlSession.commit();

        sqlSession.close();
    }

    @Test
    public void updateUserTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateUser(new User(6,"liushishi","123456"));

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.deleteUser(6);

        sqlSession.commit();
        sqlSession.close();
    }
}

4.4、万能Map

Map传递参数,直接在sql中取出key即可;

对象传递参数,直接在sql中传递对象的属性即可;

只有一个基本类型参数的情况下,可以直接在sql中取到;

多个参数用Map或者注解

5、配置解析

xml文件里面的标签都是有顺序的!!!!!

5.1、核心配置文件

  • mybatis-config.xml

  • Mybatis的配置文件包含了

5.2、 环境配置(environments)

Mybatis 可以配置成适应多种环境;

Mybatis默认的事务管理器就是JDBC,连接池:POOLED

5.3、属性(properties)

可以通过properties属性实现引用配置文件(db.properties)

  • 在resources目录下编写db.properties文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
  • 在核心配置文件中映入(Mybatis-cofig.xml)

    <!--引入核心配置文件-->
    <properties resource="db.properties">
        <property name="username" values="root"/>
        <property name="pwd" value="111"/>
    </properties>
    
    • 可以直接引入外部文件

    • 可以在其中增加一些属性配置

    • 如果两个文件有同一个字段,优先使用外部配置文件的!!!

5.4、类型别名(typeAliases)

  • 类型别名是为Java类型设置一个短的名字

    <!--可以给实体类起别名-->
    <typeAliases>
        <typeAlias type="com.yang.pojo.User" alias="User"/>
    </typeAliases>
    
  • 扫描实体类的包,默认别名就是这个类的类名,首字母小写!

    <typeAliases>
        <package name="com.yang.pojo"/>
    <typeAliases/>
    
  • 注意:

    实体类较少的时候,使用第一种方式;

    如果实体类十分多,建议使用第二种方式;

    第一种可以DIY别名,第二种不行,除非在实体类上增加注解:

    @alias("user")
    public class User {}
    

5.5、设置

5.6、其他配置

  • plugins插件

    • mybatis-genertor-core(可以根据你自己的代码自动生成mybatis代码)

    • mybatis-plus(可以让你的mybatis代码更简化)

    • 通用mapper

5.7、映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件;

方式一:(推荐)

<!--每一个Mapper.xml都需要在Mybatis核心配置文件注册-->
<mappers>
    <mapper resource="com/yang/dao/UserMapper.xml"/>
<mappers/>

方法二:使用class文件绑定注册

<mappers>
    <mapper class="com.yang.dao.UserMapper"/>
<mappers/>

注意点:

  • 接口和他的Mapper配置文件必须同名

  • 接口和它的Mapper配置文件必须在同一个包下!!!

方法三:使用扫描包进行注册绑定

<mappers>
    <package name="com.yang.dao"/>
<mappers/>

注意点:

  • 接口和他的Mapper配置文件必须同名

  • 接口和它的Mapper配置文件必须在同一个包下!!!

5.8、生命周期和作用域

SqlSessionFactoryBuilder:

  • 局部变量

  • 一旦创建了,就不再需要了

SqlSessionFactory:

  • 可以当成一个 数据库连接池

  • 一旦创建运行期间一直存在,没有理由丢弃

  • 最佳作用域是应用作用域

  • 最简单的就是使用单例模式或者静态单例模式

SqlSession

  • 连接到数据库连接池的一个请求

  • 线程不安全,不被共享,最佳作用域是请求或者方法作用域

  • 用完之后需要赶紧关闭,否则资源被占用

这里的每一个Mapper,就代表一个具体的业务!

6、解决属性名和字段名不一致的问题

数据库表格里的属性命名和代码实体类里面的名字不一致

解决办法:

起别名:as password

<select id="getUserById" resultType="com.yang.pojo.User">
    select id,name,pwd as password from mybatis.user where id=#{id}
<select/>

resultMap(结果集映射)

  • resultMap 元素是Mybatis中最强大的元素

  • 设计思想:简单语句不需要配置显式的结果映射,对于复杂的语句只需要描述他们的关系就行了

UserMapper.xml文件

<!--结果集映射-->
<resultMap id="UserMap" type="User">
    <!--column数据库字段,property实体类属性-->
    <result column="pwd" property="password"/>
<resultMap/>


<select id="getUserById" resultMap="UserMap">
    select * from mybatis.user where id=#{id}
<select/>

7、日志

7.1、日志工厂

如果一个数据库操作,出现了异常,日志就是最好助手。

曾经:sout,debug

现在:日志工厂(logImpl)

  • SLF4J

  • LOG4J(掌握)

  • LOG4J2

  • JDK_LOGGING

  • COMMONS_LOGGING

  • STDOUT_LOGGING(掌握)

  • NO_LOGGING

在mybatis具体使用哪一个日志实现,在设置中设定!

STDOUT_LOGGING标准日志输出(默认的)

在mybatis核心配置文件中,配置我们的日志:

<!--默认标准日志输出-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
            

注意:name注意大小写,一定不要写错;value注意不要出现多余空格之类的;

7.2、Log4j

什么是Log4j?

  • Log4j是一个开源项目,可以通过Log4j控制日志信息输送目的地是控制台、文件、GuI组件

  • 可以控制每一条日志的输出格式

  • 通过定义每一条日志信息的级别,更加细致的控制日志的生成过程

  • 通过一个配置文件来灵活地进行配置,不需要修改应用代码

  1. 导包(在pom.xml文件添加)
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. 创建log4j.properties文件(在resources目录下)

面向百度查询,粘贴

# 设置根日志级别和输出源
log4j.rootLogger=DEBUG, console, file

# 控制台输出配置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# 文件输出配置
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/yang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

# SQL日志配置
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
  1. 配置log4j为日志的实现(在mybatis核心配置文件)
<settings>
        <setting name="logImpl" value="log4j"/>
    </settings>
  1. Log4j的使用

简单使用(UserMapperTest)

  1. 在要使用log4j的类中,导入包 import org.apache.log4j.Logger;

  2. 日志对象,参数为当前的class

```java
static Logger logger = Logger.getLogger(UserMapperTest.class);
```
  1. 日志级别
```java
@Test
    public void Log4jExample() {
        logger.info("info:进入了testLog4j");
        logger.debug("debug:进入了testLog4j");
        logger.error("error:进入了testLog4j");
    }
```

8、分页

为什么分页?

  • 减少数据处理量

使用Limit分页

语法:select * from user limit startIndex,pageSize;
select * from user limit 3; #[0,3]

使用mybatis实现分页,核心是SQL:

  1. 接口
//分页
List<User> getUserByLimit(Map<String,Integer> map);
  1. Mapper.xml
<!--分页-->
<select id = "getUerByLimit" parameterType = "map" resultMap ="UserMap">
    select * from mybatis.user limit #{startIndex},#{pageSize}
<select/>
  1. 测试
@Test
    public void getUserByLimit(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        
        HashMap<String,Integer> map = ner HashMap<String,Integer>();
        map.put("startIndex",1);
        map.put("pageSize",2);

        List<User> userList = mapper.getUserByLimit(map);
        for(User user:userList){
        System.out.println(user);
}
        
        sqlSession.close();
    }

9、使用注解开发

mybatis大部分会使用配置文件,除了mybatis之外的东西都会使用注解开发。

9.1、面向接口编程

解耦

9.2、使用注解开发

  1. 注解在接口上实现
public interface UserMapper {

    @Select("select * from user")
    List<User> getUsers();

}
  1. 需要在核心配置中绑定接口(mybatis核心配置文件)
<!--绑定接口-->
    <mappers>
        <mapper class="com.yang.dao.UserMapper"/>
    </mappers>
  1. 测试
 @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> users = mapper.getUsers();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }

本质:反射机制实现

底层逻辑:动态代理!(面试常考)

Mybatis详细执行流程:

9.3、注解-增删查改(只需要注册接口以及编写接口方法(用注解))

MybatisUtils工具类里面:设置自动提交事务

 //有了sqlSessionFactory,从中获取sqlSession实例。////////加上true,自动提交事务commit().
   public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }

注意:我们必须要将接口注册绑定到我们的核心配置文件!!!

关于@Param()注解:

  • 基本类型的参数或者String类型,需要加上

  • 引用类型不需要

  • sql中引用的就是我们这里的@Param(”id“)中的属性名!!!

  1. 在Mybatis核心配置文件绑定注册接口
<!--绑定接口-->
    <mappers>
        <mapper class="com.yang.dao.UserMapper"/>
    </mappers>

  1. 编写接口
package com.yang.dao;

import com.yang.pojo.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserMapper {

    @Select("select * from user")
    List<User> getUsers();

    //方法存在多个参数,所有参数前面必须加上:@Param(“id”)注解
    @Select("select * from user where id = #{id}")
    User getUserById(int id);
    @Select("select * from user where id = #{id} and name = #{name}")
    User getUserById_Name(@Param("id") int id,@Param("name") String name);

    @Insert("insert into user(id,name,pwd) value (#{id},#{name},#{pwd})")
    int InsertUser(User user);

    @Delete("delete from user where id = #{id}")
    int DeleteUser(@Param("id") int id);

    @Update("update user set name = #{name} ,pwd = #{pwd} where id = #{id}")
    int UpdateUser(User user);


}


  1. 测试
  @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询所有用户
//        List<User> users = mapper.getUsers();
//        for (User user : users) {
//            System.out.println(user);
//        }

        //根据id查询用户信息
//        User userById = mapper.getUserById(1);
//        System.out.println(userById);
//          User userById_Name = mapper.getUserById_Name(4,"shshi");
//          System.out.println(userById_Name);

          //增加用户
//        mapper.InsertUser(new User(6,"dili","123456"));

        //删除用户
//        mapper.DeleteUser(6);

        //更改用户信息
        mapper.UpdateUser(new User(5,"yangshi","123456"));


        sqlSession.close();
    }

10、Lombok

是什么?

简化java代码的一个插件,看情况吧,不建议使用

使用步骤:

  1. 在IEDA中安装Lombok插件

  2. 在项目中,pom.xml导入lombok的jar包

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
  1. 直接在实体类加上注解即可
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;

}

@Data: 无参构造,get,set,tostring,hashcode,equals

@AllArgsConstructor:有参构造

@NoArgsConstructor:无参构造

@EqualsAndHashCode

@ToString

@Getter

11、多对一处理

多个学生,对应一个老师

  • 对于学生而言,关联,多个学生关联一个老师

  • 对于老师而言,集合,一个老师有很多学生

创建数据库环境:

CREATE TABLE `teacher`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY(`id`))
ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`,`name`) VALUES (1,"秦老师");

CREATE TABLE `student`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `fktid`(`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`))
ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('1','小明','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('2','小红','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('3','小张','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('4','小李','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('5','小王','1');

测试环境搭建:

(Mybatis-study2目录下的mybatis-04项目)

  1. 新建实体类

  2. 建立Mapper接口

  3. 建立Mapper.xml文件

  4. 在核心配置文件中绑定我们的Mapper接口或者文件!!(方式有很多)

  5. 测试查询是否成功

按照查询嵌套处理:

  • 先写StudentMapper接口

    public interface StudentMapper {
    
        //查询所有学生信息,以及对应老师的信息
        public List<Student> getStudent();
    }
    
    
  • 编写StudentMapper.xml文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org/DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.yang.dao.StudentMapper">
    
        <!--1.查询学生信息
            2.根据查询出来的tid,查询相应老师信息-->
        <select id="getStudent" resultMap="StudentTeacher">
            select * from student
        </select>
    
        <resultMap id="StudentTeacher" type="Student">
            <result property="id" column="id"/>
            <!--复杂的属性,需要单独处理,对象用association ;集合用collection; -->
            <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
        </resultMap>
    
        <select id="getTeacher" resultType="Teacher">
            select * from teacher where id = #{id}
        </select>
    
    </mapper>
    
  • 测试

     @Test
        public void testStudent(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    
            List<Student>  studentList = studentMapper.getStudent();
            for (Student student : studentList) {
                System.out.println(student);
            }
        }
    

按照结果嵌套处理

<!--按照结果嵌套查询-->
    <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid, s.name sname, t.name tname
        from student s,teacher t
        where s.tid = t.id;
    </select>
    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

12、一对多处理

一个老师拥有多个学生

对于老师而言,就是一对多的关系!

也有两种方法,和多对一 一样,下面我只写了一种

环境搭建

  • 实体类

    @Data
    public class Teacher {
        private int id;
        private String name;
        //一个老师拥有很多学生  一个学生集合
        private List<Student> students;
    }
    
@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}

  • 接口

    public interface TeacherMapper {
    
        //获取指定老师下所有学生以及老师的信息
        Teacher getTeacher(@Param("tid") int id);
    
    }
    
    
  • Mapper.xml(对象:association;集合:collection; javaType--指定属性类型;集合中泛型信息,我们用ofType获取)

     <!--按照结果查询-->
        <select id="getTeacher" resultMap="TeacherStudent">
            select t.id tid, t.name tname, s.id sid, s.name sname,s.tid stid
            from teacher t,student s
            where t.id = s.tid;
        </select>
        <resultMap id="TeacherStudent" type="Teacher">
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
            <collection property="students" ofType="Student">
                <result property="id" column="sid"/>
                <result property="name" column="sname"/>
                <result property="tid" column="stid"/>
            </collection>
        </resultMap>
    
  • 测试

     @Test
        public void test(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = teacherMapper.getTeacher(1);
            System.out.println(teacher);
            sqlSession.close();
        }
    

注意点:

  • 保证sql的可读性

  • 注意一对多和多对一中,属性名和字段的问题

  • 如果问题不好排查,可以使用Log4j

13、动态sql

什么是动态sql?

动态sql就是根据不同的条件生成不同的Sql语句

总结:拼接SQL语句,确保SQL语句正确性,按照SQL格式去排列组合即可。建议先写出完整SQL语句再去对应修改动态sql实现通用!

动态sql本质还是sql语句,if/ where/ set/ choose/ when/

搭建环境

(mybatis-study2目录下mybatis-06目录)

数据库环境

CREATE TABLE `blog` (
    `id` VARCHAR(50) NOT NULL COMMENT '博客id',
    `title` VARCHAR(100) NOT NULL COMMENT '博客标题',
    `author` VARCHAR(30) NOT NULL COMMENT '博客作者',
    `create_time` DATETIME NOT NULL COMMENT '创作时间',
    `views` INT(30) NOT NULL COMMENT '浏览量'
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `blog` (`id`, `title`, `author`, `create_time`, `views`) VALUES 
('1', 'mysql', '小明', '2025-01-01 00:00:00', 1000),
('2', 'maven', '小李', '2025-01-02 00:00:00', 1500),
('3', 'mybatis', '小丽', '2025-01-03 00:00:00', 2000),
('4', 'ieda中使用maven', '小云', '2025-01-04 00:00:00', 800),
('5', 'mysql动态', '小红', '2025-01-05 00:00:00', 1200);

创建一个基础工程:

  1. 导包

  2. 编写配置文件

核心配置文件添加:


<mappers>
        <mapper resource="com/yang/dao/BlogMapper.xml"/>
    </mappers>


<!--是否开启自动命名规则映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

  1. 编写实体类
@Data
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

  1. 编写实体类对应Mapper接口和Mapper.xml文件

  2. 工具类,IDUtils(随机生成id)

public class IDUtils {
    public static String getId(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }

    @Test
    public void test(){
        System.out.println(IDUtils.getId());
        System.out.println(IDUtils.getId());
        System.out.println(IDUtils.getId());
    }


}

IF

环境搭建好,只需要编写Mapper接口以及Mapper.xml文件和测试代码即可

  1. BlogMapper接口
//查询博客
    List<Blog> queryBlogIF(Map map);
  1. BlogMapper.xml
    <select id="queryBlogIF" resultType="Blog" parameterType="map">
        select * from mybatis.blog
        <where>
            <if test="title != null">
                title = #{title}
            </if>
            <if test="author != null">
                and author = #{author}
            </if>
        </where>
    </select>
<!--1.输入title查询该title全部信息
        2.输入author查询该author全部信息
        3.什么都不输入则查询全部博客信息-->
    <select id="queryBlogIF" resultType="Blog" parameterType="map">
        select * from mybatis.blog where 1 = 1
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>

  </select>
  1. MyTest
    @Test
    public void queryBlogIFTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        HashMap hashMap = new HashMap();
//        hashMap.put("title","mysql");
//        hashMap.put("author","小明");
        List<Blog> blogs = blogMapper.queryBlogIF(hashMap);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

choose,when,otherwise

  1. 接口
//查询博客
    List<Blog> queryBlogChoose(Map map);
  1. Mapper.xml
<select id="queryBlogChoose" resultType="Blog" parameterType="map">
        select * from mybatis.blog
        <where>
            <choose>
                <when test="title != null">
                    title = #{title}
                </when>
                <when test="author != null">
                    and author = #{author}
                </when>
                <otherwise>
                    views = #{views}
                </otherwise>
            </choose>
        </where>
    </select>
  1. Test
    @Test
    public void queryBlogChooseTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        HashMap hashMap1 = new HashMap();
//        hashMap1.put("title","mysql");
        hashMap1.put("author","小明");
        hashMap1.put("views",2000);
        List<Blog> blogs = blogMapper.queryBlogChoose(hashMap1);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

Set

 <select id="UpdateBlog" parameterType="map">
        update mybatis.blog
        <set>
            <if test="title != null">
                title = #{title},
            </if>
            <if test="author != null">
                author = #{author}
            </if>
        </set>
        where id = #{id}
    </select>

foreach

<!--通过foreach,传递一个万能的Map,这个Map可以存在一个集合-->
    <!--foreach:集合名,集合里面的每一个项名,开始,结束,分隔符-->
    <select id="queryBlogForeach" parameterType="map" resultType="Blog">
        select * from mybatis.blog
        <where>
            <foreach collection="ids" item="id" open="(" close=")" separator="or">
                id = #{id}
            </foreach>
        </where>
    </select>
   @Test
    public void queryBlogForeach(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        HashMap hashMap3 = new HashMap();

        ArrayList<Integer> ids = new ArrayList<Integer>();

        hashMap3.put("ids",ids);
        ids.add(1);
        ids.add(2);

        List<Blog> blogs = blogMapper.queryBlogForeach(hashMap3);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }
//查询第1-5号记录的博客
    List<Blog> queryBlogForeach(Map map);

SQL片段

有时候,可能把一些功能的部分提取出来,方便复用!(提取SQL公共部分,在需要地方引用include标签

    <sql id="if_title_author">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>


    <!--1.输入title查询该title全部信息
        2.输入author查询该author全部信息
        3.什么都不输入则查询全部博客信息-->
    <select id="queryBlogIF" resultType="Blog" parameterType="map">
        select * from mybatis.blog
        <where>
            <include refid="if_title_author"></include>
        </where>
    </select>

注意事项:

最好基于单表来定义SQL片段,不要存在where标签

14、缓存

14.1、简介

查询:连接数据库,耗资源

一次查询的结果,给他缓存在一个可以直接提取的地方,---》内存/ 缓存

我们再次查询相同数据的时候,直接走缓存,不用走数据库了。(解决高并发系统问题)

posted @ 2025-04-17 16:12  蟹堡博  阅读(17)  评论(0)    收藏  举报