小白架构师成长之路8-Mybatis认识和Mybatis体系

Mybatis认识

该文档对应的项目都可通过github下载:https://github.com/JolyouLu/mybatis01 代码在test.mybatis下

传统JDBC的弊端

创建表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int(4) NULL DEFAULT NULL COMMENT '年龄',
  `phone` bigint(20) NULL DEFAULT NULL COMMENT '手机',
  `desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '说明',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

使用传统jdbc编写crud

在我们每一次crud时我们都需要对数据库建立一次连接,首先我们需要一个工具类用来建立数据库连接与关闭数据库连接

数据库连接工具类
public class DbUtil {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    static {
        driver="com.mysql.jdbc.Driver";//数据库驱动
        url="jdbc:mysql://localhost:3306/study?characterEncoding=utf8&useSSL=true";//地址
        username="root";//连接数据库用户名
        password="123456";//连接数据库密码
    }
    /**
     * 加载数据库驱动 并且连接数据库
     */
    public static Connection open(){
        try {
            Class.forName(driver);
            return (Connection) DriverManager.getConnection(url,username,password);
        }catch (Exception e){
            System.out.println("数据库连接失败!");
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 关闭数据库连接
     */
    public static void close(Connection conn){
        if (conn !=null){
            try {
                conn.close();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
}
传参数insert语句

我们先写一个传参数来进行crud的例子

public class Jdbc01 {
    public static void main(String[] args) {
        insert("test01",12);
    }
    //使用传参数 新增数据方法
    static void insert(String name,int age){
        //定义需要执行的sql
        String sql="insert into user(username,age) value(?,?)";
        //打开数据库连接
        Connection conn = DbUtil.open();
        try {
            //执行sql
            PreparedStatement pstmt =(PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1,name);
            pstmt.setInt(2, age);
            pstmt.executeUpdate();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            //关闭数据库连接
            DbUtil.close(conn);
        }
    }
}
使用对象insert语句

首先我们需要一个user对象 该对象与数据库字段名字是完全一致的

public class User implements Serializable {
    private Integer id;
    private String username;
    private Integer age;
    private String desc;
    //以下省略get set方法
}

新增以及查询方法

public class jdbc02 {
    public static void main(String[] args) {
        User user = new User();
        user.setUsername("test02");
        user.setAge(18);
        insert(user);//插入数据方法
        User query = query(1);
        System.out.println("查询成功结果如下!");
        System.out.println(query);

    }

    static void insert(User user){
        //定义需要执行的sql
        String sql="insert into user(username,age) value(?,?)";
        //打开数据库连接
        Connection conn = DbUtil.open();
        try {
            PreparedStatement pstmt =(PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1,user.getUsername());
            pstmt.setInt(2, user.getAge());
            pstmt.executeUpdate();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            DbUtil.close(conn);
        }
    }

    static User query(int id){
        String sql="select * from user where id=?";
        Connection conn = DbUtil.open();
        try {
            PreparedStatement pstmt =(PreparedStatement) conn.prepareStatement(sql);
            pstmt.setInt(1,id);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()){
                String name = rs.getString(2);
                User user = new User();
                user.setId(id);
                user.setUsername(name);
                return user;
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            DbUtil.close(conn);
        }
        return null;
    }
}

总结

经过上面几个方法的练习,我们可以发现使用jdbc连接数据库查询的代码量很多,而且每次进行crud时都需要创建和关联数据链接。很消耗资源,而且只要我们修改表结构后整个方法体都需要修改,sql就很难进行维护。

Mybatis介绍

mybatis的官网https://mybatis.org/mybatis-3/zh/index.html

Mybaits简:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

快速开始

在使用mybatis前我们需要引入相关依赖

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

然后我们需要在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>
    <typeAliases>
<!--     把com.jiago.mybatis.pojo.User定义别名user这样mapper文件resultType直接使用user就行不用写包路径-->
        <typeAlias type="com.jiago.mybatis.pojo.User" alias="user"/>
    </typeAliases>
    <plugins>
        <!--        日志拦截器插件-->
        <plugin interceptor="com.jiago.mybatis.plugin.SqlPrintInterceptor"></plugin>
    </plugins>
    <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/study?useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        mybatis运行时读取UserMapper.xml文件-->
        <mapper resource="mybatis/UserMapper.xml"/>
<!--        mybatis运行时读取UserMapper的class-->
        <mapper class="com.jiago.mybatis.mapper.UserMapper"/>
<!--        mybatis运行时读取com.jiago.mybatis.mapper的全部class-->
<!--        <package name="com.jiago.mybatis.mapper"/>-->
    </mappers>
</configuration>

并在resources中创建一个mybatis文件夹下放我们的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.jiago.mybatis.UserMapper">
    <select id="selectUser" resultType="user">
    select * from user where id = #{id}
  </select>
</mapper>

当这些都准备好以后我们就可以编写我们的测试方法

基础的sql查询

在测试之前我们需要配置一下mybatis的配置文件告诉mybatis需要扫描resources包下的xml文件这样他才能读取到xml的sql的id

在这里插入图片描述

@Test //使用xml编写sql查询
    public void test() throws IOException {
        String resource = "mybatis-config.xml";
        //读取resources下的mybatis-config.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //com.jiago.mybatis.UserMapper.selectUser  UserMapper.xml下的id为selectUser的语句
        User user = sqlSession.selectOne("com.jiago.mybatis.UserMapper.selectUser", 1);
        System.out.println("查询结果:"+user);
    }

注解式sql查询

注解式的sql查询我们只需要编写一个UserMapper的接口并且把我们需要的查询语句写在@select()

public interface UserMapper {
    @Select("select * from user where id = #{id}")
    public User selectUser(Integer id);
}

测试注解式查询

在测试之前我们需要配置一下mybatis的配置文件告诉mybatis需要扫描mapper包下的class文件这样他才能读取

在这里插入图片描述

@Test //使用注解编写sql查询
    public void test2() throws IOException {
        String resource = "mybatis-config.xml";
        //读取resources下的mybatis-config.xml配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.selectUser(1);
        System.out.println("查询结果:"+user);
    }

总结

Mybatis注解开发与xml开发的优缺点

xml优点:sql集中于一个文件中,方便查询和修改,因为不是java文件每次编辑后无需重新编译

xml缺点:xml文件编写起来比较麻烦,容易出错,一些如“<,>”符号在xml是特殊符号需要使用转义才能运行

注解优点:调用方便,没有需要转义符号的烦恼

注解缺点:修改和查询sql比较难,对于一些多层嵌套查询的sql可读性会很差,而且很乱

Mybatis中$于#的区别

#:预编译的可以防止sql注入(推荐)

$:占位符,无法反正sql注入

Mybatis之parameterType 与 parameterMap 区别

一般情况都是使用默认的很少很少修改,通过 parameterType 指定输入参数的类型,类型可以是简单类型、hashmap、pojo 的包装 类型

Mybatis 之 resultType 与 resultMap 区别

resultType就是查询返回结果映射到你指定的bean对象

resultMap你可以把你查询的结果映射成一个你想要的map容器或者list容器,前提是你需要编写一段

Mybatis的plugin

以防止sql注入(推荐)

$:占位符,无法反正sql注入

Mybatis之parameterType 与 parameterMap 区别

一般情况都是使用默认的很少很少修改,通过 parameterType 指定输入参数的类型,类型可以是简单类型、hashmap、pojo 的包装 类型

Mybatis 之 resultType 与 resultMap 区别

resultType就是查询返回结果映射到你指定的bean对象

resultMap你可以把你查询的结果映射成一个你想要的map容器或者list容器,前提是你需要编写一段

Mybatis的plugin

plugin是写在mybtais的配置文件中用于配置各种插件,如github项目中就配置了显示sql的插件,他相当于一个拦截器把连接的数据打印在后台

小白架构师成长之路9-Mybatis源码解析

发布了33 篇原创文章 · 获赞 22 · 访问量 964

猜你喜欢

转载自blog.csdn.net/weixin_44642403/article/details/103646364
今日推荐