Java-Mybatis(一): Mybatis框架、第一个Mybatis程序以及CRUD、Map初见

Java-Mybatis-01

学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV1NE411Q7Nx

学习资料:mybatis 参考文档 – https://mybatis.org/mybatis-3/zh/index.html

1、Mybatis框架

学习使用Mybatis框架, 我使用的开发环境是:JDK1.8、Mysql5.7、maven3.6.3、IDEA

Mybatis简介:

  • MyBatis 是一款优秀的持久层框架

  • 它支持自定义 SQL存储过程以及高级映射

  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

数据持久化:

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程

  • 内存:断电即失

  • 数据库 JDBC,IO 文件持久化

持久层

MVC三层架构中有 Model、View、Control。其中Model 代码架构有Dao层、Service层。Service层就是逻辑业务代码,去调用底层 dao。

持久层对应于我们的Dao层、Service层、Controller层。

  • 完成持久化工作的代码块。
  • 层界限十分明显

对于DAO这一层专注于处理数据库 sql 的操作。前面的 JDBC 涉及到数据库连接、加载、获取对象等重复性的工作,为了专注于只去修改sql语句,为了更加便捷,所以需要这个框架。

MyBatis的优点

  • 不用再去编写一堆JDBC代码,简单易学。框架。自动化

  • sql和代码的分离,增加了可维护性

  • 提供映射标签,支持对象与数据库的 ORM关系映射

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

回顾JDBC:JDBC 就是 Java Database Connectivity,用来规定客户端程序如何来访问数据库的应用程序接口。

具体步骤为:

  1. 加载数据库驱动
  2. 需要连接的数据库的用户和配置信息 URL
  3. 连接数据库,表示数据库对象 connection
  4. 创建执行SQL的 Statement 对象(会有SQL注入现象) 使用prepareStatement 进行预编译,防止SQL注入
  5. 执行sql
  6. 关闭连接

JDBC-demo

文件格式:

image-20220313160137514

原有的demo和格式:

image-20220313160311043

code:

package com.AL.lessom1;

import java.sql.*;

public class jdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");   //固定写法,加载驱动

        //2.用户信息和url。 url指网络地址,在这里指的就是具体数据库路径地址
        //useUnicode=true 支持中文编码  characterEncoding=utf8设置中文字符为utf8 useSSL=true 使用安全连接
        String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true"; //需要连接的数据库具体文件
        String username="root";  //用户名字
        String password="123456"; //用户密码

        //3.连接成功,数据库对象   connection就代表数据库了
        Connection connection = DriverManager.getConnection(url, username, password);

        //4.执行SQL的对象  Statement 表示执行SQL的对象,此时就相当于 school.student这个表
        Statement statement = connection.createStatement();
        //5.执行SQL的对象去执行 sql 可能存在结果,查看返回结果
        String sql="select * from student";
        ResultSet resultSet = statement.executeQuery(sql);
        while(resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));  //假如不知道数据类型,就用 getObject()
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("pwd"));
            System.out.println("sex="+resultSet.getObject("sex"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
            System.out.println("address="+resultSet.getObject("address"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("========================================");
        }
        //5.关闭连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

2、第一个Mybatis程序

2.1、Mybatis的准备工作

  • maven仓库
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>
  • maven依赖的 jar包:mysql驱动、mybatis、junit测试
    <!--导入依赖 -->
    <dependencies>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <!--mybatis -->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
  • 专注于处理数据库 sql。那么还需要搭建一个数据库

    CREATE DATABASE `mybatis`;
    USE `mybatis`;
    
    CREATE TABLE `user`(
    `id` INT(20) NOT NULL PRIMARY KEY,
    `name` VARCHAR(30) DEFAULT NULL,
    `pwd` VARCHAR(30) DEFAULT NULL
    )ENGINE=INNODB CHARSET=utf8;
    
    INSERT INTO `user`(`id`, `name`, `pwd`)
    VALUES (1,'鑫仔','123456'), (2,'天啊','123456'),(3,'好胖','123890')
    

2.2、创建Maven项目

1.创建一个普通的maven项目,没有maven模板。

2.删除src目录

3.导入maven依赖

4.创建一个子项目

在这里插入图片描述

此时的子项目 mybatis-01 会继承父项目中的 jar包,不用再次导入。

Mybatis框架的步骤:

  • 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
  • SqlSessionFactory 的实例需要通过SqlSessionFactoryBuilder 来得到。
  • 这个SqlSessionFactoryBuilder 是要在xml配置文件中进行配置 config, 然后才能去构建SqlSessionFactory 实例。
2.2.1 编写mybatis的核心配置文件

如下所示:在资源文件 resource 中的 xml文件中进行预定义配置 config,才能去构建 SqlSessionFactoryBuilder

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVl4X6Qf-1619585357962)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210322195840596.png)]

