Mybatis笔记

ctrl + alt + T 是try,catch的快捷键

alt+insert 快捷键

alt+enter

搭建MyBatis框架

6 开发环境和准备工作

IDE:idea 2019.2

构建工具:maven 3.5.4

MySQL版本:MySQL 8

MyBatis版本:MyBatis 3.5.7

MySQL不同版本的注意事项

1、驱动类driver-class-name

MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver

MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver

2、连接地址url

MySQL 5版本的url: jdbc:mysql://localhost:3306/ssm

MySQL 8版本的url: jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC

否则运行测试用例报告如下错误: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more

导入依赖

<dependencies>
        <!-- Mybatis核心 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
    </dependencies>

实体类创建

快捷键alt+insert

有参构造,无参构造,tostring

package com.mybatis.pojo;
​
public class User {
    private Integer id;
​
    private String username;
​
    private  String password;
​
    private  Integer age;
​
    private  String gender;
​
    private String email;
​
    public User(Integer id, String username, String password, Integer age, String gender, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
        this.gender = gender;
        this.email = email;
    }
​
    public Integer getId() {
        return id;
    }
​
    public User setId(Integer id) {
        this.id = id;
        return this;
    }
​
    public String getUsername() {
        return username;
    }
​
    public User setUsername(String username) {
        this.username = username;
        return this;
    }
​
    public String getPassword() {
        return password;
    }
​
    public User setPassword(String password) {
        this.password = password;
        return this;
    }
​
    public Integer getAge() {
        return age;
    }
​
    public User setAge(Integer age) {
        this.age = age;
        return this;
    }
​
    public String getGender() {
        return gender;
    }
​
    public User setGender(String gender) {
        this.gender = gender;
        return this;
    }
​
    public String getEmail() {
        return email;
    }
​
    public User setEmail(String email) {
        this.email = email;
        return this;
    }
​
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
​

7 创建MyBatis核心配置文件

核心配置文件

<?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/ssm?
serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <package name="mappers/UserMapper.xml"/>
    </mappers>
</configuration>
​

8 创建Mapper接口和映射文件

Usermapper.java

package com.mybatis.mapper;
​
public interface UserMapper {
​
    int insertUser();
​
}

usermapper.xml

<mapper namespace="com.mybatis.mapper.UserMapper">是上面的全类名

<?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="com.mybatis.mapper.UserMapper">
    <!--int insertUser();-->
    <insert id="insertUser">
        insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
    </insert>
</mapper>
​

mybatis-config.xml

 <!--引入映射文件-->
    <mappers>
        <package name="mappers/UserMapper.xml"/>
    </mappers>

两个一致

mapper接口的全类名和映射文件的namespace一致

mapper接口中的方法的方法名要和映射文件中的sql的id保持一致

9 测试添加用户功能

MybatisTest

package com.mybatis.test;

import com.mybatis.mapper.UserMapper;
import com.mybatis.pojo.User;
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.junit.Test;

import java.io.IOException;
import java.io.InputStream;


public class MyBatisTest {
    @Test
    public  void testInsert() throws IOException {
        //获取核心配置文件的输入流
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //获取SQL session Factory对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
        //获取SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        //获取sql会话对象SqlSession,是Mybatis提供的操作数据库的对象
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //获取UserMapper的代理实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //User user = sqlSession.getMapper(User.class);
        //调用mapper接口中的方法,实现添加用户信息的功能
        int result=mapper.insertUser();
        System.out.println("结果:"+result);
        //提交事务
        sqlSession.commit();
        //关闭sqlsession
        sqlSession.close();
    }
}

10 优化功能

核心配置文件,配置连接数据库的环境mybatis-config.xml

引入映射文件

mapper接口(保持两个一致)

用的少:(了解)

int result = sqlSession.insert(UserMapper.insertUser);

11 源码验证和日志级别--log4j

日志的级别

FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)

从左到右打印的内容越来越详细

log4j.properties

log4j.rootLogger=debug, stdout, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

log4j.xml

<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM
        "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">

<log4j:configuration debug="true">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}
%m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

12 测试修改和删除用户的功能

SqlSessionUtil.java

新建一个工具类,封装到这里

com.mybatis.utils

