MyBatis 入门

环境:

  • JDK1.8
  • Mysql 5.7
  • maven 3.6.1
  • IDEA

回顾:

  • JDBC
  • Mysql
  • Java基础
  • Maven
  • Junit

框架:最好的方式是看文档

一、简介

1.什么是MyBatis
  1. MyBatis 是一款优秀的持久层框架
  2. 它支持自定义 SQL、存储过程以及高级映射。
  3. MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  4. MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
什么是持久层?
  1. 数据持久化
    持久化就是将程序的数据在持久状态和瞬时状态转化的过程。
  2. 持久化方式
    数据库、io文件持久化
  3. 持久层就是完成持久化工作的代码块(Dao层)
2.获取MyBatis
  1. maven仓库
  2. Giuhub
3.为什么需要MyBatis
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql

二、第一个MyBatis程序

思路:搭建环境–>导入MyBatis–>编写代码–>测试

1.搭建环境

创建数据库
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 default charset=utf8;

insert into user values
(1,'大哥','123456'),
(2,'二哥','123457'),
(3,'三弟','234567');
新建项目
  1. 新建一个普通的maven项目。(用自己的maven)
  2. 删除src,作为父工程。
  3. 导入依赖:Mysql、MyBatis、Junit

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核心配置文件-->
<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;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>
编写MyBatis工具类

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用Mybatis获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
    public  static SqlSession getSqlSession(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
}
编写代码
  • 实体类
@Data
public class User {
    private int id;
    private String name;
    private  String pwd;

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
}
  • 接口
package com.dlc.dao;
public interface UserMapper {
    List<User> getUserList();
}
  • 接口实现类
    使用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">
<!--namespace 绑定一个对应的Mapper接口-->
<mapper namespace="com.dlc.dao.UserMapper">
    <!--id对应方法名,resultType返回一种类型,resultMap返回多个类型,使用全限定名-->
    <select id="getUserList" resultType="com.dlc.pojo.User">
        select * from user
    </select>
</mapper>
测试
  • junit测试
public class UserMapperTest {
    @Test
    public void test(){
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //方式一,getMapper:执行sql
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserList();
        //方式二:旧版不推荐
        //List<User> userList = sqlSession.selectList("com.dlc.dao.UserMapper.getUserList");
        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }
}

注意点org.apache.ibatis.binding.BindingException: Type interface com.dlc.dao.UserMapper is not known to the MapperRegistry.
需要在mybatis-config.xml中注册每一个xml。

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

此外,在pom.xml中,还需要在build里配置resources,以防止资源导出失败问题(因为要导出java/下的资源)。

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

三、CRUD

1.namespace

<mapper namespace="com.dlc.dao.UserMapper">
</mapper>

namespace的值要和对应mapper接口的全类名一致。

2.select

public interface UserMapper {
    //根据id查询用户
    User getUserById(int id);
}
<select id="getUserById" resultType="com.dlc.pojo.User" parameterType="int">
        select * from user where id = #{id}
</select>
  • id:就是对应namespace中的方法名;
  • resultType:sql语句执行的返回值
  • parameterType:参数类型

3.insert

public interface UserMapper {
    //插入一个用户
    int addUser(User user);
}
<!--    对象中的属性可以直接取出-->
    <insert id="addUser" parameterType="com.dlc.pojo.User">
        insert into user (id, name, pwd) values (#{id},#{name},#{pwd})
    </insert>

与查询不同的是,增删改之后需要提交事务,所以在测试类中应该这样写。

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

        userMapper.addUser(new User(4,"四叔","535626"));
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }

4.update

public interface UserMapper {
    //修改
    int updateUser(User user);
}
    <update id="updateUser" parameterType="com.dlc.pojo.User">
        update user set name=#{name},pwd=#{pwd} where id=#{id}
    </update>

5.delete

public interface UserMapper {
    //删除
    int deleteUser(int id);
}
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id}
    </delete>

6.万能的Map

假设我们的实体类或者数据库中表的字段或者参数过多,我们应当考虑使用map。(属于野路子)
同时也是一种传入多个参数的方式。
使用Map的话,在更新时可以不用每次都新建一个实体类然后给不需要修改的字段赋值,只需要放入要修改的字段即可。
以下以insert方法为例:

  • 接口:
    //插入一个用户2
    int addUser2(Map<String,Object> map);
  • 实现xml
<!--    传入一个map的添加用户法-->
    <insert id="addUser2" parameterType="map">
    	<!--不受实体类约束,可以随意设置字段名-->
        insert into user (id, name, pwd) values (#{userId},#{userName},#{passWord})
    </insert>
  • 测试方法
	@Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        Map<String,Object> map = new HashMap<String, Object>();
        map.put("userId",5);
        map.put("userName","五花肉");
        map.put("passWord","21343234");

        userMapper.addUser2(map);

        sqlSession.commit();
        sqlSession.close();
    }
