mybatis上手

发布于:2025-07-22 ⋅ 阅读:(19) ⋅ 点赞:(0)

要学的内容

1.mybatis-CRUD 2.MyBatis配置文件 3.结果集映射 (重点难点) 4.分页 5.使用注解开发 (重点) 6.一对多、多对一的处理 (难点) 7.动态SQL (重点) 8.缓存 (十分重要,极其重要) 9.MyBatis- Plus 10.Log4j 11.通用Mapper

以后学任何思路:配环境——导入框架(mybatis)——编写代码——测试

这次学练习没多少,都是跟着视频来的,重复的不多,会容易遗忘。

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

mybatis用来用去还是,设置接口userMapper.java,配置文件userMapper.xml,测试

持久化和持久层

持久化:数据持久化,持久化就是将程序的数据在持久状态和瞬时状态转化的过程 ·内存:断电即失 ·数据库(Jdbc),io文件持久化。

**为什么需要需要持久化?**有一些对象,不能让他丢掉。内存太贵了

持久层:Dao层 , Service层, Controller层..是完成持久化工作的代码块,层界限十分明显。

为什么用Mybatis

1.帮助程序猿将数据存入到数据库中。 2.方便 3.传统的JDBC代码太复杂了。简化。框架。自动化。 4.不用Mybatis也可以。更容易上手。技术没有高低之分

优点: 。 简单易学 。 灵活 。 sql和代码的分离,提高了可维护性。 。提供映射标签,支持对象与数据库的orm字段关系映射 。提供对象关系映射标签,支持对象关系组建维护 。 提供xml标签,支持编写动态sql。

最重要的一点:使用的人多!

1.配置环境

src
└── main
    ├── java
    │   └── com.littlespark
    │       ├── myMapper
    │       │   ├── userMapper
    │       │   └── userMapper.xml
    │       ├── pojo
    │       │   └── User
    │       └── utils
    │           └── myUtils
    ├── resources
    │   └── mybatis-config.xml
    └── webapp
└── test
    └── java
        └── com.littlesaprk.mapper
            └── userMapperTest

八个东西:

com/littlespark/myMapper/userMapper.java;com/littlespark/myMapper/userMapper.xml ;com/littlespark/pojo/User.java;com/littlespark/utils/myUtils.java ;

mybatis-config.xml;userMapperTest.java

Utils方法类

pom.xml

创建数据库

CREATE DATABASE `mybatis`;

use `mybatis`;

CREATE TABLE `user`(
  `id` INT(20) not null PRIMARY KEY,
  `name` VARCHAR(30) DEFAULT NULL,
  `pwd` VARCHAR(20) DEFAULT NULL
)ENGINE=innodb DEFAULT CHARSET=utf8;

INSERT into `user`(`id`,`name`,`pwd`) VALUES
(1,'kobe','123123'),
(2,'durant','123123'),
(3,'lebron','123123');

pom.xml因为下载的MYSQL服务器是8.0+,所以这里的配置也要到8.0之后的。

<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/maven-v4_0_0.xsd>">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.littlespark</groupId>
        <artifactId>first</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>son</artifactId>
    <packaging>war</packaging>
    <name>son Maven Webapp</name>
    <url><http://maven.apache.org></url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
<!--            <scope>java</scope>-->
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>**8.0.24**</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>son</finalName>
             <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
				<!--
				若 <filtering>true</filtering>,Maven 会替换资源文件中的 ${},
				可能导致 db.properties 中的 ${driver} 被错误替换。
				-->
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
    </build>

</project>

mybatis-config.xml 因为MYSQL是8.0所以driver要改为com.mysql.cj.jdbc.Driver

<?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="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;allowPublicKeyRetrieval=true" />
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
<!--    每一个mapper.xml都需要再mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/littlespark/myMapper/userMapper.xml"/>
    </mappers>
</configuration>

userMapper.xml

namespace="com.littlespark.myMapper.userMapper是为了联系接口userMapper,userMapper接口的方法名getUserList(),

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
    <select id="getUserList" resultType="com.littlespark.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

userMapper 接口

package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import java.util.List;

public interface userMapper {
    List<User> getUserList();
}

User实体类

package com.littlespark.pojo;

public class User {
    private int id;
    private String name;
    private int pwd;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPwd() {
        return pwd;
    }

    public void setPwd(int pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\\'' +
                ", pwd=" + pwd +
                '}';
    }
}