<?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">
<!--XML 配置文件或者预先定义的一个 config,去SqlSessionFactoryBuilder, 配置数据库,便于创建sqlSessionFactory实例-->
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;charsetEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    
    <!--关联映射文件-->
    <mappers>
        <mapper resource="com/AL/dao/UserMapper.xml"/>
    </mappers>
</configuration>
2.2.2、编写mybatis工具类

在这里我们预定义配置了mybatis-config.xml。我们是从 XML文件中去构建 SqlSessionFactory的实例。使用类路径下资源文件进行配置,即 String resource = “mybatis-config.xml”;

SqlSessionFactoryBuilder 从配置文件 mybatis-config.xml中 使用输入流InputStream 获得SqlSessionFactory,并中获取sqlsession。

InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

mybatis工具类:

package com.AL.utils;

import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

//import javax.annotation.Resources;
import org.apache.ibatis.io.Resources;
import java.io.InputStream;

// sqlSessionFactory --> sqlSession
public class MybatisUtils {

    // 创建这个sqlSessionFactory,是从资源文件resource中的去获得。
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            //利用mybatis第一步: 获取一个sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            /**  注意:不需要修改,是因为导入的包不正确.不是 import javax.annotation.Resources
             * 将ResourcesgetResourceAsStream(resource);改为
             * Resources.class.getResourceAsStream(resource);
             *  //得到配置文件流
             * InputStream inputStream = Resources.class.getResourceAsStream(resource);
             */
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    public static SqlSession getSqlSession() {
        //SqlSession sqlSession = sqlSessionFactory.openSession();
        //return sqlSession;
        return sqlSessionFactory.openSession();
    }
}
2.2.3、实体类

编写实体类。实体类 class中的属性对应着 数据库 mybatis.user中的字段, 即 id,name, pwd

package com.AL.pojo;

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

    public User() {
    }
    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
    public 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 String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

2.2.4、Dao接口
package com.AL.dao;

import com.AL.pojo.User;
import java.util.List;

public interface UserDao {
    // 获取全部的用户
    List<User> getUserList();
}
2.2.5、Mapper配置文件

接口实现类:sql语句功能。

接口实现类由原来的 UserDaoImpl转变为一个 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">
<!--namespace= 绑定一个对应的Dao/Mapper接口
<mapper namespace="org.mybatis.example.BlogMapper">
    <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
-->
<mapper namespace="com.AL.dao.UserDao">
    <!--select 查询语句 -->
    <select id="getUserList" resultType="com.AL.pojo.User">
    select * from mybatis.user
  </select>
</mapper>
2.2.6、测试代码

在测试的里面,我们也建立和main中的java 对应的结构,这样更加规范:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wsivIq32-1619585357966)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210322201109778.png)]

package com.AL.dao;

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

import java.util.List;

public class UserDaoTest {
    @Test
    public void test(){
        //1.拿到sqlSessionFactory对象
        //SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
        //2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
        //SqlSession sqlSession = sqlSessionFactory.openSession();
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //4.通过mapper对象来执行操作;
        List<User> userList = userDao.getUserList();

        //获得结果集
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭sqlSession
        sqlSession.close();
    }
}
2.2.7、结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sUUR4yYX-1619585357967)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210322201516685.png)]

发现错误:

org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/AL/dao/UserMapper.xml
    .......
Caused by: java.io.IOException: Could not find resource com/AL/dao/UserMapper.xml

可以发现是这个资源无法找到。

很明显是Could not find resource com/xxx/xxx/Xxx.xml的错误。本人使用的是idea编译器,在idea中是不会编译src的java目录的xml文件,所以在Mybatis的配置文件中找不到xml文件!(也有可能是Maven构建项目的问题)。

资源配置导出出现了问题,所以在 pom.xml文件中进行添加配置资源导出:

    <build>
        <!--希望maven在导出项目的时候,能够将我们的配置及资源导出-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

关于作用域和生命周期的问题

自己在学习的时候,会发现

  • private static SqlSessionFactory sqlSessionFactory; // 静态变量

    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

  • public static SqlSession getSqlSession() {
        //SqlSession sqlSession = sqlSessionFactory.openSession();
        //return sqlSession;
        return sqlSessionFactory.openSession();
    }
    

