【SSM框架】Mybatis的基本使用

Mybatis的基本使用

学习目标

  1. 认识Mybatis

  2. 了解Mybatis功能

  3. 知道为什么学习Mybatis

  4. 利用Mybatis编写一个简单程序

  5. 学会使用Mybatis基本功能

  6. 了解Mybatis的基本配置

一、认识Mybatis

官方文档

1. 简介

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,屏蔽了jdbc api底层访问细节,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

2. 原理

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

3. 为什么使用Mybatis

原生jdbc连接

import org.junit.jupiter.api.Test;

import java.sql.*;


public class MySQLTest {
    
    
    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost:3306/hist?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true" +
            "&serverTimezone=UTC";

    // 数据库的用户名与密码,需要根据自己的设置
    static final String USER = "root";
    static final String PASS = "123456";

    /**
     * 测试原生sql方式查询
     */
    @Test
    public void testQuery() {
    
    
        Connection conn = null;
        Statement stmt = null;
        try {
    
    
            // 1.注册 JDBC 驱动
            Class.forName(JDBC_DRIVER);

            // 2.打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            // 3.执行查询
            System.out.println(" 实例化Statement对象...");
            stmt = conn.createStatement();

            String sql;
            sql = "SELECT runoob_id, runoob_title, runoob_author FROM runoob_tbl WHERE runoob_title='学习PHP'";
            ResultSet rs = stmt.executeQuery(sql);

            // 4.展开结果集数据库
            while (rs.next()) {
    
    
                System.out.println(rs.getString("runoob_title"));
                // 通过字段检索
                int id = rs.getInt("runoob_id");
                String name = rs.getString("runoob_title");
                String author = rs.getString("runoob_author");

                // 输出数据
                System.out.print("ID: " + id);
                System.out.print("name: " + name);
                System.out.print("author: " + author);
                System.out.print("\n");
            }
            // 5.完成后关闭
            rs.close();
            stmt.close();
            conn.close();
        } catch (Exception se) {
    
    
            // 处理 JDBC 错误
            se.printStackTrace();
        }// 处理 Class.forName 错误
        finally {
    
    
            // 关闭资源
            try {
    
    
                if (stmt != null) {
    
    
                    stmt.close();
                }
            } catch (SQLException ignored) {
    
    
            }// 什么都不做
            try {
    
    
                if (conn != null) {
    
    
                    conn.close();
                }
            } catch (SQLException se) {
    
    
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jdbctest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

存在的问题

  1. 数据库连接频繁开启和关闭,会严重影响数据库的性能。

  2. 代码中存在硬编码,分别是数据库部分的硬编码和SQL执行部分的硬编码。

Mybatis的存在:

  • Mybatis就是帮助我们将数据存入数据库中 , 和从数据库中取数据

  • MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) -->对象关系映射

当然,所有的事情,不用Mybatis依旧可以做到,只是用了它,所有实现会更加简单!

4. Mybatis的优点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。

  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

  • 提供xml标签,支持编写动态sql。

  • 用户量大,公司需要

5. Mybatis的核心

  • mybatis配置文件,包括Mybatis****全局配置文件和Mybatis映射文件**,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的 信息。

  • mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。

  • 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。

  • SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)

  • Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型

6. 如何获取mybatis

  • Maven
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>
  • Github:https://github.com/mybatis/mybatis-3

  • 源码中文注释: https://github.com/tuguangquan/mybatis
    要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中即可。

二、Mybatis入门

项目结构

img

1. 环境搭建

  • 创建数据库
CREATE DATABASE `mybatis_01`;

USE `mybatis_01`;

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`phone` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`name`,`phone`) values (1,'张三','1536537156'),(2,'李四','1536537157'),(3,'王五','1536537158');

新建一个Maven项目作为父工程

  • 导入相关Maven依赖
	<dependencies>
        <!--   mybatis依赖     -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- 数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <!-- <version>5.1.47</version>-->
            <version>8.0.11</version>

        </dependency>
        <!--        <dependency>-->
        <!--            <groupId>mysql</groupId>-->
        <!--            <artifactId>mysql-connector-java</artifactId>-->
        <!--            <version>8.0.12</version>-->
        <!--        </dependency>-->
        <!--测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>
    <!--在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>

2. 创建一个模块,编写MyBatis核心配置文件

mybatis-config.xml

<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置mybatis的环境信息 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置JDBC事务控制,由mybatis进行管理 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源,采用传统的javax. sql. DataSource规范中的连接池 -->
            <dataSource type="POOLED">
                <!--       如果数据库驱动使用的是8.0.12需要使用下面的驱动        -->
                <!--<property name="driver" value="com.mysql.cj.jdbc.Driver"/>-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>

