Mybatis(1)

Mybatis

1.快速入门

请添加图片描述

2.Mybatis介绍

  1.MyBatis 在 java 和 sql 之间提供更灵活的映射方案

  2.mybatis 可以将对数据表的操作(sql,方法)等等直接剥离,写到 xml 配置文件,实现和 java代码的解耦

  3.mybatis 通过 SQL 操作 DB, 建库建表的工作需要自己完成

3.Mybatis工作示意图

在这里插入图片描述

4.MyBatis 快速入门

完成对 monster 表的 crud操作

4.1.1创建monster表

CREATE DATABASE `mybatis` CREATE TABLE `monster` 
`id` INT NOT NULL AUTO_INCREMENT, `age` INT NOT NULL, `birthday` DATE DEFAULT NULL, `email` VARCHAR(255) NOT NULL , `gender` TINYINT NOT NULL, `name` VARCHAR(255) NOT NULL, `salary` DOUBLE NOT NULL,
PRIMARY KEY (`id`)
) CHARSET=utf8

4.1.2 创建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>
    <!--配置mybatis自带的日志输出-查看原生的sql-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--配置别名-->
    <typeAliases>
        <typeAlias type="com.rjh.entity.Monster" alias="Monster"></typeAlias>
        <!--<typeAlias type="com.rjh.entity.Monk" alias="Monk"></typeAlias>-->
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <!--配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置数据源-->
            <dataSource type="POOLED">
                <!--配置连接url-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1111"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/rjh/mapper/MonsterMapper.xml"></mapper>
    </mappers>
</configuration>

4.1.3 创建pojo类

package com.rjh.entity;

import java.util.Date;

//要求这里的实体类属性要和表名字段保持一致
public class Monster {
    private Integer id;
    private Integer age;
    private String name;
    private String email;
    private Date birthday;
    private double salary;
    private Integer gender;

    public Monster() {
    }

    public Monster(Integer id, Integer age, String name, String email, Date birthday, double salary, Integer gender) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.email = email;
        this.birthday = birthday;
        this.salary = salary;
        this.gender = gender;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", birthday=" + birthday +
                ", salary=" + salary +
                ", gender=" + gender +
                '}';
    }
}

4.1.4 创建MonsterMapper接口

package com.rjh.mapper;

import com.rjh.entity.Monster;

import java.util.List;

//这是一个接口,该接口用于定义操作monster表的方法
//这些方法可以通过注解或者xml文件来实现
public interface MonsterMapper {

    public void addMonster(Monster monster);
    
    public void delMonster(Integer id);

    public void updateMonster(Monster monster);
    
    public Monster getMonsterById(Integer id);
    
//    如果返回为集合,应该设置为集合包含的类型,而不是集合本身的类型
    public List<Monster> findAllMonster();
}

4.1.5 创建MonsterMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <!--namespace="com.rjh.mapper.MonsterMapper"
        说明本 mapper.xml 文件是用来 映射管理 MonsterMapper 接口,
        主要是去实现 MonsterMapper 接口声明方法
        namespace指定该xml文件和哪一个接口对应
-->
        <!--select: 实现一个查询操作 insert:表示一个添加操作-->
        <!--id="addMonster" 表示 MonsterMapper 接口 的方法名-->
        <!--resultType="xx" 返回的结果类型,如果没有就不需要写-->
        <!--parameterType="com.rjh.entity.Monster" 表示该方法输入的形参类型,com.rjh.entity.Monster可以简写-->
        <!--(age,birthday,email,gender,name,salary) 表的字段名-->
        <!--#{age},#{birthday},#{email},#{gender},#{name},#{salary} 是实体类 Monster 的属性-->