为什么这么写呢? https://mybatis.org/mybatis-3/zh/getting-started.html

不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

  • 依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。

  • SqlSessionFactoryBuilder

    这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。

  • SqlSessionFactory

    SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式

  • SqlSession

    每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 finally。

3、CRUD

增删查改实现:只需要修改三个地方

  1. 编写接口
  2. 编写接口对应的mapper中的sql语句
  3. 测试,编写对应的CRUD方法 对应的测试方法。

接口 Dao/mapper: 在这里定义想要完成某个sql功能的方法名和参数
在这里插入图片描述

接口实现类: xml配置文件, 在这里完成sql功能的方法的具体实现。
其中的namespace = 绑定的一个接口 dao/mapper。
id对应着 接口中的方法名; resultType是返回的类型。

在这里插入图片描述

接口实现类中的 namespace中的包名, 要和接口 Dao/mapper中的包名一致。如下方代码所示:

<mapper namespace="com.AL.dao.UserDao">
    <!--select 查询语句 -->
    <select id="getUserList" resultType="com.AL.pojo.User">
    select * from mybatis.user
  </select>
</mapper>

上述的xml中的代码分析:

  • select:sql中的查询语句。
  • id:对应着namespace中的包名的方法名。 对应着此时的接口中的某个方法
  • resultType: sql语句执行的返回值。是这个数据库 mybatis.user,是一个User类,里面包含了表格的字段(属性): id /name/pwd

3.1、查找指定id用户

通过指定的id进行查找用户: 在这里,为了 更好的映射,我将 userDao接口改成了 userMapper接口

3.1.1、接口代码的修改:
package com.AL.dao;

import com.AL.pojo.User;
import java.util.List;

public interface UserMapper {
    // 获取全部的用户
    List<User> getUserList();
    // 根据ID查找用户
    User getUserById(int id);
}
3.1.2、mapper中的sql语句

接口实现类:编写对应的sql语句.

  • id:对应着Mapper接口中的方法名,此时增加了一个 getUserId方法,

  • resulttype: sql语句返回的值,是这个数据库 mybatis.user,是一个User类,里面包含了表格的属性: id /name/pwd

  • parameterType: 参数类型, 即数据库中的参数,即User类中的参数,属性. 如果是 int类型,可以不用写这个

    <?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= 绑定一个对应的Dao/Mapper接口
    <mapper namespace="org.mybatis.example.BlogMapper">
        <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
    -->
    <mapper namespace="com.AL.dao.UserMapper">
        <!--select 查询语句 -->
        <select id="getUserList" resultType="com.AL.pojo.User">
        select * from mybatis.user
      </select>
    
        <select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
        select * from mybatis.user where id = #{id}
      </select>
    
    </mapper>
    
3.1.3、测试

测试代码中, 对接口中的sql语句,进行对应的方法测试。 这里增加的是getUserById方法。

package com.AL.dao;

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

import java.util.List;

public class UserDaoTest {
    @Test
    public void test(){
        //1.拿到sqlSessionFactory对象
        //SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
        //2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //4.通过mapper对象来执行操作;
        List<User> userList = userMapper.getUserList(); //查询全部用户

        //获得结果集
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭sqlSession
        sqlSession.close();
    }
    @Test
    public void getUserById(){
        //1.拿到sqlSessionFactory对象
        //2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //4.通过mapper对象来执行操作;
        User userById = userMapper.getUserById(1);

        //获得结果
        System.out.println(userById);
        //关闭sqlSession
        sqlSession.close();
    }
}

#{}和${}的区别是什么?

  • ** 是 P r o p e r t i e s ⽂ 件 中 的 变 量 占 位 符 ∗ ∗ , 它 可 以 ⽤ 于 标 签 属 性 值 和 s q l 内 部 , 属 于 静 态 ⽂ 本 替 换 , ⽐ 如 {} 是 Properties ⽂件中的变量占位符**,它可以⽤于标签属性值和 sql 内部,属于静态⽂本替换,⽐如 Propertiessql{driver}会被静态替换为 com.mysql.jdbc.Driver 。

  • **#{} 是 sql 的参数占位符,**Mybatis 会将 sql 中的 #{} 替换为?号,在 sql 执⾏前会使⽤PrepareStatement 的参数设置⽅法,

    按序给 sql 的?号占位符设置参数值,⽐如 ps.setInt(0, parameterValue), #{item.name} 的取值⽅式为使⽤反射从参数对象中获取item 对象的 name 属性值,相当于 param.getItem().getName() 。

  • #{}是预编译处理,${}是字符串替换

    1、Mybatis 在处理 #{} 时,会将 SQL 中的 #{} 替换为 ? 号,调用 PrepareStatement 的 set 方法来赋值;使用 #{} 可以有效的防止 SQL 注入,提高系统安全性

    2、Mybatis在处理 ${} 时,

    ​ 就是把 ${} 替换成变量的值。

