SSM之MyBatis 01 —— 第一个MyBatis程序、增删改查(模糊查询)

系列文章

SSM之MyBatis 01 —— 第一个MyBatis程序、增删改查(模糊查询)

SSM之MyBatis 02 —— 配置文件说明、日志工厂、分页(Limit和RowBounds)

SSM之MyBatis 03 —— 使用注解开发、Lombok、多对一&一对多处理

SSM之MyBatis 04 —— 动态SQL、缓存Cache



一、简介

1.1、什么是MyBatis

在这里插入图片描述

  • MyBatis 是一款优秀的持久层框架,支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名为MyBatis 。2013年11月迁移到Github

如何获得MyBatis:

  • maven仓库

    <!-- 目前最新是3.6.5 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
    
  • GitHub:https://github.com/mybatis/mybatis-3/releases

  • 官方手册:https://mybatis.org/mybatis-3/zh/index.html

1.2、持久层

为什么需要持久化?最主要是有一些对象需要长时间保存。

数据持久化:

  • 持久化就是将程序在持久状态和瞬时状态转化的过程
  • 像生活中,我们吃的罐头,就是将食物持久化,能保存更长时间
  • 内存是断电即失,因此我们可以将数据写入硬盘。
  • 目前持久化可以通过数据库(JDBC)、文件(IO)

持久层就是完成持久化的代码块,持久化是一个动作,而持久层是一种概念。

1.3、为什么需要MyBatis

  • 帮助程序猿将数据存入到数据库中
  • 简化传统的JDBC代码,使得操作数据库更加方便
  • MyBatis优点多:
    • 简单易学
    • 灵活
    • sql和代码分离,提高了可维护性
    • 提供映射标签,支持对象与数据库的orm字段关系映射
    • 提供对象关系映射标签,支持对象关系组建维护
    • 提供xml标签,支持编写动态sql

最重要的是使用MyBatis的人很多!!
 

二、第一个MyBatis程序

第一个MyBatis程序,在数据库新建一个用户表,通过MyBatis进行查询。

步骤:搭建环境、导入MyBatis、写代码、测试

目录结构

1613893506934

2.1、搭建环境

搭建数据库

CREATE DATABASE `mybatis`;

USE `mybatis`;