总结
  1. Map传递参数,直接在sql中取出key即可;
  2. 对象传递参数,直接在sql中取对象的属性即可;
  3. 只有一个基本数据类型的情况下,可以直接在sql中取到。.

7.模糊查询

方式一:在test方法中传入带通配符的字符串(可能sql注入)
    //模糊查询
    List<User> getUserLike(String value);
<!--    模糊查询-->
    <select id="getUserLike" resultType="com.dlc.pojo.User" parameterType="string">
        select * from user where name like #{value}
    </select>
@Test
    public void getUserLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = userMapper.getUserLike("四%");
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.commit();
        sqlSession.close();
    }
    //User(id=4, name=四龙, pwd=535626)
	//User(id=5, name=四叔, pwd=32423423)
方式二:在sql中拼接%
<!--    模糊查询-->
    <select id="getUserLike" resultType="com.dlc.pojo.User" parameterType="string">
        select * from user where name like "%"#{value}"%"
    </select>

四、配置解析

1.核心配置文件

  • mybatis-config.xml
  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息
configuration(配置)
	properties(属性)
	settings(设置)
	typeAliases(类型别名)
	typeHandlers(类型处理器)
	objectFactory(对象工厂)
	plugins(插件)
	environments(环境配置)
		environment(环境变量)
			transactionManager(事务管理器)
			dataSource(数据源)
	databaseIdProvider(数据库厂商标识)
	mappers(映射器)

2.环境配置(environments)

MyBatis 可以配置成适应多种环境,尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。可通过<environments default="development">改变default的值选择。

(1)事务管理器(transactionManager)

在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]")

(2)数据源(dataSource)

有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]")

3.属性(properties)

可以通过properties属性来实现引用配置文件。

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。

  • 编写一个数据库配置文件db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8
username=root
password=123456
  • 引入这个配置文件
<?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核心配置文件-->
<configuration>
<!--    引入外部配置文件-->
    <properties resource="db.properties"/>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/dlc/dao/UserMapper.xml"/>
    </mappers>
</configuration>

如果在properties中有同名的<property>标签,优先使用配置文件的配置。

4.类型别名(typeAliases)

  • 类型别名可为 Java 类型设置一个缩写名字
  • 它仅用于 XML 配置,意在降低冗余的全限定类名书写
方式一

在mybatis-config.xml中添加:

    <typeAliases>
        <typeAlias type="com.dlc.pojo.User" alias="User"/>
    </typeAliases>

即可在mapper.xml中使用User来代替com.dlc.pojo.User。

方式二
<typeAliases>
        <package name="com.dlc.pojo"/>
</typeAliases>

每一个在包 com.dlc.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名
比如 com.dlc.pojo.User的别名就是user

在实体类比较少的时候,使用第一种方式
实体类多的时候使用第二种,且可以在实体类上使用@Alias指定别名来实现diy。

5.设置(settings)

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

6.其他配置

  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
    • mybatis-generator-core
    • mybatis-plus
    • 通用mapper

7.映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件

方式一:使用相对于类路径的资源引用

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

方式二:使用映射器接口实现类的完全限定类名

<mappers>
  <mapper class="com.dlc.dao.UserMapper"/>
</mappers>

方式二注意点:

  • 接口和实现xml文件必须同名
  • 接口和xml文件必须在同一包下。

8.生命周期和作用域

生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题
在这里插入图片描述
SqlSessionFactoryBuilder
一旦创建了SqlSessionFactory,就不再需要SqlSessionFactoryBuilder了。局部变量

SqlSessionFactory

  • 可以理解为:“数据库连接池”
  • 一旦被创建就应该在应用的运行期间一直存在,最佳作用域是应用作用域
  • 使用单例模式

SqlSession

  • 连接到连接池的一个请求
  • 最佳作用域是方法作用域
  • 用完之后需要关闭,否则资源被占用。

五、ResultMap 结果集映射

将User的属性中pwd改为password,这样属性名和字段名就不一致了。

从数据库中查询得到的User类便查不到password字段。

此时,返回的结果使用resultMap即可解决问题。

<!--    结果集映射-->
    <resultMap id="UserMap" type="User">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
    <select id="getUserById" resultMap="UserMap" parameterType="int">
        select * from user where id=#{id}
    </select>

column是数据库中的列字段,property是类的属性。

  • resultMap元素是MyBatis中最重要最强大的元素
  • ResultMap的设计思想是,对于简单的语句根本不需要配置显示的结果映射,而对于复杂一点的语句只需要去描述它们的关系就行了
  • ResultMap最优秀的地方在于,虽然你已经对它相当了解了,但是根本不需要显式地用到他们。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值