3.2、增删改

3.2.1、接口代码的修改
package com.AL.dao;

import com.AL.pojo.User;
import java.util.List;

public interface UserMapper {
    // 获取全部的用户
    List<User> getUserList();
    
    // 根据ID查找用户
    User getUserById(int id); //依据的是 id,所以用 int id
    
    //insert 一个用户
    int addUser(User user); //插入一个用户,即插入了一个完整的实例 class,对象,所以用 user
    
    //修改一个用户
    int updateUser(User user);
    //删除一个用户
    int deleteUser(int id);

}

3.2.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">
<!--namespace= 绑定一个对应的Dao/Mapper接口
<mapper namespace="org.mybatis.example.BlogMapper">
    <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
-->
<mapper namespace="com.AL.dao.UserMapper">
    <!--select 查询语句 -->
    <select id="getUserList" resultType="com.AL.pojo.User">
    select * from mybatis.user
  </select>
    
    <select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
    select * from mybatis.user where id = #{id}
  </select>

    <!--对象中的属性,可以直接取出来。 如id name -->
    <insert id="addUser" parameterType="com.AL.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id},#{name}, #{pwd});
</insert>

    <update id="updateUser" parameterType="com.AL.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>
3.2.3、测试
package com.AL.dao;

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

import java.util.List;

public class UserDaoTest {
    @Test
    public void test(){
        //1.拿到sqlSessionFactory对象
        //SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
        //2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //4.通过mapper对象来执行操作;
        List<User> userList = userMapper.getUserList(); //查询全部用户

        //获得结果集
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭sqlSession
        sqlSession.close();
    }
    @Test //查询
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User userById = userMapper.getUserById(1);

        //获得结果
        System.out.println(userById);
        //关闭sqlSession
        sqlSession.close();
    }

    @Test //插入
    public void addUser(){
        //1.拿到sqlSessionFactory对象
        //2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //4.通过mapper对象来执行操作;
        int res = userMapper.addUser(new User(4,"the shy","123456"));
        if (res>0){
            System.out.println("我插入成功了啊");
        }
        //提交事务
        //提交事务
        //提交事务
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
    }
    @Test //更新
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        userMapper.updateUser(new User(4, "jack", "978654321"));

        sqlSession.commit(); //提交事务
        sqlSession.close();
    }

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

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        userMapper.deleteUser(4);

        sqlSession.commit(); //提交事务
        sqlSession.close();
    }
}

3.3、总结

在Mybatis框架中,其实dao接口中的一个方法,对应着接口实现类xml中的 id 方法名, 一个xml 语句 具体实现,即 id,parameter,result. 然后对应着测试里面的一个方法(这里面用于测试CRUD),去完成CRUD的工作。

注意点:

  • 所有的增删改,需要提交事务sqlSession.commit()

  • 在接口中,注意类型 parameterType, 这个其实在对应的 mapper文件中,写sql语句时也有对应, 在@Test方法中,返回的类型也对应。

    // 查询指定Id的用户
    User getUserById(int id); //依据的是 id,所以用 int id
    
    //insert 一个用户
    int addUser(User user); //插入一个用户,即插入了一个完整的实例 class,对象,所以用 user
    
  • 标签需要一致, 即接口中的(Mapper)方法插入/修改,需要在接口实现类,(xml文件)中的sql语句里面的 要对应为 inesrt/update 对应起来.

  • namesapce + id=“getUserList” 去构成全限定名,匹配对应的类、方法。

  • 参数类型和返回类型:

    <select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
    

Mybatis框架的步骤

  1. pom.xml 配置文件。导入依赖的jar包, 以及防止maven资源配置文件导出失败的xml文件
  2. 编写mybatis的核心配置文件。在资源文件 resource 中的 xml文件中进行配置 SqlSessionFactoryBuilder.
  3. 编写mybatis工具类。 由SqlSessionFactoryBuilder来构建SqlSessionFactory 以及 session
  4. 实体类。 对应着数据库的表。 ORM关系映射
  5. Dao接口。
  6. Mapper配置文件。 sql语句,是接口实现类
  7. 测试代码。Dao接口、sql语句、测试方法都对应着。

4、Map和模糊查询扩展