                <!--       如果数据库驱动使用的是8.0.12需要使用下面的配置         -->
                <!--<property name="url" value="jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&amp;useUnicode=true&amp;serverTimezone=UTC&amp;characterEncoding=utf8"/>-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/hist/dao/UserMapper.xml"/>
    </mappers>
</configuration>

3. 编写MyBatis工具类

MybatisUtil

public class MybatisUtil {
    
    
    private static SqlSessionFactory sqlSessionFactory;

    static {
    
    
        try {
    
    
            // 1. 读取配置文件
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            // 2. 通过SqlSessionFactoryBuilder创建sqlSessionFactory会话工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     *功能描述:获取SqlSession连接
    */
    public static SqlSession getSession(){
    
    
        // 使用sqlSessionFactory创建SqlSession
        return sqlSessionFactory.openSession();
    }
}

4. 创建实体类

User

public class User {
    
    
   
   private int id;  //id
   private String name;   //姓名
   private String phone;   //手机号
   
   //构造,有参,无参
   //set/get
   //toString()
   
}

5. 编写Mapper接口

public interface UserMapper {
    
    
    /**
     *功能描述: 查询用户集合
     * @return java.util.List<com.hist.entity.User>
    */
    List<User> selectUser();
}

6. 编写Mapper.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 
	namespace:命名空间,它的作用就是对SQL进行分类化管理,可以理解为SQL隔离
	注意:使用mapper代理开发时,namespace有特殊且重要的作用
 -->

<mapper namespace="com.hist.dao.UserMapper">
    <select id="selectUser" resultType="com.hist.entity.User">
      select * from user
     </select>
</mapper>

7. 编写测试类

public class UserTest {
    
    
    @Test
    public void selectUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        // 调用SqlSession操作数据库
        List<User> users = mapper.selectUser();

        for (User user: users){
    
    
            System.out.println(user);
        }
        // 关闭 SqlSession
        session.close();
    }
}

8. 运行结果

img

三、更多案例讲解

1. 通过id查询用户

在UserMapper中添加方法

public interface UserMapper {
    
    
    /**
     *功能描述: 查询用户集合
     * @return java.util.List<com.hist.entity.User	>
    */
    List<User> selectUser();
    /**
     *功能描述: 通过id查询用户
     * @param id 用户id
     * @return com.hist.entity.User
    */
    User selectUserById(int id);
}

在UserMapper.xml中添加Select语句

<!-- 
		[id]:statement的id,要求在命名空间内唯一  
		[parameterType]:入参的java类型
		[resultType]:查询出的单条结果集对应的java类型
		[#{}]: 表示一个占位符?
		[#{id}]:表示该占位符待接收参数的名称为id。注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义
	 -->
	<select id="selectUserById" parameterType="int" resultType="com.hist.entity.User">
		SELECT * FROM USER WHERE id = #{id}
	</select>

在测试类中添加

    @Test
    public void tsetSelectUserById() {
    
    
        SqlSession session = MybatisUtil.getSession();  //获取SqlSession连接
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selectUserById(1);
        System.out.println(user);
        session.close();
    }

运行结果

img

2. 根据多个参数查询

在UserMapper中添加

/**
     *功能描述: 根据多个参数查询用户
     * @param name 用户名
     * @param phone 手机号
     * @return com.hist.entity.User
    */
    User selectUserByParams(String name, String phone);

在UserMapper.xml中添加

    <select id="selectUserByParams" resultType="com.hist.entity.User">
		SELECT * FROM USER WHERE name = #{
    
    name} and phone = #{
    
    phone}
	</select>

测试类