package com.mybatis.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 SqlSessionUtil {
    public static SqlSession getSqlSession(){
        SqlSession sqlSession=null;
        try {
            //获取核心配置文件的输入流
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //获取SqlSessionFactoryBuilder
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
            //获取SqlSessionFactory
            SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is);
            //获取sqlSession对象
            sqlSession=sqlSessionFactory.openSession(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }
}

UserMapper.xml

    <!-- void updateUser(); -->
    <update id="updateUser">
        update t_user set username="root",password="123" where id=3
    </update>

    <!-- void deletdeUser(); -->
    <delete id="deleteUser">
        delete  from t_user where id=3
    </delete>

UserMapper.java

package com.mybatis.mapper;
​
public interface UserMapper {
​
    int insertUser();
​
    void updateUser();
​
    void deleteUser();
​
}
​

Test.java

@Test
    public void testUpdate(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateUser();
        sqlSession.close();
    }
​
​
    @Test
    public void testDelete(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.deleteUser();
        sqlSession.close();
    }

13 测试查询功能

UserMapper.java

package com.mybatis.mapper;
​
import com.mybatis.pojo.User;
​
import java.util.List;
​
public interface UserMapper {
​
    int insertUser();
​
    void updateUser();
​
    void deleteUser();
​
    User getUserById();
​
    List<User> getAllUser();
    
}
​

较上节课新增的有(查询)

User getUserById();

 List<User> getAllUser();

UserMapper.xml

    <!--
        resultType : 设置结果类型,即查询的数据要转换为的Java类型
        resultMap : 自定义映射,处理多对一或一对多的映射关系
     -->
    <select id="getUserById" resultType="com.mybatis.pojo.User">
        select  * from t_user where id=1
    </select>

    <!-- List<User> getAllUser -->
    <select id="getAllUser" resultType="com.mybatis.pojo.User">
        select * from t_user
    </select>

Test.java

  @Test
    public void testGetUserById(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user=mapper.getUserById();
        System.out.println(user);
    }


    @Test
    public void testGetAllUser(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> list=mapper.getAllUser();
       // list.forEach(System.out::println);
       //最后一句不好使,不能运行
    }

Mybatis核心配置文件

14 environments

<!--
        environments:配置连接数据库的环境
        属性:
        default:设置默认使用的环境id
    -->
    <environments default="development">
        <!--
            environment:设置一个具体的连接数据库环境
            属性:
            id:设置环境的唯一标识,不能重复
        -->
        <environment id="development">
            <!--
                transactionManager:设置事务管理器
                属性:
                type:设置事务管理的方式
                type="JDBC/MANAGED"
                JDBC:表示使用JDBC中原生的事务管理方式
                MANAGED:被管理,例如Spring
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource:设置数据源
                属性:
                type="POOLED/UNPOOLED/JNDI"
                POOLED:表示使用数据库连接池
                UNPOOLED:表示不使用数据库连接池
                JNDI:表示使用上下文中的数据源
            -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?
serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

1 . default:设置默认的id

<environment id="development">

上面有标注

15 properties

jdbc.properties(新建的文件)

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

mybatis-config.xml

<!--引入properties文件,此后就可以在当前文件中使用   ${key}   的方式访问value  -->
    <properties resource="jdbc.properties"></properties>
<dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>

16 typeAliases类型别名

配置顺序

Mybatis核心配置文件中的标签必须要按照指定的顺序配置
    properties?,settings?,typeAliases?,typeHandlers?,
    objectFactory?,objectWrapperFactory?,reflectorFactory?,
    plugins?,environments?,databaseIdProvider?,mappers?

mybatis-config.xml

 <!--
        typeAlias:设置类型别名,即为某个具体的类型设置一个别名
        在Mybatis范围内,就可以使用别名表示一个具体的类型
     -->
    <typeAliases>
        <!--
            type:设置需要起别名的类型
            alias:设置某个类型的别名
        -->
        <!--<typeAlias type="com.mybatis.pojo.User" alias="abc"></typeAlias>-->
        <!--若不设置alias,当前的类型拥有默认的别名,即类名且不区分大小写 -->
        <!--<typeAlias type="com.mybatis.pojo.User"></typeAlias>-->
        <!--通过包设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写-->
        <package name="com.mybatis.pojo"/>
    </typeAliases>

UserMapper.xml

resultType="com.mybatis.pojo.User"可以写为resultType="User

<select id="getUserById" resultType="User">
        select  * from t_user where id=1
    </select>

17 mappers

<mappers>
    <!--<mapper resource="mappers/UserMapper.xml"></mapper>-->
    <!--
        以包的方式引入映射文件,但是必须满足两个条件:
        1、mapper接口和映射文件所在的包必须一致
        2、mapper接口的名字和映射文件的名字必须一致
    -->
    <package name="com.mybatis.mapper"/>
</mappers>

resources目录下新建文件com/mybatis/mapper

【图】

18 在idea中能够创建mybatis核心配置文件和映射文件的模板

mybatis-config

<?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>

    <!--  Mybatis核心配置文件中的标签必须要按照指定的顺序配置
    properties?,settings?,typeAliases?,typeHandlers?,
    objectFactory?,objectWrapperFactory?,reflectorFactory?,
    plugins?,environments?,databaseIdProvider?,mappers?
    -->
    <properties resource="jdbc.properties"></properties>
    
    <typeAliases>
        <package name=""/>
    </typeAliases>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <package name=""/>
    </mappers>
</configuration>

mybatis-mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<mapper namespace="">
</mapper>

Settings

19 使用模板搭建Mybatis框架

1、导入log4j.xml

jdbc.properties

2、mybatis-config.xml(模板)

3、接口

4、对应的映射文件

Mybatis获取参数值

20 两种方式

MyBatis获取参数值的两种方式:${}和#{}

${}的本质就是字符串拼接,#{}的本质就是占位符赋值

${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单 引 号;

但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时, 可以自 动添加单引号

21 情况(1)

单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型

此时可以使用${}和#{}以任意的名称获取参数的值,注意${}需要手动加单引号

Mybatis 3.5

UserMapper.java

User getUserByUsername(String username);

UserMapper.xml

<!--User getUserByUsername(String username); -->
    <select id="getUserByUsername" resultType="com.atguigu.mybatis.pogo.User">
        select * from t_user where username =#{username}
        <!--   '${username}'   -->
    </select>

ParameterTest.java

@Test
    public void testGetUserByUsername(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserByUsername("admin");
        System.out.println(user);
    }

22 情况(2)

多个字面量类型的参数

若mapper接口中的方法参数为多个时 此时MyBatis会自动将这些参数放在一个map集合中,以arg0,arg1...为键,以参数为值;

以 param1,param2...为键,以参数为值;

因此只需要通过${}和#{}访问map集合的键就可以获取相 对应的 值,注意${}需要手动加单引号

UserMapper.java

/*验证登录*/
    User checkLogin(String username,String password);

UserMapper.xml

<!--User checkLogin(String username,String password);-->
    <select id="checkLogin" resultType="com.atguigu.mybatis.pogo.User">
        select *from t_user where username= #{param1} and password= #{param2}
        /*select *from t_user where username= '${arg0}' and password= '${arg1}'*/
    </select>

ParameterTest.java

@Test
    public void testCheckLogin(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.checkLogin("admin", "123456");
        System.out.println(user);
    }

23 情况(3)

map集合类型的参数

若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在 map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号

UserMapper.java

/*验证登录(以map集合作为参数)*/
    User checkLoginByMap(Map<String,Object> map);

UserMapper.xml

 <!--User checkLoginByMap(Map<String,Object> map);-->
    <select id="checkLoginByMap" resultType="com.atguigu.mybatis.pogo.User">
        select * from t_user where username=#{username} and password = #{password}
    </select>

ParameterTest.java

@Test
    public void testCheckLoginByMap(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map<String ,Object> map=new HashMap<String, Object>();
        map.put("username","admin");
        map.put("password","123456");
        User user = mapper.checkLoginByMap(map);
        System.out.println(user);
    }

24 情况(4)

实体类类型的参数

若mapper接口中的方法参数为实体类对象时 此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号

UserMapper.java

/*添加用户信息*/
    void insertUser(User user);

UserMapper.xml

<!--void insertUser(User user);-->
    <insert id="insertUser">
        insert into t_user values (null,#{username},#{password},#{age},#{gender},#{email})
    </insert>

ParameterTest.java

 @Test
    public void testInsertUser() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(null, "root", "123456", 33, "女", "123@qq.com");
        mapper.insertUser(user);
    }

25 情况(5)

使用@Param标识参数

可以通过@Param注解标识mapper接口中的方法参数

此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;

以 param1,param2...为键,以参数为值;

只需要通过${}和#{}访问map集合的键就可以获取相对应 的值,

注意${}需要手动加单引号

UserMapper.java

/*验证登录(使用Param)*/
    User checkLoginByParam(@Param("username") String username,@Param("password") String password);

UserMapper.xml

<!--User checkLoginByParam(@Param("username") String username,@Param("password") String password);-->
    <select id="checkLoginByParam" resultType="com.atguigu.mybatis.pogo.User">
        select *from t_user where username=#{username} and password=#{password}
    </select>

ParameterTest.java

 @Test
    public void testCheckLoginByParam(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.checkLoginByParam("admin", "123456");
        System.out.println(user);
    }

Mybatis的各种查询功能

26 功能(1)

若sql语句查询结果为多条时,一定不能以实体类类型作为方法的返回值

否则会抛出异常TooManyResultsException

若sql语句查询的结果为1条时,此时可以使用实体类类型或list集合类型作为方法的返回值

SelectMapper.java

public interface SelectMapper {
​
    User getUserById(@Param("id") Integer id);
​
    List<User> getAllUser();
​
}

SelectMapper.xml

<!--User getUserById(@Param("id") int id);-->
    <select id="getUserById" resultType="com.atguigu.mybatis.pogo.User">
        select * from t_user where id=#{id}
    </select>
​
    <!--List<User> getAllUser();-->
    <select id="getAllUser" resultType="com.atguigu.mybatis.pogo.User">
        select * from t_user
    </select>

SelectMapperTest.java

 @Test
    public void testGetUserById(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
    }

    /*@Test
    public void testGetAllUser(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        List<User> list = mapper.getAllUser();
        list.forEach(System.out);
    }*/

    @Test
    public void testGetAllUser(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        List<User> list = mapper.getAllUser();
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

27 功能(2)

SelectMapper.java

/*查询用户的总数量*/
    Integer getCount();

SelectMapper.xml

<!--Integer getCount();-->
    <select id="getCount" resultType="java.lang.Integer">
        select count(*) from t_user
    </select>

SelectMapperTest.java

@Test
    public void testGetCount(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        Integer count = mapper.getCount();
        System.out.println(count);
    }

28 功能(3)

SelectMapper.java

/*根据id查询用户信息为map集合*/
    Map<String,Object> getUserByIdToMap(@Param("id") Integer id);

SelectMapper.xml

 <!--Map<String,Object> getUserByIdToMap(@Param("id") Integer id);-->
    <select id="getUserByIdToMap" resultType="map">
        select * from t_user where id= #{id}
    </select>

SelectMapperTest.java

@Test
    public void testGetUserByIdToMap(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        Map<String, Object> map = mapper.getUserByIdToMap(1);
        //{password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin}
        //数据为null则不会被放到map集合中
        //{password=123, gender=男, id=2, age=19}
        System.out.println(map);
    }

29 功能(4)

/*
    * 若数据有多条时,并且要将每条数据转换为Map集合
    * 此时有两种解决方案:
    * 1、将mapper接口方法的返回值设置为泛型是map的list集合
    * List<Map<String,Object> >getAllUserToMap();
    *结果:{password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin},
        {password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}
     *2、
     * 可以将每条数据转换的map集合放在一个大的map中,但是必须通过@MapKey注解
     * 将查询的某个字段作为大的map键
     @MapKey("id")
    Map<String,Object> getAllUserToMap();
     结果:
    * */
    /*{1={password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin},
        2={password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}}
         */

List常用

SelectMapper.java

List<Map<String,Object> >getAllUserToMap();

SelectMapper.xml

<!--List<Map<String,Object> >getAllUserToMap();-->
    <select id="getAllUserToMap" resultType="map">
        select *from t_user
    </select>

SelectMapperTest.java

public void testGetAllUserToMap(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        /*Map<String, Object> map = mapper.getAllUserToMap();
        System.out.println(map);*/
        /*{1={password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin},
        2={password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}}
         */
        List<Map<String, Object>> list = mapper.getAllUserToMap();
        System.out.println(list);
        /*[{password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin}, 
        {password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}]*/
    }

Map

SelectMapper.java

/*查询所有用户信息为map集合*/
    @MapKey("id")
    Map<String,Object> getAllUserToMap();

SelectMapper.xml

<!--List<Map<String,Object> >getAllUserToMap();-->
    <select id="getAllUserToMap" resultType="map">
        select *from t_user
    </select>

SelectMapperTest.java

public void testGetAllUserToMap(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        Map<String, Object> map = mapper.getAllUserToMap();
        System.out.println(map);
    }

特殊SQL的执行

30 处理模糊查询(1)

SpecialSQLMapper.java

/**
     * 测试模糊查询
     * 通过用户名模糊查询用户信息
     *
     * @param mohu
     * @return
     * */
    //List<User> getUserByLike(@Param("mohu") String mohu);
    List<User> getUserByLike(@Param("mohu") String mohu);

SpecialSQLMapper.xml

<!--List<User> getUserByLike(@Param("mohu") String mohu);-->
    <select id="getUserByLike" resultType="User">
        <!--select * from t_user where username like '%${mohu}%'-->
        <!--select * from t_user where username like concat('%',#{mohu},'%')-->
        select * from t_user where username like "%"#{mohu}"%"
    </select>

SpecialSQLMapper.java

 @Test
    public void testgetUserByLike(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class);
        List<User> list = mapper.getUserByLike("a");
        //list.forEach(System.out::println);
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

31 处理模糊查询(2)

<!--List<User> testMohu(@Param("mohu") String mohu);-->
<select id="testMohu" resultType="User">
<!--select * from t_user where username like '%${mohu}%'-->
<!--select * from t_user where username like concat('%',#{mohu},'%')-->
select * from t_user where username like "%"#{mohu}"%"
</select>

32 Mybatis批量处理删除

注意:xml中要使用${ids}

#{ids}不行

SpecialSQLMapper.java

/*批量删除*/
    void deleteMoreUser(@Param("ids") String ids);

SpecialSQLMapper.xml

<!--void deleteMoreUser(@Param("ids") String ids);-->
    <delete id="deleteMoreUser">
        delete from t_user where id in(${ids})
    </delete>

SpecialSQLMapper.java

@Test
    public void testDeleteMoreUser(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class);
        mapper.deleteMoreUser("7,8");
    }

33 Mybatis处理动态设置表名

注意:${tableName}

SpecialSQLMapper.java

/*处理动态设置表名*/
    List<User> getUserList(@Param("tableName") String tableName);

SpecialSQLMapper.xml

 <!--List<User> getUserList(@Param("tableName") String tableName);-->
    <select id="getUserList" resultType="user">
        select * from ${tableName}
    </select>

SpecialSQLMapper.java

@Test
    public void testGetUserList(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class);
        List<User> list = mapper.getUserList("t_user");
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

34 Mybatis获取自增的主键

SpecialSQLMapper.java

 /*添加用户信息并获取自增的主键*/
    void insertUser(User user);

SpecialSQLMapper.xml

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into t_user VALUES (null,#{username},#{password},#{age},#{gender},#{email})
    </insert>

SpecialSQLMapper.java

@Test
    public void testInsertUser(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class);
        User user=new User(null,"xiaoming","123456",10,"女","123456@qq.com");
        mapper.insertUser(user);
        System.out.println(user);
    }
 public  void testJDBC(){
        try {
            Class.forName("");
            Connection connection= DriverManager.getConnection("","","");

            String sql="insert into t_user values()";
            PreparedStatement ps=connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
            ps.executeUpdate();
            ResultSet resultSet = ps.getGeneratedKeys();
            resultSet.next();
            int id=resultSet.getInt(1);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

自定义映射ResultMap

35 搭建Mybatis框架

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射

ResultMap:设置自定义映射
属性:
id:设置自定义映射的唯一标识
type:查询的数据要映射的实体类的类型
子标签:
id:表示主键的映射关系
result:设置普通字段的映射关系
association:设置多对一的映射关系
collection:设置一对多的映射关系

36 使用全局配置处理字段和属性名不一致的情况

EmpMapper.java

/*根据id查询员工信息*/
    Emp getEmpByEmpId(@Param("empId") Integer empId);

EmpMapper.xml

<!--Emp getEmpByEmpId(@Param("empId") Integer empId);-->
    <select id="getEmpByEmpId" resultType="com.atguigu.mybatis.pogo.Emp">
        select * from t_emp where emp_id=#{empId}
    </select>

ResultMapTest.java

@Test
    public void testGetEmpByEmpId(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpByEmpId(1);
        System.out.println(emp);
    }

37 使用resultType处理字段名和属性名不一致的情况

ResultMap:设置自定义映射
属性:
id:设置自定义映射的唯一标识//唯一标识
type:查询的数据要映射的实体类的类型//处理映射关系的实体类类型
子标签:
id:表示主键的映射关系//处理主键和实体类中属性的映射关系
result:设置普通字段的映射关系//处理普通字段和实体类中属性的映射关系
column:设置映射关系中的字段名,必须是sql查询出的某个字段
property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名
association:设置多对一的映射关系
collection:设置一对多的映射关系

EmpMapper.java

/*根据id查询员工信息*/
    Emp getEmpByEmpId(@Param("empId") Integer empId);

EmpMapper.xml

<resultMap id="empResultMap" type="com.atguigu.mybatis.pogo.Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
    </resultMap>
    <select id="getEmpByEmpId" resultMap="empResultMap" >
        select * from t_emp where emp_id=#{empId}
    </select>

ResultMapTest.java

@Test
    public void testGetEmpByEmpId(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpByEmpId(1);
        System.out.println(emp);
    }

38 处理多对一映射关系功能分析

EmpMapper.java

/*获取员工及所对应的部门信息*/
    Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);

EmpMapper.xml

 <!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
    <select id="getEmpAndDeptByEmpId" resultType="com.atguigu.mybatis.pogo.Emp">
        select t_emp.*,t_dept.*
        from t_emp
        left join t_dept
        on t_emp.dept_id=t_dept.dept_id
        where t_emp.emp_id=#{empId}
    </select>

ResultMapTest.java

@Test
    public void testGetEmpAndDeptByEmpId(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDeptByEmpId(1);
        System.out.println(emp);
    }

39-44(4)

39 使用级联处理多对一的映射关系

property="dept.deptName"爆红,但是可以运行

EmpMapper.xml

    <resultMap id="empAndDeptResultMap" type="com.atguigu.mybatis.pogo.Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <result column="dept_id" property="dept.deptId"></result>
        <result column="dept_name" property="dept.deptName"></result>
    </resultMap>

    <!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
    <select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
        select t_emp.*,t_dept.*
        from t_emp
        left join t_dept
        on t_emp.dept_id=t_dept.dept_id
        where t_emp.emp_id=#{empId}
    </select>

40 使用association处理多对一的映射关系

比上一种好用,层次更加清晰

EmpMapper.xml

<!--
        association:处理多对一的映射关系(处理实体类类型的属性)
        property:设置需要处理映射关系的属性和属性名
        javaType:设置要处理的属性的类型
    -->
<resultMap id="empAndDeptResultMap" type="com.atguigu.mybatis.pogo.Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <association property="dept" javaType="Dept">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"></result>
        </association>
    </resultMap>

41 使用分布查询处理多对一的映射关系

EmpMapper.xml

<resultMap id="empAndDeptByStepResultMap" type="com.atguigu.mybatis.pogo.Emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="gender" property="gender"></result>
        <association property="dept"
            select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptBySteptTwo"
            column="dept_id">
        </association>
    </resultMap>

    <!--Emp getEmpAndDeptByStep(@Param("empId") Integer empId);-->
    <select id="getEmpAndDeptByStep" resultMap="empAndDeptByStepResultMap">
        select * from t_emp where emp_id =#{empId}
    </select>

42 延迟加载

mubatis-config.xml

<settings>
        <!--将下划线映射为驼峰-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--按需加载-->
    </settings>

EmpMapper.xml

<!--
            fetchType:在开启了延迟加载的环境中,通过该属性设置当前的分步查询是否使用延迟加载
            fetchType="lazy" 延迟加载
            fetchType="eager" 立即加载
        -->
        <association property="dept" fetchType="lazy"
            select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptBySteptTwo"
            column="dept_id">
        </association>

43 通过collection处理多对一的映射关系

常用:

resultMap:设置自定义的映射关系
id:唯一标识
type:处理映射关系的实体类的类型

常用的标签:
id:处理主键和实体类中属性的映射关系
association:处理多对一的映射关系(处理实体类类型的属性)
result:处理普通字段和实体类中属性的映射关系
collection:处理一对多的映射关系(处理集合类型的属性)
column:设置映射关系中的字段名,必须是sql查询出的某个字段
property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名

ofType="com.atguigu.mybatis.pogo.Emp"

<collection property="emps" ofType="com.atguigu.mybatis.pogo.Emp">

EmpMapper.xml

 <resultMap id="deptAndEmpResultMap" type="com.atguigu.mybatis.pogo.Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <collection property="emps" ofType="com.atguigu.mybatis.pogo.Emp">
            <id column="emp_id" property="empId"></id>
            <id column="emp_name" property="empName"></id>
            <id column="age" property="age"></id>
            <id column="gender" property="gender"></id>
        </collection>
    </resultMap>

    <!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);-->
    <select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
        select *
        from t_dept
        left join t_emp
        on t_dept.dept_id=t_emp.dept_id
        where t_dept.dept_id=#{deptId}
    </select>

44通过分布查询处理多对一的映射关系

EmpMapper.xml

<resultMap id="deptAndEmpResultMapByStep" type="com.atguigu.mybatis.pogo.Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
        <collection property="emps"
                    select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
                    column="dept_id"></collection>
    </resultMap>
    
    <!--Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);-->
    <select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">
        select * from t_dept where dept_id=#{deptId}
    </select>

动态SQL

45-51(3)

Mybatis动态标签

45 动态SQL简介

Myabtis框架的动态SQL技术是一种根据特定条件动态拼装SQl语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题
if:通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到sql中)
where:
        a.若where标签中有条件成立,会自动生成where关键字
        b.会自动将where标签中内容前多余的and去掉
        c.若where标签中没有任何一个条件成立,则where没有任何功能
trim:   prefix

46 if标签

if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;
​
反之 标签中的内容不会执行

DynamicSQLMapper.java

/*根据条件查询员工信息*/
    List<Emp> getEmpByCondition(Emp emp);

DynamicSQLMapper.xml

<!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp where
        <if  test="empName!=null and empName!=''">
            emp_name=#{empName}
        </if>
        <if test="age !=null and age !=''">
            and age = #{age}
        </if>
        <if test="gender !=null and gender !=''">
            and  gender = #{gender}
        </if>
    </select>

DynamicMapperTest.java

@Test
    public void DynamicMapperTest(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp=new Emp(null,"张三",21,"男");
        List<Emp> list = mapper.getEmpByCondition(emp);
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

47 where标签

where和if一般结合使用:

 a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字 

b>若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的 and去掉 ,但是内容后的and去不掉

注意:where标签不能去掉条件最后多余的and

第一种方法

where 1=1

DynamicSQLMapper.xml

<!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp where 1=1
        <if  test="empName!=null and empName!=''">
            and emp_name=#{empName}
        </if>
        <if test="age !=null and age !=''">
            and age = #{age}
        </if>
        <if test="gender !=null and gender !=''">
            and  gender = #{gender}
        </if>
    </select>

第二种方法

DynamicSQLMapper.java

 /*根据条件查询员工信息*/
    List<Emp> getEmpByCondition(Emp emp);

DynamicSQLMapper.xml(只改变了这部分)

<select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp
        <where>
            <if  test="empName!=null and empName!=''">
                emp_name=#{empName}
            </if>
            <if test="age !=null and age !=''">
                and age = #{age}
            </if>
            <if test="gender !=null and gender !=''">
                and  gender = #{gender}
            </if>
        </where>
    </select>

DynamicMapperTest.java

 @Test
    public void DynamicMapperTest(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp=new Emp(null,"",null,"");
        List<Emp> list = mapper.getEmpByCondition(emp);
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

48 trim标签

trim用于去掉或添加标签中的内容 

常用属性: 

prefix:在trim标签中的内容的前面添加某些内容 

prefixOverrides:在trim标签中的内容的前面去掉某些内容 

suffix:在trim标签中的内容的后面添加某些内容 

suffixOverrides:在trim标签中的内容的后面去掉某些内容

DynamicSQLMapper.java

 

DynamicSQLMapper.xml

 

DynamicMapperTest.java

 

49 choose、when标签 otherwise

choose、when,otherwise

相当于

if,else if,else

DynamicSQLMapper.java

/*使用choose查询员工信息*/
    List<Emp> getEmpByChoose(Emp emp);

DynamicSQLMapper.xml

<!--List<Emp> getEmpByChoose(Emp emp);-->
    <select id="getEmpByChoose" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp
        <where>
            <choose>
                <when test="empName != null and empName !=''">
                    emp_name=#{empName}
                </when>
            </choose>
            <choose>
                <when test="age != null and age!=''">
                    age=#{age}
                </when>
            </choose>
            <choose>
                <when test="gender != null and gender!=''">
                    gender=#{gender}
                </when>
            </choose>
        </where>
    </select>

DynamicMapperTest.java

@Test
    public void getEmpMapperTest(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp=new Emp(null,"",null,"");
        List<Emp> list = mapper.getEmpByChoose(emp);
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
    }

50 foreach标签(重要)批量添加

collection:设置要循环的数组或集合
item:用一个字符串表示数组或集合中的每一个数据
separator:设置每次循环的数据之间的分隔符
open:循环的所有内容以什么开始
close:循环的所有内容以什么结束

DynamicSQLMapper.java

/*批量添加员工信息*/
    void  insertMoreEmp(@Param("emps") List<Emp> emps);

DynamicSQLMapper.xml

<!--void  insertMoreEmp(List<Emp> emps);-->
    <insert id="insertMoreEmp">
        insert into t_emp values
        /*separator:分隔符*/
        <foreach collection="emps" item="emp" separator=",">
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        </foreach>
    </insert>

DynamicMapperTest.java

@Test
    public void getInsertMoreEmp(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp1=new Emp(null,"小明1",20,"男");
        Emp emp2=new Emp(null,"小明2",20,"男");
        Emp emp3=new Emp(null,"小明3",20,"男");
        List<Emp> list = Arrays.asList(emp1, emp2, emp3);
        mapper.insertMoreEmp(list);
    }

51 foreach标签 批量删除

DynamicSQLMapper.java

/*批量删除*/
    void deleteMoreEmp(@Param("empIds") Integer[] empIds);

DynamicSQLMapper.xml

<!--void deleteMoreEmp(@Param("empIds") Integer[] empIds);-->
    <delete id="deleteMoreEmp">
        delete from t_emp where emp_id in
        (
        <foreach collection="empIds" item="empId" separator=",">
            #{empId}
        </foreach>
        )
    </delete>

DynamicMapperTest.java

@Test
    public void getDeleteMoreEmp(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Integer[] empIds=new Integer[]{6,7};
        mapper.deleteMoreEmp(empIds);
    }

第一种

DynamicSQLMapper.xml

<delete id="deleteMoreEmp">
        delete from t_emp where emp_id in
        (
        <foreach collection="empIds" item="empId" separator=",">
            #{empId}
        </foreach>
        )
    </delete>

第二种

open="(" close=")"

DynamicSQLMapper.xml

<delete id="deleteMoreEmp">
        delete from t_emp where emp_id in
        <foreach collection="empIds" item="empId" separator="," open="(" close=")">
            #{empId}
        </foreach>
    </delete>

第三种

DynamicSQLMapper.xml

    delete from t_emp where
        <foreach collection="empIds" item="empId" separator="or">
            emp_id=#{empId}
        </foreach>

52-58(2)

52 Mybatis动态SQL之sql标签

sql片段:
可以记录一段sql,在需要用的地方使用include标签进行引用

DynamicSQLMapper.xml

<sql id="empColumns">
        emp_id,emp_name,age,gender,dept_id
    </sql>
​
​
<include refid="empColumns"></include>

Mybatis的缓存

53 Mybatis的一级缓存

一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就 会从缓存中直接获取,不会从数据库重新访问

/*
    一级缓存测试
    *两次查询只执行了一次sql
    * */
    @Test
    public void testGetEmpByIdtest1(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        Emp emp1 = mapper.getEmpById(1);
        System.out.println(emp1);
        Emp emp2 = mapper.getEmpById(1);
        System.out.println(emp2);
    }

54 使一级缓存失效的四种情况

使一级缓存失效的四种情况:

  1. 不同的SqlSession对应不同的一级缓存

  2. 同一个SqlSession但是查询条件不同

  3. 同一个SqlSession两次查询期间执行了任何一次增删改操作

  4. 同一个SqlSession两次查询期间手动清空了缓存

清空一级缓存:
 sqlSession.clearCache();

55 Mybatis的二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被 缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

/*
    二级缓存
    */
    @Test
    public void testCache() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        Emp emp =mapper.getEmpById(1);
        System.out.println(emp);
        sqlSession.close();
​
        SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
        CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
        Emp emp1 =mapper1.getEmpById(1);
        System.out.println(emp1);
        sqlSession1.close();
    }

二级缓存开启的条件:

a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置

b>在映射文件中设置标签

c>二级缓存必须在SqlSession关闭或提交之后有效

d>查询的数据所转换的实体类类型必须实现序列化的接口

public class Emp implements Serializable {

}

使二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

56 Mybatis二级缓存相关的配置和缓存

在mapper配置文件中添加的cache标签可以设置一些属性:

①eviction属性:缓存回收策略,默认的是 LRU。

LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。

FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。

SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

②flushInterval属性:刷新间隔,单位毫秒

默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

③size属性:引用数目,正整数

代表缓存最多可以存储多少个对象,太大容易导致内存溢出

④readOnly属性:只读, true/false

    true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了 很重 要的性能优势。 

false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。

Mybatis缓存的查询顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。

如果二级缓存没有命中,再查询一级缓存

如果一级缓存也没有命中,则查询数据库

SqlSession关闭之后,一级缓存中的数据会写入二级缓存

57 Mybatis整合第三方缓存

针对二级缓存(了解)

58 Mybatis逆向工程之清晰简洁版

正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工 程的。

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

Java实体类 Mapper接口 Mapper映射文件

59 Mybatis逆向工程之奢华尊享版

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--
    targetRuntime: 执行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD(清新简洁版)
    MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.atguigu.mybatis.pojo"
                            targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.atguigu.mybatis.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.atguigu.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="t_emp" domainObjectName="Emp"/>
        <table tableName="t_dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

60 分页功能分析

limit index,pageSize
pageSize:每页显示的条数
pageNum:当前页的页码
index:当前页的起始索引,index=(pageNum-1)*pageSize
count:总记录数
totalPage:总页数
totalPage = count / pageSize;
if(count % pageSize != 0){
totalPage += 1;
}
pageSize=4,pageNum=1,index=0 limit 0,4
pageSize=4,pageNum=3,index=8 limit 8,4
pageSize=4,pageNum=6,index=20 limit 8,4
首页 上一页 2 3 4 5 6 下一页 末页

61 分页插件的使用

添加依赖pom.xml

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>

配置分页插件

<plugins>
<!--设置分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

62 通过分页插件获取分页相关数据

a>在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能
pageNum:当前页的页码
pageSize:每页显示的条数
b>在查询获取list集合之后,使用PageInfo<T> pageInfo = new PageInfo<>(List<T> list, int
navigatePages)获取分页相关数据
list:分页之后的数据
navigatePages:导航分页的页码数
c>分页相关数据
PageInfo{
pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8,
list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30,
pages=8, reasonable=false, pageSizeZero=false},
prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true,
hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8,
navigatepageNums=[4, 5, 6, 7, 8]
}
pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[1,2,3,4,5]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值