4.1、万能Map

当我们的实体类,或者数据库中的表,字段或者参数多的时候,我们应该去考虑使用Map。这样我们就不用把每一个参数写出来,像下面这样:

insert into mybatis.user (id, name, pwd) values (#{id},#{name}, #{pwd});

万能的map:利用的是键值对. 只需要针对特定的,需要的参数 写出来, 不用全部都写出来。如:我们进行查询,只需要 id值, 且此时的参数类型不是 parameterType=“int” ,而是parameterType=“map”

    <select id="getUserById2" parameterType="map" resultType="com.AL.pojo.User">
    select * from mybatis.user where id = #{kkkid};
  </select>

对应的,在调用方法 getUserById2() 时,使用 kkkid这个映射的map键,向map中传递参数:

HashMap<String, Object> map = new HashMap<String, Object>();

map.put("kkkid", 1);
User userById2 = mapper.getUserById2(map);

利用map 进行 插入和查询的例子

1、接口mapper的代码修改:

package com.AL.dao;

import com.AL.pojo.User;

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

public interface UserMapper {
    // 获取全部的用户
    List<User> getUserList();

    // 根据ID查找用户
    User getUserById(int id); //依据的是 id,所以用 int id

    User getUserById2(Map<String,Object> map); // map

    //insert 一个用户
    int addUser(User user); //插入一个用户,即插入了一个具体的实例,对象,所以用 user
    // 万能的 Map
    int addUser2(Map<String,Object> map);
}

2.UserMapper.xml 修改:映射路径,sql语句

<mapper namespace="com.AL.dao.UserMapper">
    <!--select 查询语句 -->
    <select id="getUserList" resultType="com.AL.pojo.User">
    select * from mybatis.user
  </select>

    <select id="getUserById" parameterType="int" resultType="com.AL.pojo.User">
    select * from mybatis.user where id = #{id}
  </select>

    <select id="getUserById2" parameterType="map" resultType="com.AL.pojo.User">
    select * from mybatis.user where id = #{kkkid};
  </select>

    <!--对象中的属性,可以直接取出来。 如id name -->
    <insert id="addUser" parameterType="com.AL.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id},#{name}, #{pwd});
</insert>
    
    <insert id="addUser2" parameterType="map">
insert into mybatis.user (id, name, pwd) values (#{userid},#{userName},#{passWord});
    </insert>

</mapper>

3、测试代码修改:

package com.AL.dao;

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

import java.util.HashMap;
import java.util.List;

public class UserDaoTest {
    @Test
    public void test(){
        //1.拿到sqlSessionFactory对象
        //SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSession();
        //2.通过sqlSessionFactory对象openSession()创建一个sqlSession。
        //SqlSession sqlSession = sqlSessionFactory.openSession();
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //3.通过sqlSession获得mapper对象 , 参数为映射文件对应的接口类的class对象
        UserMapper userDao = sqlSession.getMapper(UserMapper.class);
        //4.通过mapper对象来执行操作;
        List<User> userList = userDao.getUserList();

        //获得结果集
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭sqlSession
        sqlSession.close();
    }

    @Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("userid", 5);
        map.put("userName", "clearlove");
        map.put("passWord", 77777);

        int res = mapper.addUser2(map);
        if (res>0){
            System.out.println("我插入成功了啊");
        }
        //提交事务
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
    }

    @Test
    public void getUserById2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Object> map = new HashMap<String, Object>();

        map.put("kkkid", 1);
        User userById2 = mapper.getUserById2(map);
        //获得结果
        System.out.println(userById2);

        sqlSession.close();
    }
}

注意:增删改的时候 一定要提交事务。否则完成不了sql 任务。

4.2、模糊查询

模糊查询的语法:

  1. Java代码执行的时候, 使用通配符 % %

    List<User> userList = mapper.getUserLike("%嗯%")
    
  2. SQL中,使用通配符 “%” “%”

    select * from mybatis.user where name like%#{value}“%”
    

例子:

1、接口 mapper代码:

//模糊查找用户
List<User> getUserLike(String s);

2.UserMapper.xml 修改:映射路径,sql语句

<select id="getUserLike" resultType="com.AL.pojo.User">
select * from mybatis.user where name like #{value}
</select>

3、测试代码修改:

    @Test
    public void getUserLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.getUserLike("%c%");

        for (User user : userList) {
            System.out.println(user);
        }
        //关闭sqlSession
        sqlSession.close();
    }

结果为:

User{id=4, name='jack', pwd='978654321'}
User{id=5, name='clearlove', pwd='77777'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值