    @Test
    public void testSelectUserByParams() {
    
    
        SqlSession session = MybatisUtil.getSession();  //获取SqlSession连接
        UserMapper mapper = session.getMapper(UserMapper.class);
        String name = "王五";
        String phone = "1536537158";
        User user = mapper.selectUserByParams(name, phone);
        System.out.println(user);
        session.close();
    }

运行结果

img

报错原因

因为java没有保存形参的记录,java在运行的时候会把 selectUserByParams(name, phone) 中的参数变成这样selectUserByParams(int arg0,int arg1),这样我们就没有办法去传递多个参数。

解决办法一:

在参数前添加@Param 注解 mybatis提供了@Param这个注解来完成命名传入参数

/**
     * 功能描述: 根据多个参数查询用户
     *
     * @param name  用户名
     * @param phone 手机号
     * @return com.hist.entity.User
     */
    User selectUserByParams(@Param("name") String name, @Param("phone") String phone);

解决办法二:

使用Map

User selectUserByParams2(Map<String,String> map);
-------
<select id="selectUserByParams2" parameterType="map" resultType="com.hist.entity.User">
    SELECT * FROM USER WHERE name = #{
    
    name} and phone = #{
    
    phone}
</select>
--------
Map<String,String> map = new HashMap<String, String>();
map.put("name","王五");
map.put("phone","1536537158");
User user = mapper.selectUserByParams2(map);

两种方法对比:

Map方法缺点就在于可读性差,每次必须阅读他的键,才能明白其中的作用,后期维护困难。

@Param,可读性比较强

当参数为2-5个时候,用@param最佳,当大于5的时候,肯定会选择map了

Map替代方法:

使用BO传输

在entity中创建UserBo

public class UserBO {
    
    
    private String name;
    private String phone;
    //构造,有参,无参
   //set/get
   //toString()
}

UserMapper

User selectUserByParams3(UserBO userBO);

UserMapper

<select id="selectUserByParams3" parameterType="com.hist.entity.UserBO" resultType="com.hist.entity.User">
    SELECT * FROM USER WHERE name = #{name} and phone = #{phone}
</select>

测试类

    @Test
    public void testSelectUserByParams3() {
    
    
        SqlSession session = MybatisUtil.getSession();  //获取SqlSession连接
        UserMapper mapper = session.getMapper(UserMapper.class);
        UserBO userDTO = new UserBO();
        userDTO.setName("王五");
        userDTO.setPhone("1536537158");
        User user = mapper.selectUserByParams3(userDTO);
        System.out.println(user);
        session.close();
    }

一篇文章讲清楚VO,BO,PO,DO,DTO的区别

3. 根据name模糊查询

在UserMapper中添加

/**
 *功能描述: 根据name 模糊查询
 * @param name 用户姓名
 * @return com.hist.entity.User
*/
User selectUserLikeByName(String name);

在UserMapper.xml中添加Select语句

<!-- 
		[${}]:表示拼接SQL字符串
	 	[${value}]:表示要拼接的是简单类型参数。
		 注意:
		1、如果参数为简单类型时,${}里面的参数名称必须为value 
		2、${}会引起SQL注入,一般情况下不推荐使用。但是有些场景必须使用${},比如order by ${colname}
	-->

<select id="selectUserLikeByName" parameterType="String" resultType="com.hist.entity.User">
    select * from USER where name like '%${value}%'
</select>

在测试类中添加

    @Test
    public void testSelectUserLikeByName() {
    
    
        SqlSession session = MybatisUtil.getSession();  //获取SqlSession连接
        UserMapper mapper = session.getMapper(UserMapper.class);
        String name = "李";
        User user = mapper.selectUserLikeByName(name);
        System.out.println(user);
        session.close();
    }

**#{}**和${}

#{}:相当于预处理中的占位符?。

#{}里面的参数表示接收java输入参数的名称。

#{}可以接受HashMap、POJO类型的参数。

当接受简单类型的参数时,#{}里面可以是value,也可以是其他。

#{}可以防止SQL注入。

${}:相当于拼接SQL串,对传入的值不做任何解释的原样输出。

${}会引起SQL注入,所以要谨慎使用。

${}可以接受HashMap、POJO类型的参数。

当接受简单类型的参数时,${}里面只能是value。

4. 新增用户

在UserMapper中添加

    /**
     *功能描述: 新增一个用户
     * @param user 用户信息
    */
    int addUser(User user);

在UserMapper.xml中添加insert语句

    <insert id="addUser" parameterType="com.hist.entity.User">
        insert into user (id,name,phone) values (#{
    
    id},#{
    
    name},#{
    
    phone})
    </insert>

如果主键值是通过MySQL自增机制生成的,此处可以不再显式的为id赋值

    <insert id="addUser" parameterType="com.hist.entity.User">
        insert into user (name,phone) values (#{
    
    name},#{
    
    phone})
    </insert>

在测试类中添加

    @Test
    public void testAddUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User(4,"周六","15936537150");
        int i = mapper.addUser(user);
        System.out.println(i);
        //提交事务,重点!不写的话不会提交到数据库
        session.commit(); 
        session.close();
    }