CREATE TABLE `user`(
	`id` INT(20)  NOT NULL,
	`name` VARCHAR(20) DEFAULT NULL,
	`password` VARCHAR(20) DEFAULT NULL,
	PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `user`(`id`,`name`,`password`) VALUES
(1, '小白', '123456'),
(2, '小红', '123456'),
(3, '小黑', '123456');

新建项目

1、创建普通maven项目

2、删除src目录

3、导入maven依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.2</version>
</dependency>

2.2、创建一个模块

1、直接创建一个普通maven模块

2、按照手册说的,写好MyBatis配置文件,放在resources目录下

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>
    <!-- 选择默认的数据库环境配置 -->
    <environments default="development">
        <!-- 可以设置多个环境 -->
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

3、编写MyBatis工具类

为了方便后面使用MyBatis,编写一个工具类是有必要的。

package 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 MyBatisUtils {
    
    
    private static SqlSessionFactory sqlSessionFactory;
    static {
    
    
        //引用前面的MyBatis配置文件,该文件放在resources目录下
        String resource = "mybatis-config.xml";

        try {
    
    
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
	//后续对数据库的操作都用Sqlsession类代替
    public SqlSession getSqlSession(){
    
    
        return sqlSessionFactory.openSession();
    }
}

2.3、编写代码

1、实体类

根据数据库的user表创建对应的实体类

package pojo;

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

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

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

    public void setPassword(String password) {
    
    
        this.password = password;
    }

    public int getId() {
    
    
        return id;
    }

    public String getName() {
    
    
        return name;
    }

    public String getPassword() {
    
    
        return password;
    }

    public User() {
    
    
    }

    public User(int id, String name, String password) {
    
    
        this.id = id;
        this.name = name;
        this.password = password;
    }
}

2、Dao接口(对比之前的smbms项目实践)

package com.zcy.dao;

import com.zcy.pojo.User;

import java.util.List;

//MyBatis中 不称Dao接口,而是用Mapper
public interface UserMapper {
    
    
    public List<User> getUserList();
}

3、接口实现类

由原来的UserDaoImpl.java,转变为一个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">
<!-- 绑定到UserMapper接口上 -->
<mapper namespace="com.zcy.dao.UserMapper">
	<!-- 返回类型是User -->
    <select id="getUserList" resultType="com.zcy.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

2.4、测试

使用Junit测试,在test目录下创建和java相同的目录结构,然后新建一个测试类。

package com.zcy.dao;

import com.zcy.pojo.User;
import com.zcy.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserMapperTest {
    
    
    @Test
    public void test(){
    
    
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        try{
    
    
            //方式一:已过时
            //List<User> userList = sqlSession.selectList("com.zcy.dao.UserMapper.getUserList");
            //方式二
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = userMapper.getUserList();

            for(User user : userList)
                System.out.println(user);
        }catch (Exception e){
    
    
            e.getStackTrace();
        }finally {
    
    
            sqlSession.close();
        }
    }
}

结果:

在这里插入图片描述

2.5、可能出现的错误

1、没有注册Mapper

1613893702294

解决:在mybatis-config.xml中注册对应的mapper,这里面的包的点要换成反斜杠,这是一个路径

<mappers>
    <mapper resource="com/zcy/dao/UserMapper.xml"/>
</mappers>

2、找不到UserMapper.xml

在这里插入图片描述

解决:IDEA的maven项目不会输出resources目录下的xml等资源,需要我们在pom.xml中设置,添加下列代码。

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
    <resources>
        <resource>
            <directory>${basedir}/src/main/webapp</directory>
        </resource>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
        </resource>
        <resource>
            <directory>${basedir}/src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

3、UserMapper.xml中的方法名或者类型不完整,namespace和resultType都需要完整路径。

<?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.zcy.dao.UserMapper">

    <select id="getUserList" resultType="com.zcy.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

三、CRUD 增删改查

1、分析UserMapper.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">
<mapper namespace="com.zcy.dao.UserMapper">

    <select id="getUserList" resultType="com.zcy.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

  • namespace:命名空间,将整个命名空间绑定到UserMapper接口,包名要和Dao/Mapper接口的包名一致

  • select:查询语句

    • id:对应于namespace中接口的方法名
  • resultType:Sql语句执行后的返回值类型

    • parameterType:对应方法里的参数类型(后面要用到)
  • #{ }里面放变量,如果参数类型是一个对象,则#{ }可以直接引用到该对象的成员
     

2、select、insert、update、delete标签

它们使用方法都一样

1、编写接口

package com.zcy.dao;

import com.zcy.pojo.User;

import java.util.List;

public interface UserMapper {
    
    
    //查询全部用户
    public List<User> getUserList();

    //通过ID查询用户
    public User getUserById(int id);
    //增加用户
    public int addUser(String name, String password);
    //更新用户
    public int updateUser(int id);
    //删除用户
    public int delete(int id);
}

2、编写对应mapper中的sql语句

<?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.zcy.dao.UserMapper">
    <select id="getUserList" resultType="com.zcy.pojo.User">
        select * from mybatis.user;
    </select>

    <select id="getUserById" parameterType="int" resultType="com.zcy.pojo.User">
        <!-- 这里#{id}是直接引用到User类的成员变量 -->
        select * from mybatis.user where id = #{id};
    </select>

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

    <update id="updateUser" parameterType="com.zcy.pojo.User">
        update mybatis.user set name=#{name}, passwod=#{passwod} where id = #{id};
    </update>

    <delete id="deleteUser" parameterType="com.zcy.pojo.User">
        delete from mybatis.user where id = #{id};
    </delete>
</mapper>

3、测试

增删改需要提交事务,才能修改数据库!!

package com.zcy.dao;

import com.zcy.pojo.User;
import com.zcy.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserMapperTest {
    
    

    @Test
    public void testDelete(){
    
    
        //固定写法
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //删除用户
        userMapper.deleteUser(3);

        //涉及到增删改都需要提交事务
        sqlSession.commit();
        List<User> userList = userMapper.getUserList();
        for(User u : userList)
            System.out.println(u);
        //固定写法
        sqlSession.close();
    }

    @Test
    public void testSelect(){
    
    
        //固定写法
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //通过ID查询用户
        User user = userMapper.getUserById(1);
        System.out.println(user);

        //固定写法
        sqlSession.close();
    }

    @Test
    public void testInsert(){
    
    
        //固定写法
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //增加新用户
        User user = new User(4, "新增用户", "111111");
        userMapper.addUser(user);

        //增删改必须提交事务,才能改变数据库
        sqlSession.commit();
        List<User> userList = userMapper.getUserList();
        for(User u : userList)
            System.out.println(u);
        //固定写法
        sqlSession.close();
    }

    @Test
    public void testUpdate(){
    
    
        //固定写法
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //更新用户
        User user = new User(1, "更新的用户", "123456");
        userMapper.updateUser(user);

        //增删改必须提交事务,才能改变数据库
        sqlSession.commit();
        List<User> userList = userMapper.getUserList();
        for(User u : userList)
            System.out.println(u);
        //固定写法
        sqlSession.close();
    }
}

也可以设置为自动提交,在获得SqlSession时,添加参数true。

public static SqlSession getSqlSession(){
    
    
    return sqlSessionFactory.openSession(true);
}

3、Map

在写mapper.xml的SQL语句时,我们有多种方式获取接口中方法的参数:

  1. 仅一个基本类型参数时,可直接省略

    接口中的方法 public User getUserById(int id);
    
    maaper中sql:省略 parameterType="int"
    <select id="getUserById" resultType="com.zcy.pojo.User">
        select * from mybatis.user where id = #{
          
          id};
    </select>
    
    
  2. 仅一个参数且是对象时,直接用类

接口中的方法 public int addUser(User user);

mapper中的sql:其中 id、name、password都是User类的同名成员变量,名字必须相同
<insert id="addUser" parameterType="com.zcy.pojo.User">
     insert into mybatis.user (id, name, password) values (#{
    
    id}, #{
    
    name}, #{
    
    password});
