• 首页

  • 图库

  • 分类

  • 随笔

  • 归档

  • 友链

  • 关于我
❤ 寸 劲 - 开 天 ❤
❤ 寸 劲 - 开 天 ❤

寸劲开天

获取中...

06
05
SSM

Mybatis 基础知识回顾!

发表于 2020-06-05 • 被 164 人看爆

简介

简化 JDBC,优秀的持久层框架

数据持久化

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

  • 内存:断电即失(内存贵,但是快)

  • 数据库(JDBC),io文件持久化。

  • 生活:冷藏、罐头

  • 为什么进行持久化:

    • 有一些对象,不能被丢掉
    • 内存太贵了
  • 持久层:

    • Dao层、Service层、Controller层.....
    • 完成持久化工作的代码块
    • 层界限十分明显

为什么使用 Mybatis

  • 帮助程序员将数据存入数据库中
  • 方便
  • 传统的 jdbc 代码太复杂,简化、框架、自动化
  • 不用 Mybatis 也可以,更容易上手,技术没有高低之分
  • 优点:
    • 与JDBC相比,减少了50%以上的代码量
    • 最简单的持久化框架、小巧简单易学
      SQL代码从程序代码中彻底分离出来,可重用
    • 提供XML标签,支持编写动态SQL
    • 提供映射标签,支持对象与数据库的ORM字段关系映射(半自动化 —— 需要人的干预指导)
  • 缺点:
    • SQL语句编写工作量大,熟练度要高
    • 数据库移植性差,比如mysql移植到Orecle,SQL语句会有差异从而引起err

快速创建 Demo

(1)搭建数据库

(2)新建项目

pom.xml

<?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>com.rui</groupId>
    <artifactId>MyBatis-Study</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--导入依赖-->
    <dependencies>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

⭐在build中配置resources,来防止我们资源导出失败的问题

<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
</build>

mybatis的核心配置文件

<?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默认环境-->
    <environments default="development">
        <!--environment单个环境-->
        <environment id="development">
            <!--transactionManager配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=tru8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--每一个mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="com/quan/dao/UserMapper.xml"/>
    </mappers>
</configuration>

mybatis工具类

//sqlSessionFactory--->SessionFactory
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(){
        return sqlSessionFactory.openSession();
    }
}

User 实体类

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;
    }
    //剩下的省略...
    ..........................................

UserDao 接口

public interface UserDao {
    List<User> getUserList();
}

UserMapper.xml配置

接口实现类由原来的UserImpl转变为一个Mapper

<?xml version="1.0" encoding="gbk" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个对应的mapper接口-->
<mapper namespace="com.quan.dao.UserDao">
    <!--select查询语句-->
    <select id="getUserList" resultType="com.quan.pojo.User">
       /*定义sql*/
       select * from mybatis.user
   </select>
</mapper>

测试

public class UserDaoTest {
    @Test
    public void test(){
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //执行SQL
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        //关闭SqlSession
        sqlSession.close();
    }
}

可能会遇到的问题:

  • 配置文件没有注册
  • 绑定接口错误
  • 方法名不对
  • 返回类型不对
  • Maven导出资源问题

增删改查(CUID)

以查询语句为例;

  • id:就是对应的namespace中的方法名;
  • resultType:Sql语句执行的返回值!
  • parameterType:参数类型!

UserMapper 接口

public interface UserMapper {
    //根据id查询用户
    User getUserById(int id);
}

UserMapper.xml

编写对应 sql

<select id="getUserById" resultType="com.rui.quan.User" parameterType="int">
      /*定义sql*/
      select * from mybatis.user where id = #{id}
</select>

测试

@Test
    public void getUserById(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
        sqlSession.close();
    }

⭐注意点:增删改需要提交事务(sqlSession.commit();)

可能出现的错误

  • 标签不要匹配错误
  • resource绑定mapper,需要使用路径!
  • 程序配置文件必须符合规范
  • NullPointerException,没有注册到资源
  • 输出的xml文件中存在中文乱码问题
  • maven资源没有导出问题

万能Map

实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map(或注解)!!!

  • 【parameterType="map"】
    Map传递参数,直接在sql中取出key即可!
  • 【parameterType="Object"】
    对象传递参数,直接在sql中取对象的属性即可!

(只有一个基本类型参数的情况下,可以直接在sql中取到!)

示例

  • UserMapper.java