<mapper namespace="com.rjh.mapper.MonsterMapper">
    <insert id="addMonster" parameterType="com.rjh.entity.Monster" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO monster (age,birthday,email,gender,name,salary)
        VALUES(#{age},#{birthday},#{email},#{gender},#{name},#{salary})
    </insert>

    <delete id="delMonster" parameterType="java.lang.Integer">
        delete from monster where id = #{id}
    </delete>

    <update id="updateMonster" parameterType="Monster">
        update monster set age=#{age},birthday=#{birthday},email=#{email},
        gender=#{gender},name=#{name},salary=#{salary} where id=#{id}
    </update>

    <select id="getMonsterById" parameterType="java.lang.Integer" resultType="Monster">
        select * from monster where id=#{id};
    </select>

    <select id="findAllMonster" resultType="Monster">
        select * from monster;
    </select>

</mapper>

4.1.6 mybatis-config.xml 引入Mapper.xml 文件

<mappers>
        <mapper resource="com/rjh/mapper/MonsterMapper.xml"></mapper>
</mappers>

4.1.6 创建SqISession工具类

package com.rjh.util;

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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;


// 1.获得 SqISession 的实例
// 2.SqlSession 提供了对数据库执行 SQL 命所需的所有方法 3.通过 SqISession 实例来直接执行已映射的 SQL 语句

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
//            指定资源文件,配置文件mybatis-config.xml
            String resource="mybatis-config.xml";
//            加载文件时,默认到resource目录—->运行后的工作目录classes
            InputStream inputStream= Resources.getResourceAsStream(resource);
            sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//    编写方法:返回sqlsession对象-会话
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

4.1.7 创建测试类

package com.rjh.mapper;

import com.rjh.entity.Monster;
import com.rjh.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;

import java.util.Date;
import java.util.List;

public class MonsterMapperTest {
    private SqlSession sqlsession;
    private MonsterMapper monsterMapper;
//    当方法使用before注解,表示在执行目标测试方法前,会先执行该方法
    @Before
    public void init() throws Exception {
    //通过 SqlSessionFactory 对象获取一个 SqlSession 会话
        sqlsession = MyBatisUtils.getSqlSession();
    //获取 MonsterMapper 接口对象, 该对象实现了 MonsterMapper
         monsterMapper = sqlsession.getMapper(MonsterMapper.class);
//         class com.sun.proxy.$Proxy7动态代理对象
//        System.out.println(monsterMapper.getClass());
    }

    @Test
    public void t1(){
        System.out.println("t1");
    }
    
    @Test
    public void addMonster(){
        for(int i=0;i<1;i++){
            Monster monster=new Monster();
            monster.setAge(10);
            monster.setBirthday(new Date());
            monster.setEmail("123@qq");
            monster.setGender(0);
            monster.setName("牛魔王2");
            monster.setSalary(2000);
            monsterMapper.addMonster(monster);
            System.out.println("添加对象"+monster);
        }
//        如果是增删改,需要提交
        if(sqlsession!=null){
            sqlsession.commit();
            sqlsession.close();
        }
        System.out.println("添加成功");
    }
    
    @Test
    public void deleteMonster(){
        monsterMapper.delMonster(7);
        if(sqlsession!=null){
            sqlsession.commit();
            sqlsession.close();
        }
        System.out.println("删除成功");
    }
    
    @Test
    public void updateMonster(){
        Monster monster=new Monster();
        monster.setAge(20);
        monster.setBirthday(new Date());
        monster.setEmail("234@qq");
        monster.setGender(1);
        monster.setName("孙悟");
        monster.setSalary(200);
        monster.setId(8);
        monsterMapper.updateMonster(monster);
        if(sqlsession!=null){
            sqlsession.commit();
            sqlsession.close();
        }
        System.out.println("更新成功");
    }

    @Test
    public void getMonsterById(){
        Monster monster= monsterMapper.getMonsterById(8);
        System.out.println(monster);
        if(sqlsession!=null){
            sqlsession.close();
        }
        System.out.println("通过id查询成功");
    }
    
    @Test
    public void findAllMonster(){
        List<Monster> allMonster = monsterMapper.findAllMonster();
        for (Monster monster : allMonster) {
            System.out.println(monster);
        }
        if(sqlsession!=null){
            sqlsession.close();
        }
        System.out.println("查询成功");
    }
}

5.日志输出-查看 SQL

在mybatis-config.xml文件里添加下面的语句

<!--配置mybatis自带的日志输出-查看原生的sql-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

6.原生的 API&注解方法

使用 MyBatis 原生的 API 完成,就是直接通过SqlSession 接口的方法来完成


public class sqlsessionTest {
    private SqlSession sqlsession;
    
    @Before
    public void init() throws Exception {
        //通过 SqlSessionFactory 对象获取一个 SqlSession 会话
        sqlsession = MyBatisUtils.getSqlSession();
    }
    
    @Test
    public void myBatisNativeCrud(){
        Monster monster = new Monster();
        monster.setAge(200);
        monster.setBirthday(new Date());
        monster.setEmail("100@sohu.com");
        monster.setGender(2);
        monster.setName("白骨精");
        monster.setSalary(9234.89);
        sqlsession.insert("com.rjh.mapper.MonsterMapper.addMonster",monster);

        if (sqlsession != null) {
           sqlsession.commit();
         sqlsession.close();
        }

=======================delete==========================
        sqlsession.delete("com.rjh.mapper.MonsterMapper.delMonster",12);
        if (sqlsession != null) {
           sqlsession.commit();
           sqlsession.close();
       }

//===========update start======================
        Monster monster = new Monster();
        monster.setAge(300);
        monster.setBirthday(new Date());
        monster.setEmail("tn100@sohu.com");
		monster.setGender(2);
        monster.setName("狮驼国妖精");
        monster.setSalary(9234.89);
        monster.setId(7);
        sqlsession.update("com.hspedu.mapper.MonsterMapper.updateMonster", monster);
       if (sqlsession != null) {
           sqlsession.commit();
           sqlsession.close();
       }
//===========update end======================

        //=========select start=================
        List<Monster> monsterList =
                sqlsession.selectList("com.rjh.mapper.MonsterMapper.findAllMonster");
        for (Monster monster1 : monsterList) {
            System.out.println(monster1);
        }
    }
}

6.MyBatis-注解的方式操作sql

6.1 创建MonsterAnnotation接口,添加注解


public interface MonsterAnnotation {
    @Insert("INSERT INTO monster (age,birthday,email,gender,name,salary) " +
            "VALUES(#{age},#{birthday},#{email},#{gender},#{name},#{salary}")
    public void addMonster(Monster monster);

    @Delete("delete from monster where id=#{id}}")
    public void delMonster(Integer id);

    //修改 Monster
    @Update("UPDATE monster SET age=#{age}, birthday=#{birthday}, "
            + "email = #{email},gender= #{gender}, "
            + "name=#{name}, salary=#{salary} " + "WHERE id=#{id}")
    public void updateMonster(Monster monster);

    //查询-根据 id
    @Select("SELECT * FROM monster WHERE " + "id = #{id}")
    public Monster getMonsterById(Integer id);
    //查询所有的 Monster
    @Select("SELECT * FROM monster ")
    public List<Monster> findAllMonster();
}

6.2 修改mybatis-config.xml , 对 MonsterAnnotaion 进行注册

<mappers>
<!-- 这里会引入我们的 Mapper.xml 文件 -->
<mapper resource="com/hspedu/mapper/MonsterMapper.xml"/>
<!--解读
1. 如果是通过注解的方式,可以不使用 MonsterMapper.xml
2. 但是需要在 mybatis-config.xml 注册含注解的类
-->
<mapper class="com.rjh.mapper.MonsterAnnotation"/>

在这里插入图片描述

6.3 添加测试类

public class MonsterAnnotationTest {
    private SqlSession sqlSession;
    private MonsterAnnotation monsterAnnotation

    @Before
    public void init() throws Exception {
        sqlSession = MyBatisUtils.getSqlSession();
    }
  

    @Test
    public void addMonster() {
        Monster monster = new Monster();
        monster.setAge(500);
        monster.setBirthday(new Date());
        monster.setEmail("1235@sohu.com");
        monster.setGender(2);
        monster.setName("白虎精");
        monster.setSalary(9234.89);
        monsterAnnotation = sqlSession.getMapper(MonsterAnnotation.class);
        monsterAnnotation.addMonster(monster);
        //增删改,需要提交事务
        if (sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }
        System.out.println("操作成功");

        Monster monsterById = monsterAnnotation.getMonsterById(10);
        System.out.println(monsterById);

    }
}

6.4 org.apache.ibatis.binding.BindingException:

sql语句问题或者是config.xml没有导入注解相关配置

6.5 注意事项和说明:

  1. 如果是通过注解的方式,就不再使用 MonsterMapper.xml文件 ,但是需要在mybatis-config.xml 文件中注册含注解的类/接口

  2.使用注解方式,添加时, 如果要返回自增长id值,可以使用@Option注解,组合使用

@Insert("INSERT INTO monster (age,birthday,email,gender,name,salary) VALUES(#{age},#{birthday},#{email},#{gender},#{name},#{salary})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public void addMonster(Monster monster);

在这里插入图片描述

7.mybatis-config.xml-配置文件详解

mybatis 的核心配置文件(mybatis-config.xml),比如配置 jdbc 连接信息,注册 mapper
等等

在这里插入图片描述

7.1 properties 属性

通过该属性可以指定一个外部的 jdbc.properties 文件,引入我们的 jdbc 连接信息
在这里插入图片描述

7.1 修改 mybatis-confing.xml

<!-- 这里就是引入 jdbc.properties 文件 -->
<properties resource="jdbc.properties"/>
 <environments default="development">
        <environment id="development">
            <!--配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置数据源-->
            <dataSource type="POOLED">
                <!--配置连接url-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

修改父项目的 pom.xml(如果已经配置了.properties 就不用再配置)
在这里插入图片描述

7.2 setting 属性

配置mybatis自带的日志输出-查看原生的sql,之前配置过一个
在这里插入图片描述

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

7.3 typeAliases 别名处理器

  1. 别名是为 Java 类型命名一个短名字。它只和 XML 配置有关,用来减少类名重复的部分

  2. 如果指定了别名,我们的 MappperXxxx.xml 文件就可以做相应的简化处理

  3.注意指定别名后,还是可以使用全名的

<typeAliases>
<!-- 如果一个包下有很多的类,我们可以直接引入包,这样
该包下面的所有类名,可以直接使用
-->
<package name="com.rjh.entity"/>
<!-- 为某个 mapper 指定一个别名, 下面可以在 XxxxxMapper.xml 做相应简化处理 -->
<!-- <typeAlias type="com.hspedu.entity.Monster" alias="Monster"/> -->
</typeAliases>

7.3 environments 环境

  1. resource 注册 Mapper 文件: XXXMapper.xml 文件(常用,使用过)
  2. class:接口注解实现(使用过)
  3. url:外部路径,使用很少,不推荐,
  4. package 方式注册 :< package name=“com.rjh.mapper”/> 并测试
<!-- 老韩解读
1. 当一个包下有很多的 Mapper.xml 文件和基于注解实现的接口时,
为了方便,我们可以以包方式进行注册
2. 将下面的所有 xml 文件和注解接口都进行注册
-->
<mappers>
<package name="com.rjh.mapper"/>
</mappers>

8. XxxxMapper.xml-SQL 映射文件

在sql语句中,能在parameterType和resultType因为在xml文件中配置了重命名,所以能写简写
在这里插入图片描述

8.1 XxxMapper.xml-基本介绍

  1.MyBatis 的真正强大在于它的语句映射(在 XxxMapper.xml 配置), 由于它的异常强大, 如 果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。 MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

  2.SQL 映射文件常用的几个顶级元素(按照应被定义的顺序列出)

  cache – 该命名空间的缓存配置。

  cache-ref – 引用其它命名空间的缓存配置。

  resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。

  parameterType - 将会传入这条语句的参数的类全限定名或别名

8.2 XXxxMapper.xml-详细说明

8.2.1 XXxxMapper.xml-传入 POJO 类型

案例 1:请查询 id = 1 或者 name = ‘白骨精’ 的妖怪
案例 2:请查询 name 中 包含 “牛魔王” 的妖怪

//通过 id 或者名字查询
public List<Monster> findMonsterByNameORId(Monster monster);
//查询名字中含义'精'妖怪
public List<Monster> findMonsterByName(String name);
  1. 修改 MonsterMapper.xml
<!-- 实现 findMonsterByNameORId -->

<select id="findMonsterByNameORId" parameterType="Monster" resultType="Monster">
   select * from monster where id=#{id} or name=#{name};
</select>

<!-- 看看模糊查询的使用 取值 需要 ${value} 取值-->

<select id="findMonsterByName" parameterType="String" resultType="Monster">
   select * from monster where name like "%${name}%"
 </select>

  1. 修改 MonsterMapperTest.java,完成测试
    @Test
    public void findMonsterByNameORId(){
        Monster monster=new Monster();
        monster.setName("白虎精");
        monster.setId(10);
        List<Monster> list = monsterMapper.findMonsterByNameORId(monster);
        for(Monster monster1:list){
            System.out.println(monster1);
        }
        if(sqlsession!=null){
            sqlsession.close();
        }
    }

    @Test
    public void findMonsterByName(){
        List<Monster> list = monsterMapper.findMonsterByName("精");
        for(Monster m:list){
            System.out.println(m);
        }
          if(sqlsession!=null){
            sqlsession.close();
        }

在这里插入图片描述
在这里插入图片描述

8.2.2 XXxxMapper.xml-传入 HashMap

要求:声明一个方法,按传入参数是 HashMap 的方式,查询 id > 10 并且 salary 大于 40
的所有妖怪

  1. 修改 MonsterMapper.java, 增加方法接口
public List<Monster> findMonsterByIdAndSalary_PrameterHashMap(Map<String, Object> map);
  1. 修改 MonsterMapper.xml
<select id="findMonsterByIdAndSalary_PrameterHashMap" parameterType="map" resultType="Monster">
        select * from monster where id> #{id} AND salary > #{salary};
</select>
  1. 修改 MonsterMapperTest.java 进行测试
@Test
    public void findMonsterByIdAndSalary_PrameterHashMap(){
        Map<String, Object> map=new HashMap<String,Object>();
        map.put("id",15);
        map.put("salary",95);
        List<Monster> list = monsterMapper.findMonsterByIdAndSalary_PrameterHashMap(map);
        for(Monster m:list){
            System.out.println(m);
        }
        if(sqlsession!=null){
            sqlsession.close();
        }
    }

在这里插入图片描述

8.2.3 XXxxMapper.xml-传入和返回都是HashMap

  1. 修改 MonsterMapper.java
    public List<Map<String,Object>> findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap(Map<String, Object> map);

  1. 修改 MonsterMapper.xml
<select id="findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap" parameterType="map" resultType="map">
      select * from monster where id > #{id} AND salary > #{salary};
 </select>
  1. 修改 MonsterMapperTest.java
@Test
    public void findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", 10);//条件
        map.put("salary", 900);
        List<Map<String, Object>> list = monsterMapper.findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap(map);
        for(Map<String,Object> map2:list){
            for (Map.Entry<String, Object> entry : map2.entrySet()) {
                System.out.println(entry.getKey() + "--" + entry.getValue());
        }
        if (sqlSession != null) {
			sqlSession.close();
		}
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值