5. 修改用户

在UserMapper中添加

/**
 *功能描述: 用户修改
 * @param user 待修改的用户信息
 * @return int
*/
int updateUser(User user);

在UserMapper.xml中添加update语句

<update id="updateUser" parameterType="com.hist.entity.User">
    update user set name=#{name},phone=#{phone} where id = #{id}
</update>

在测试类中添加

    @Test
    public void testUpdateUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setId(1);
        user.setName("李思思");
        user.setPhone("12345678910");
        int i = mapper.updateUser(user);
        System.out.println(i);
        // 提交事务
        session.commit();
        session.close();
    }

6. 删除用户

在UserMapper中添加

    /**
     *功能描述: 删除用户
     * @param id 待删除用户id
     * @return int
    */
    int deleteUser(int id);

在UserMapper.xml中添加delete语句

    <delete id="deleteUser" parameterType="int">
      delete from user where id = #{id}
    </delete>

在测试类中添加

    @Test
    public void testDeleteUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int i = mapper.deleteUser(5);
        System.out.println(i);
        //提交事务,重点!不写的话不会提交到数据库
        session.commit(); 
        session.close();
    }

四、配置解析

1. mybatis-config.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>
    <!-- 配置mybatis的环境信息 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置JDBC事务控制,由mybatis进行管理 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源,采用传统的javax. sql. DataSource规范中的连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 映射器 : 定义映射SQL语句文件 -->
    <mappers>
        <mapper resource="com/hist/dao/UserMapper.xml"/>
    </mappers>
</configuration>

dataSource 有三种内建的数据源类型

type="[UNPOOLED|POOLED|JNDI]"
  • unpooled:这个数据源的实现只是每次被请求时打开和关闭连接。

  • pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。

  • jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

  • 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…

的用法

<!-- 1. 使用相对于类路径的资源引用 -->
<mappers>
 <mapper resource="com/hist/dao/UserMapper.xml"/>
</mappers>

<!-- 不使用
2. 使用完全限定路径 
-->
<mappers>
 <mapper url="F:\teach\project\mybatis-01\src\main\java\com\hist\dao\UserMapper.xml"/>
</mappers>

<!--
3. 使用映射器接口实现类的完全限定类名
需要mapper接口和mapper映射文件称相同,且放到同一个目录下
-->
<mappers>
 <mapper class="com.hist.dao.UserMapper"/>
</mappers>

<!-- 推荐使用
4. 将包内的映射器接口实现全部注册为映射器
需要mapper接口和mapper映射文件称相同,且放到同一个目录下
-->
<mappers>
 <package name="com.hist.dao"/>
</mappers>

2. Mapper文件

<?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.hist.mapper.UserMapper">
   
</mapper>

当namespace绑定接口后,不用写接口实现类,mybatis会通过该绑定自动帮你找到对应要执行的SQL语句

namespace中文意思:命名空间:

  • namespace的命名必须跟某个接口同名

  • 接口中的方法与映射文件中sql语句id应该一一对应

<select id="selectUser" resultType="com.hist.entity.User">
    select * from user
</select>
  • namespace命名规则 : 包名+类名

3. properties数据库文件配置

properties数据库文件配置,设置为外部配置可替换

新建一个db.properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&useUnicode=true&characterEncoding=utf8
username=root
password=123456

修改mybatis-config.xml

img

4. typeAliases

别名是使用是为了在映射文件中,更方便的去指定参数和结果集的类型,不再用写很长的一段全限定名。

img

img

5. Log4j配置

对于以往的开发过程,我们会经常使用到debug模式来调节,跟踪我们的代码执行过程。但是现在使用Mybatis是基于接口,配置文件的源代码执行过程。因此,我们必须选择日志工具来作为我们开发,调节程序的工具。

  • Log4j是Apache的一个开源项目

  • 通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…

  • 我们也可以控制每一条日志的输出格式;

  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

使用步骤:

1、导入log4j的包

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

2、配置文件编写

日志级别在开发阶段设置成DEBUG,在生产阶段设置成INFO或者ERROR。

Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来,也是说大于等于的级别的日志才输出

# 全局日志配置
log4j.rootLogger=WARN, stdout
# MyBatis 日志配置,打印一组映射器的日志,只需要打开映射器所在的包的日志功能即可
log4j.logger.com.hist.dao.UserMapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3、setting设置日志实现

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