Utils方法类

package com.littlespark.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;

public class myUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            // 第一步,获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 有了SqlSessionFactory 就可以获得SqlSession的实例
    // SqlSession 完全包含了面向数据可执行的SQL命令的所有方法
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

2.CRUD

namespace="com.littlespark.myMapper.userMapper"

namespace的包名要和接口的包名一致。

之前配置的内容,变得不多,变四处,还真的服一直报错,重启就又好了

Process finished with exit code 1
Class not found: "com.littlesaprk.mapper.userMapperTest"

userMapper.java;userMapper.xml;userMapperTest.java

userMapper.java 接口添加 User getUserById(int id);

package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import java.util.List;

public interface userMapper {
    List<User> getUserList();

    User getUserById(int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(int id);
}

userMapper.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
    <select id="getUserList" resultType="com.littlespark.pojo.User">
        select * from mybatis.user
    </select>
    
    <select id="getUserById" resultType="com.littlespark.pojo.User" parameterType="int">
        select * from mybatis.user where id = #{id}
    </select>

    <insert id="addUser" parameterType="com.littlespark.pojo.User" >
        insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd});
    </insert>

    <update id="updateUser" parameterType="com.littlespark.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.java

package com.littlesaprk.mapper;
import com.littlespark.myMapper.userMapper;
import com.littlespark.pojo.User;
import com.littlespark.utils.myUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class userMapperTest   {
   @Test
   public void test() {
       SqlSession sqlSession = myUtils.getSqlSession();// 获取sqlSession对象
       userMapper mapper = sqlSession.getMapper(userMapper.class);
       for (User user : mapper.getUserList()) {
           System.out.println(user);
       }
       sqlSession.close();
   }

   @Test
   public void getUserById(){
       SqlSession sqlSession = myUtils.getSqlSession();
       userMapper mapper = sqlSession.getMapper(userMapper.class);

       User user = mapper.getUserById(4);

       sqlSession.close();
   }

   @Test
   public void addUser(){
       SqlSession sqlSession = myUtils.getSqlSession();
       userMapper mapper = sqlSession.getMapper(userMapper.class);

       mapper.addUser(new User(4,"lll","1231231"));

       sqlSession.commit();
       sqlSession.close();
   }
    @Test
    public void updateUser(){
        SqlSession sqlSession = myUtils.getSqlSession();
        userMapper mapper = sqlSession.getMapper(userMapper.class);

        mapper.updateUser(new User(4,"lll","123112312331"));
        
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = myUtils.getSqlSession();
        userMapper mapper = sqlSession.getMapper(userMapper.class);

        mapper.deleteUser(4);

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

}

3.万能的map

因为userMapper.xml也需要写很多的sql语句,每一条对应一个函数,也很多,优化方案就是这个map。

当实体类或数据库表,字段的参数过度,就可以用map。因为如果不用,那就要把所有的参数都列出来,但是有了这个map修改啥就可以列啥。

动四个地方:userMapper.java;userMapper.xml;userMapperTest.java;userMapper.java

package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import java.util.List;

public interface userMapper {
      int addUser2(Map map);
}

userMapper.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
<!-- 这里的values的数据就直接可以变,不需要跟User实体类对应,而且只插入一部分也行-->
    <insert id="addUser2" parameterType="map" >
        insert into mybatis.user(id,name) values(#{adsadasd},#{namesdsadad});
    </insert>
</mapper>

userMapperTest.java

package com.littlesaprk.mapper;
import com.littlespark.myMapper.userMapper;
import com.littlespark.pojo.User;
import com.littlespark.utils.myUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class userMapperTest   {
   @Test
	 public void addUser2(){
       SqlSession sqlSession = myUtils.getSqlSession();
       userMapper mapper = sqlSession.getMapper(userMapper.class);

       Map<String, Object> map = new HashMap<String, Object>();
       // 只为了说明,有了map,不需要对应User属性名字也行
       map.put("adsadasd",1111);
       map.put("namesdsadad","lll");
       mapper.addUser2(map);

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

4.配置解析

My Batis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 configuration (配置) properties (属性) settings (设置) typeAliases (类型别名) typeHandlers (类型处理器) objectFactory (对象工厂) plugins (插件) environments (环境配置) environment ( 环境变量) transactionManager (事务管理器) dataSource (数据源) databaseIdProvider (数据库厂商标识) mappers(映射器)

db.properties配mybatis-config.xml

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
<?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>
    <!--引入配置文件写最上面    -->
    <properties resource="db.properties"/>

    <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>
<!--    每一个mapper.xml都需要再mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/littlespark/myMapper/userMapper.xml"/>
    </mappers>
</configuration>

pom.xml有一个问题。若 <filtering>true</filtering>,Maven 会替换资源文件中的 ${},可能导致 db.properties 中的 ${driver} 被错误替换。所以**/*.properties的过滤器改为 <filtering>false</filtering>

<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/maven-v4_0_0.xsd>">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.littlespark</groupId>
        <artifactId>first</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>son</artifactId>
    <packaging>war</packaging>
    <name>son Maven Webapp</name>
    <url><http://maven.apache.org></url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!--            <scope>java</scope>-->
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.24</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>

    </dependencies>

  <build>
    <finalName>son</finalName>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
<!--
若 <filtering>true</filtering>,Maven 会替换资源文件中的 ${},
可能导致 db.properties 中的 ${driver} 被错误替换。
-->
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

</project>

5.类型别名

在mybatis-config.xml注册别名,然后在userMapper.xml就可以在parameterType直接用这个别名就不需要把完成的包名写出来了。

**<typeAliases>
    <typeAlias type="com.littlespark.pojo.User" alias="User"/>
</typeAliases>**

pom.xml有一个问题。这个<filtering>true</filtering>有很多问题,直接注释掉就好了

两个地方:mybatis-config.xml,userMapper.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>
    <!--引入配置文件写最上面    -->
    <properties resource="db.properties"/>

    **<typeAliases>
        <typeAlias type="com.littlespark.pojo.User" alias="User"/>
    </typeAliases>**

    <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>
<!--    每一个mapper.xml都需要再mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/littlespark/myMapper/userMapper.xml"/>
    </mappers>
</configuration>

userMapper.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.userMapper">
    <select id="getUserList" resultType="**User**">
        select * from mybatis.user
    </select>
</mapper>

第二种配置的方法,在mybatis-config.xml配置换成这个就行了,其他不变

    <typeAliases>
      <package name="com.littlespark.pojo"/>
    </typeAliases>

在实体类比较少的时候,使用第一种方式。因为一条对应一个实体类。

如果实体类十分多,建议使用第二种。一下子对应一个包里的所有实体类。

第一种可以DIY别名,第二种则不行,如果非要改,需要在实体上增加注解

也就是在pojo/User.java这个实体类最上面添上注解@Alias(”dddd”),这样userMapper.xml的resultType也就可以根据这个注解@Alias(”dddd”)写成,resultType=“dddd”,实现了自定义别名的功能。

6.不太理解 SqlSessionBuilder SqlSessionFactory SqlSession之前的区别。

9、生命周期和作用域_哔哩哔哩_bilibili

7.日志

SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING

很简单,添加一句话,注意在mybatis-config.xml的位置

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
<?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>
    <!--引入配置文件写最上面    -->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
      <package name="com.littlespark.pojo"/>
    </typeAliases>

    <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>
<!--    每一个mapper.xml都需要再mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/littlespark/myMapper/userMapper.xml"/>
    </mappers>
</configuration>

如果用log4j的话,两个地方,pom.xml要导包,mybatis-config.xml配置为setting

<settings>
    <setting name="logImpl" value="log4j"/>
</settings>

pom.xml的dependence导一个log4j的包

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>

8.注解

为什么都需要写一个接口,然后再来实现这个接口?就是为了解耦。

练习注解,这时候就不需要userMapper.xml了。

注意原本的是/ 现在变**.**

在这里还有个问题,如果userMapper.xml没有被删除,但是mybatis-config.xml只有class的mapper就会出问题,就算把userMapper.xml注释掉,也不行。

src
└── main
    ├── java
    │   └── com.littlespark
    │       ├── myMapper
    │       │   ├── userMapper
    │       │   └── userMapper.xml
    │       ├── pojo
    │       │   └── User
    │       └── utils
    │           └── myUtils
    ├── resources
    │   └── mybatis-config.xml
    └── webapp
└── test
    └── java
        └── com.littlesaprk.mapper
            └── userMapperTest

修改两个东西:mybatis-config.xml,userMapper.java接口

mybatis-config.xml要由原本的 <mapper resource="com/littlespark/myMapper/userMapper.xml"/>改为<mapper class="com.littlespark.myMapper.userMapper"/>

<?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>
    <!--引入配置文件写最上面    -->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
      <package name="com.littlespark.pojo"/>
    </typeAliases>

    <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 class="com.littlespark.myMapper.userMapper"/>
    </mappers>
</configuration>

userMapper.java接口

package com.littlespark.myMapper;
import com.littlespark.pojo.User;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

public interface userMapper {

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

    @Select("select * from user where id=${idiiiiiiiii}")
    User getUserById(@Param("idiiiiiiiii") int id);

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

    int addUser2(Map<String,Object> map);

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

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

其他不需要变,测试类直接测试就可以了

Lombok偷懒神器

可用可不用,没啥东西

多对一

src
└── main
    ├── java
    │   └── com.littlespark
    │       ├── myMapper
    │       │   ├── studentMapper
    │       │   └── teacherMapper
    │       ├── pojo
    │       │   ├── Student
    │       │   └── Teacher
    │       └── utils
    │           └── myUtils
    ├── resources
    │   ├── com.littlespark.myMapper
    │   │   ├── studentMapper.xml
    │   │   └── teacherMapper.xml
    │   ├── db.properties
    │   └── mybatis-config.xml
    └── webapp
└── test
    └── java
        └── com.littlesaprk.mapper
            ├── studentMapperTest
            └── teacherMapperTest

要实现这个功能:

select s.id ,s.name,t.name from student s,teacher t where s.tid=t.id;

根据student的外键tid找到老师的id

修改九个地方:mybatis-config.xml,studentMapper.java,Student.java,studentMapper.xml,teacherMapper.java,Teacher.java, teacherMapper.xml,studentMapperTest.java,teacherMapperTest.java

**create table teacher(
    `id` int(20) not null primary key ,
    `name` varchar(30) default null
);

insert into teacher(`id`,`name`) values
(1,'hh'),(2,'kobe');

create table student(
    `id` int(20) 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`)
);

insert into student(`id`,`name`,`tid`) values
(1,'ivring','1'),(2,'nay','2'),(3,'yao','2'),(4,'wang','2');**

mybatis-config.xml就这两句话

<mapper resource="com/littlespark/myMapper/teacherMapper.xml"/> <mapper resource="com/littlespark/myMapper/studentMapper.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>
    <!--引入配置文件写最上面    -->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
      <package name="com.littlespark.pojo"/>
    </typeAliases>

    <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="com/littlespark/myMapper/teacherMapper.xml"/>
        <mapper resource="com/littlespark/myMapper/studentMapper.xml"/>
    </mappers>
</configuration>

studentMapper.java,Student.java,studentMapper.xml 写一个就行了很像

teacherMapper.java,Teacher.java, teacherMapper.xml

package com.littlespark.myMapper;

import com.littlespark.pojo.Student;
import java.util.List;

public interface studentMapper {
    List<Student> getStudentList();
}

无参构造必须有

package com.littlespark.pojo;

public class Student {
    private int id;
    private String name;
    private Teacher teacher;

    public Student(){}

    public Student(int id, String name, Teacher teacher) {
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\\'' +
                ", teacher=" + teacher +
                '}';
    }
}

*****studentMapper.xml,因为要根据student表里的tid找到teacher表里的name,但在studentMapper.xml里一次只能查一个表。就用到了这三条语句,最上面最下面都是简单的查student,teacher表的语句。

查getStudentList的时候,返回值是resultMap="studentTeacher",而这个studentTeacher就注册为中间的地方resultMap。

property是数据库里的字段名,column是实体类的字段名。而result只能针对单个属性,复杂的属性就只能用association(对象)或collection (集合),这里返回的是一个单个对象所以association

association 里也有property对应的是student实例的第三个字段也就是Teacher,学生表第三个内容是tid 。返回的内容因为是复杂的类型,这里写javaType="Teacher" 。

如何得到tid对应的teacher呢?就是通过嵌套查询select="getTeacherList",对应的就是第三个语句的<select id="getTeacherList" resultType="Teacher">,通过这个查询得到的teacher数据。

有个疑问:这里的是studentMapper.xml如何能找到com.littlespark.myMapper.teacherMapper的方法?

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
    <select id="getStudentList" resultMap="studentTeacher">
        select * from mybatis.student
    </select>
    
    <resultMap id="studentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacherList"/>
    </resultMap>
    
    <select id="getTeacherList" resultType="Teacher">
        select * from mybatis.teacher where id = #{id}
    </select>
</mapper>

上面的方法是按照查询嵌套,下面的第二种方法是按照结果嵌套

动两个东西:studentMapper.java studentMapper.xml

package com.littlespark.myMapper;

import com.littlespark.pojo.Student;
import java.util.List;

public interface studentMapper {
    List<Student> getStudentList();
}
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
    <select id="getStudentList2" 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="id"/>
        <result property="name" column="name"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>
</mapper>

一对多

根据一个老师的tid找到对应的学生有哪些?(感觉跟多对一很像,也不太一样)

动四个东西:teacherMapper.java,teacherMapper.xml,Teacher.java,Student.java

package com.littlespark.myMapper;

import com.littlespark.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import java.util.List;

public interface teacherMapper {
    Teacher getTeacherById(@Param("teacherMapperParam") int id);
}

Teacher.java 和Student.java写在一块了,可以看看对比一下

package com.littlespark.pojo;

import java.util.List;

public class Teacher {
    private int id;
    private String name;
    private List<Student> students;

}

package com.littlespark.pojo;

public class Student {
    private int id;
    private String name;
    private int studentPojoTeacherId;

}

teacherMapper.xml,写的很详细了。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
    <select id="getTeacherById" resultMap="TeacherSelectHowManyStudents">
        select s.id sid, s.name sname,t.name tname,t.id tid
        from student s,teacher t
        where s.tid=t.id and t.id=#{teacherMapperParam}
    </select>
    <resultMap id="TeacherSelectHowManyStudents" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!--
        1.因为这次返回的是List<Student>是集合,所以用collection
        之前返回的是Teacher 是对象 所以用的是association
        2.上面俩属性是返回的是teacher的名字,为啥column是tid?因为查询的语句改名字了
        3.这个collection是对应的集合,自然property属性就是Student的属性。
        第一个property根据的是teacher里的 private List<Student> students;
        4.javaType指定属性的类型,集合当中泛型信息List<>都是用ofType
        -->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="studentPojoTeacherId" column="tid"/>
        </collection>
    </resultMap>
</mapper>

动态SQL

可以实现SQL的复用,本质上还是Sql的语句.

什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句

利用动态SQL这一特性可以彻底摆脱这种痛苦。动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。 MyBatis大大精简了元素种类,现在只需学习原来一半的元素便可。 MyBatis 采用功能强大的基于 OGNL的表达式来淘汰其它大部分元素。 if choose (when, otherwise) trim (where, set) I foreach

if

三个地方:studentMapper.java,studentMapper.xml,studentMapperTest.java

studentMapper.java,这里传递的Map map,就是对应的id ,name

package com.littlespark.myMapper;

import com.littlespark.pojo.Student;

import java.util.List;
import java.util.Map;

public interface studentMapper {
    List<Student> getStudentList3(Map map);
}

studentMapper.xml,语法就是IF

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
  <select id="getStudentList3" parameterType="map" resultType="Student">
	    select * from student where 1=1
  <if test="id != null">
      and id = #{id}
  </if>
  <if test="name != null">
      and name = #{name}
  </if>
	</select>
</mapper>

studentMapperTest.java,hashMap.put("id", "1");如果注释掉这句话,那么就是查全部,也就是两个if语句都失效,那就是where 1=1 全查,这里的id也就是传进去的#{id},要变都同时变。

变三处

hashMap.put("idddd ", "1");

<if test="idddd != null">

and id = #{idddd}</if>

public class studentMapperTest {
    @Test
    public void testStudentMapper() {
        SqlSession sqlSession = myUtils.getSqlSession();
        studentMapper mapper = sqlSession.getMapper(studentMapper.class);
        HashMap hashMap = new HashMap<>();
        hashMap.put("id", "1");
        for(Student student:mapper.getStudentList3(hashMap)){
            System.out.println(student);
        }
        sqlSession.commit();
        sqlSession.close();
    }
}

choose(when ,otherwise)

只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

<select id="getStudentList3" parameterType="map" resultType="Student">
    select * from student
    <where>
        <choose>
            <when test="idddd != null">
                id = #{idddd}
            </when>
             <when test="name != null">
                 and name = #{name}
             </when>
             <otherwise>
                 and id = 1
             </otherwise>
        </choose>
    </where>
</select>

where保证当 and在开始的时候,会自动去掉,choose就是switch选择,otherwise就是如果前两个都没匹配上就默认查最后这句话。

trim(where,set)

<select id="getStudentList3" parameterType="map" resultType="Student">
	    select * from student where
  <if test="id != null">
      id = #{id}
  </if>
  <if test="name != null">
      and name = #{name}
  </if>
</select>

这里有个问题,如果只是配test="name != null" 这个if,上面test="id != null"没有匹配成功,那么翻译过来的sql语句就是 select * from student where and name = #{name};

这个是错误的,所以where就起作用了

<select id="getStudentList3" parameterType="map" resultType="Student">
	    select * from student 
	<where>
	  <if test="id != null">
	      id = #{id}
	  </if>
	  <if test="name != null">
	      and name = #{name}
	  </if>
	</where>
</select>

如果只匹配第二句这种and或or开头的,会自动消除and 或者or

翻译过来的sql语句就是 select * from student where name = #{name};

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号

原本更新语句

    <update id="updateStudent" parameterType="map">
        update  student set name = #{name} where id = #{idddd}
    </update>

使用set之后

<update id="updateStudent" parameterType="map">
    update  student
    <set>
        <if test="idddd != null" >id = #{idddd},</if>
        <if test="name != null"  >name = #{name}</if>
    </set>
    where tid = #{tid}
</update>

对应

public class studentMapperTest {
    @Test
    public void testStudentMapper() {
        SqlSession sqlSession = myUtils.getSqlSession();
        studentMapper mapper = sqlSession.getMapper(studentMapper.class);
        HashMap hashMap = new HashMap<>();
        hashMap.put("idddd", "1010");
        hashMap.put("name", "crazy");
        hashMap.put("tid", "1");
        mapper.updateStudent(hashMap);
        
        sqlSession.commit();
        sqlSession.close();
    }
}

foreach

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach

当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。

当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。 open="(" separator="," close=")" 这句话的意思 是把 collection="list"集合里的元素提取出来,按照

( , , , , , )的格式获取,每个,之间的内容就是list的数据

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach collection="list" item="item" index="index"  open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

举个例子:select * from student where 1=1 and( id=1 or id=2 or id=3)

动三个地方:studentMapper.java,studentMapper.xml,studentMapperTest.java

studentMapper.xml

parameterType="map" 传递进来的是Map map

resultType="student" 要返回的数值类型是Student

collection="integers" 对应的是前面传递的map的K V里的V(values值)。

item="idssss" 取每一个values值的别名idssss

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.littlespark.myMapper.studentMapper">
	<select id="selectByIds" parameterType="map" resultType="student">
	    select * from student
	    <where>
	        1=1 
	        <foreach collection="integers" item="idssss" open="and(" close=")" separator="or">
	            id = #{idssss}
	        </foreach>
	    </where>
	</select>
</mapper>

studentMapperTest.java

public class studentMapperTest {
    @Test
    public void testStudentMapper() {
        SqlSession sqlSession = myUtils.getSqlSession();
        studentMapper mapper = sqlSession.getMapper(studentMapper.class);
        HashMap hashMap = new HashMap<>();
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        hashMap.put("integers", integers);

        for(Student student:mapper.selectByIds(hashMap)){
            System.out.println(student);
        }
        sqlSession.commit();
        sqlSession.close();
    }
}

studentMapper.java

package com.littlespark.myMapper;

import com.littlespark.pojo.Student;

import java.util.List;
import java.util.Map;

public interface studentMapper {
    List<Student> selectByIds(Map map);
}

动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了 建议:在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!

缓存

查询,连接数据库 ,耗资源! 一次查询的结果,给他暂存在一个可以直接取到的地方!--> 内存 : 缓存 我们再次查询相同数据的时候,直接走缓存,就不用走数据库了

为什么使用缓存?减少和数据库的交互次数,减少系统开销,提高系统效率。

什么样的数据能使用缓存?经常查询并且不经常改变的数据。【可以使用缓存】

MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下,只有一级缓存开启。(SqISession级别的缓存,也称为本地缓存) 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。(也就是写的那么多次的mapper配置) 为了提高扩展性, MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

第一次查询是存放在一级缓存里,当SqlSession关闭的时候,会把以及缓存的数据放到Mapper的二级缓存里,当新的查询又来的时候,会先从二级缓存里找,找不到再去一级缓存里????再找不到再去数据库找

是这样吗?


网站公告

今日签到

点亮在社区的每一天
去签到