int addUser2(Map<String,Object> map);
  • UserMapper.xml
<!--对象中的属性,可以直接取出来 parameterType=传递map中的key-->
<insert id="addUser2" parameterType="map">
    insert into mybatis.user (id, name, pwd) values (#{userId},#{userName},#{password});
</insert>
  • UserTest.java
@Test
public void addUser2(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Object> map = new HashMap<>();
    map.put("userId",4);
    map.put("userName","王五");
    map.put("password","23333");
    mapper.addUser2(map);
    //提交事务
    sqlSession.commit();
    sqlSession.close();
}

模糊查询

  • Java代码执行的时候传递通配符%%
List<User> userList=mapper.getUserLike("%李%");
  • 在sql拼接中使用通配符!(sql注入 慎用)
select * from mybatis.user where name like "%"#{value}"%"

外部配置文件

在核心配置文件中引入

    <!--引入外部配置文件-->
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="Cc105481"/>
    </properties>

说明:

  • 不写 property 标签即直接引入外部文件
  • 写 property 即在外部配置文件的基础上再增加一些属性配置
  • 如果内外有同一字段,优先使用外部配置文件!

取别名

  • 类型别名是为 Java 类型设置一个短的名字。
  • 存在的意义仅在于用来减少类完全限定名的冗余。
<!--可以给实体类起别名-->
<typeAliases>
    <typeAlias type="com.rui.pojo.User" alias="User"/>
</typeAliases>

简化使用:指定包名,MyBatis 会在包名下面搜索需要的 Java Bean
比如:扫描实体类的包,他的默认别名就为这个类的类名,首字母小写(建议)!

 <!--可以给实体类起别名-->
<typeAliases>
    <package name="com.rui.pojo"/>
</typeAliases>

ResultMap 映射

处理数据库与实体类字段不一致的情况

  • ResultMap 是 MyBatis 中最重要最强大的元素
  • 对于简单的语句不需要配置显式的结果映射,对于复杂的语句只需要描述它们的关系就行了。
  • ResultMap 最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。(大多数情况字段一致,不需映射)
<!--结果集映射-->
    <resultMap id="UserMap" type="User">
        <!--column数据库中的字段,property实体类中的属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
    <select id="getUserById" resultMap="UserMap" parameterType="int">
       /*定义sql*/
       select * from mybatis.user where id = #{id};
   </select>

注解(解耦)

面向接口编程的根本原因:解耦,可拓展,提高复用,分层开发中、上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性好

  • 注解在接口上实现
@Select(value = "select * from user")
List<User> getUsers();
  • 需要在核心配置文件中绑定接口!
<!--绑定接口-->
<mappers>
    <mapper class="rui.dao.UserMapper"/>
</mappers>
  • 测试
public class UserMapperTest {
    @Test
    public void test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //底层主要应用反射
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.getUsers();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}

⭐本质:反射机制实现
⭐底层:动态代理!

【注意:我们必须要将接口注册绑定到我们的核心配置文件中!】

补充:

  • 关于@Param()注解
    • 基本类型的参数或者String类型,需要加上
    • 引用类型不需要加
    • 如果只有一个基本类型的话,可以忽略,但是建议大家都加上
    • 我们在SQL中引用的就是我们这里的@Param()中设定的属性名
  • #{} ${}区别(#防止sql注入)
    • #{}在mybatis中的底层是运用了PreparedStatement 预编译,传入的参数会以 ? 形式显示
    • 因为sql的输入只有在sql编译的时候起作用,当sql预编译完后,传入的参数就仅仅是参数,不会参与sql语句的生成
    • ${}则没有使用预编译,传入的参数直接和sql进行拼接,由此会产生sql注入的漏洞。
分享到:
Ajax 基本使用 回顾!
SSM中快速应用 spring-security
  • 文章目录
  • 站点概览
寸劲开天

帅哥寸劲开天

Github QQ Email RSS
看爆 Top5
  • Spring 基础知识回顾! 659次看爆
  • Spring MVC 基础知识回顾! 326次看爆
  • Ajax 基本使用 回顾! 257次看爆
  • 给博客添加天气和飘落特效! 256次看爆
  • SpringBoot+Mybatis实现评论楼中楼功能! 238次看爆

Copyright © 2021 寸劲开天 · 鲁ICP备19012310号

Proudly published with Halo · Theme by fyang · 站点地图