4 在程序中使用Log4j进行输出!

public class UserTest {
    
    
    static Logger logger = Logger.getLogger(UserTest.class);
    @Test
    public void selectUser() {
    
    
        logger.info("info:进入selectUser方法");
        logger.debug("debug:进入selectUser方法");
        logger.error("error: 进入selectUser方法");
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> users = mapper.selectUser();

        for (User user : users) {
    
    
            System.out.println(user);
        }
        session.close();
    }
}

五、ResultMap结果集映射

解决实体类属性名与数据库表的字段名不一致

场景还原

创建一个User1实体类

public class User1 {
    
    
    private int id;
    private String name;
    private String number; // 手机号与数据库中的不一样
   //构造方法
   //set/get
   //toString()
}

创建一个接口

 /**
     * 功能描述: 通过id查询用户
     *
     * @param id 用户id
     * @return com.hist.module.User
     */
    User1 selectUser1ById(int id);

创建一个查询语句

<select id="selectUser1ById" parameterType="int" resultType="com.hist.entity.User1">
    SELECT * FROM USER WHERE id = #{id}
</select>

测试

    @Test
    public void testSelectUser1ById() {
    
    
        SqlSession session = MybatisUtil.getSession();  //获取SqlSession连接
        UserMapper mapper = session.getMapper(UserMapper.class);
        User1 user = mapper.selectUser1ById(1);
        System.out.println(user);
        session.close();
    }

运行结果

img

分析:

  • select * from user where id = #{id} 可以看做
    select id,name,phone from user where id = #{id}

  • mybatis会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写) , 去对应的实体类中查找相应列名的set方法设值 , 由于找不到setPhone() , 所以number返回null ; 【自动映射】

解决方案

  1. 在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配
<select id="selectUser1ById" parameterType="int" resultType="com.hist.entity.User1">
  select
    id,
    name,
    phone as number
  from user
  where id = #{id}
</select>
  1. 使用结果集映射->ResultMap
<resultMap id="UserMap" type="com.hist.entity.User1">
    <!-- id为主键 -->
    <id column="id" property="id"/>
    <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
    <result column="name" property="name"/>
    <result column="phone" property="number"/>
</resultMap>
<select id="selectUser1ById" parameterType="int" resultMap="UserMap">
    SELECT * FROM USER WHERE id = #{id}
</select>

六、Lombok使用(推荐)

https://zhuanlan.zhihu.com/p/146659383

1、IDEA安装Lombok插件

2、引入Maven依赖

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.16.10</version>
</dependency>

3、在代码中增加注解

@Data //GET,SET,ToString,有参,无参构造
public class Teacher {
    
    
   private int id;
   private String name;
}

七、注解实现增删改查

1. 查

 /**
     * 功能描述: 查询用户集合
     *
     * @return java.util.List<com.hist.module.User>
     */
    @Select("select * from user")
    List<User> selectUser();

在mybatis的核心配置文件中注入

<!--使用class绑定接口-->
<mappers>
   <mapper class="com.hist.dao"/>
</mappers>

测试

    @Test
    public void selectUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> users = mapper.selectUser();

        for (User user : users) {
    
    
            System.out.println(user);
        }
        session.close();
    }

2. 增

改造MybatisUtils工具类的getSession( ) 方法,重载实现。

public static SqlSession getSession(){
    
    
    //事务自动提交
    return sqlSessionFactory.openSession(true);
}

编写接口新增方法

//添加一个用户
@Insert("insert into user (id,name,phone) values (#{id},#{name},#{phone})")
int addUser(User user);

测试

    @Test
    public void testAddUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User(5, "周六", "15936537150");
        int i = mapper.addUser(user);
        System.out.println(i);
        session.close();
    }

3. 删除

编写删除接口

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

测试

    @Test
    public void testDeleteUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int i = mapper.deleteUser(5);
        System.out.println(i);
        session.close();
    }

4. 修改

编写修改接口

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

测试

    @Test
    public void testUpdateUser() {
    
    
        SqlSession session = MybatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setId(1);
        user.setName("李2思");
        user.setPhone("12345678910");
        int i = mapper.updateUser(user);
        System.out.println(i);
        session.close();
    }

下一篇:

【SSM框架】Mybatis动态SQL
https://blog.csdn.net/qq_45696377/article/details/122268668

猜你喜欢

转载自blog.csdn.net/qq_45696377/article/details/122160827