</insert>

更好的替代方式!用Map传递参数,取代对象传递参数!

接口中的方法:public int getUserById2(Map<String, Object> map);


mapper中的sql:不用成员变量来获取参数,而是用map的key(相当于可以自定义),并且不需要写完整的User成员
<select id="getUserById2" parameterType="map" resultType="com.zcy.pojo.User">
    select * from mybatis.user where id = #{
    
    userId} and name = #{
    
    userName};
</select>

    
测试类中的写法:
 @Test
public void getUserById2(){
    
    
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("userId",2);
    map.put("userName","小红");

    User user = userMapper.getUserById2(map);
    System.out.println(user);

    sqlSession.close();
}

  1. 多个参数时,用Map或者注解

4、模糊查询

方法一:在Java代码执行的时候,传递通配符% %

UserMapper.xml

<!-- 模糊 查询    -->
<select id="getUserLike" resultType="com.zcy.pojo.User">
    select * from user where name like #{
    
    value};
</select>

@Test
public void testSelectLike(){
    
    
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    List<User> userList = userMapper.getUserLike("%小%");
    for (User user : userList) {
    
    
        System.out.println(user);
    }

    sqlSession.close();
}

方法二:在mapper的sql中使用通配符
UserMapper.xml

<!-- 模糊 查询    -->
<select id="getUserLike" resultType="com.zcy.pojo.User">
    select * from user where name like "%" #{value} "%";
</select>

@Test
public void testSelectLike(){
    
    
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    List<User> userList = userMapper.getUserLike("小");
    for (User user : userList) {
    
    
        System.out.println(user);
    }

    sqlSession.close();
}

猜你喜欢

转载自blog.csdn.net/qq_39763246/article/details/113933038