Spring 学习之路--Spring MyBatis学习笔记

Spring MyBatis

一. 概念

1 .定义

​ 是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,使得Java开发人员可以使用面向对象的编程思想来操作数据库。

MyBatis框架也被称之为ORM( Object/Relational Mapping,即对象关系映射)框架

2 .Hibernate与MyBatis的区别

Hibernate

​ 是一个全表映射的框架。通常开发者只需定义好持久化对象到数据库表的映射关系,就可以通过 Hibernate提供的方法完成持久层操作。开发者并不需要熟练地掌握SQL语句的编写, Hibernate会根据制定的存储逻辑,自动的生成对应的SQL,并调用JDBC接口来执行,所以其开发效率会高于 MyBatis。然而 Hibernate自身也存在着一些缺点,例如它在多表关联时,对SQL查询的支持较差;更新数据时,需要发送所有字段;不支持存储过程;不能通过优化SOL来优化性能等。这些问题导致其只适合在场景不太复杂且对性能要求不高的项目中使用。

MyBatis

​ 是一个半自动映射的框架。这里所谓的“半自动”是相对于 Hibernate全表映射而言的, MyBatis需要手动匹配提供POJO、SQL和映射关系,而 Hibernate只需提供POJO和映射关系即可。与 Hibernate相比,虽然使用 MyBatis手动编写SQL要比使用Hibernate的工作量大,但 MyBatis可以配置动态SQL并优化SQL,可以通过配置决定SQL的映射规则,它还支持存储过程等。对于一些复杂的和需要优化性能的项目来说,显然使用MyBatis更加合适。

二. MyBatis的工作原理

1. 读取 Mybatis 配置文件mybatis- config. xml

​ mybatis- config. xml作为 Mybatis的全局配置文件,配置了 Mybatis的运行环境等信息,其中主要内容是获取数据库连接。

2. 加载映射文件 Mapper. xml

​ Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在 mybatis- config. xml中加载オ能执行。 mybatis- config. xml可以加载多个配置文件,每个配置文件对应数据库中的一张表。

3. 构建会话工厂

​ 通过 MyBatis的环境等配置信息构建会话工厂 Sqlsessionfactory。

4. 创建 Sqlsession对象

​ 由会话工厂创建 Sqlsession对象,该对象中包含了执行SQL的所有方法。

5. Executor接口执行SQL语句

​ MyBatis底层定义了一个 Executor接口来操作数据库,它会根据 Sqlsession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

6. MappedStatement类型参数

​ 在 Executor接口的执行方法中,包含一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等。 Mapper.xml文件中一个SQL对应一个 MappedStatement对象,SQL的d即是 MappedStatement的id。

7. 输入参数映射

​ 在执行方法时, MappedStatement对象会对用户执行SOL语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型), Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SOL语句中。这里对输入参数的映射过程就类似于JDBC编程中对 preparedstatement对象设置参数的过程。

8. 输出结果映射

​ 输出结果映射。在数据库中执行完SQL语句后, MappedStatement对象会对SOL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型), Executor执行器会通过 MappedStatement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。

三. 案例实现(查询客户)

1. 数据库建表

​ 在 MYSQL数据库中,创建一个名为spring的数据库,在此数据库中创建一个person表,同时预先插入几条数据。

2. 创建项目

​ 在IDEA中,创建一个名为Spring MyBatis的Web项目,将 Mybatis的核心JAR包、lib目录中的依赖JAR包,以及MySQL数据库的驱动JAR包一同添加到项目的lib目录下,并发布到类路径中。

所需jar包地址.

3. 创建实体类

​ 在Src目录下,创建一个com.soft.model包,在该包下创建持久化类 Person,并在类中声明id、 username、 jobs和 phone属性,及其对应的 getter/setter方法。

package com.soft.model;

public class Person {
    private int id;
    private String username;
    private String password;
    private String job;
    private String phone;

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", job='" + job + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

4. 导入 log4j 的配置文件

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.soft=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

5 . 导入mybatis的核心配置文件,配置mapper

​ 在com目录下,创建一个映射文件PersonMapper. xml

​ 核心配置文件,事务 ,数据源,加载mapper文件,mapper 用一个唯一标识(命名空间+id),找到一条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.soft.model.PersonMapper">
    <select id="findPersonById" parameterType="integer" resultType="com.soft.model.Person">
        select * from person where id=#{id}
    </select>

    <select id="findPersonByName" parameterType="String" resultType="com.soft.model.Person">
        select * from person where username like concat('%',#{username},'%')
    </select>

    <insert id="addPerson" parameterType="com.soft.model.Person">
        insert into person(id,username,password,job,phone) values  (#{id},#{username},#{password},#{job},#{phone})
    </insert>
    <update id="updatePerson" parameterType="com.soft.model.Person">
        update person set username=#{username},password=#{password},job=#{job},phone=#{phone} where id=#{id}
    </update>
    <delete id="deletePerson" parameterType="integer">
        delete from person where id=#{id}
    </delete>
</mapper>

在定义的查询SQL语句中,“#{}”用于表示ー个占位符,相当于"?",而“#{id}”表示该占位符待接收参数的名称为id。

6.创建核心配置文件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>
    <!--1.配置环境 ,默认的环境id为mysql-->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url"
                          value="jdbc:mysql://localhost:3306/spring" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="PersonMapper.xml"/>
    </mappers>
</configuration>

7. 运行测试

​ 在com.soft目录下,创建测试类myBibatisTest,并在类中编写测试方法findPersonByIdTest()、findPersonByNameTest()、addPersonTest()、updatePersonTest()、deletePersonTest(),分别对应通过用户ID查询、通过名字中所含字段查询、增加用户信息、插入/更改用户信息、删除用户信息。

package com.soft;

import com.soft.model.Person;
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 org.junit.Test;

import java.io.InputStream;
import java.util.List;

public class myBibatisTest {
    @Test
    public void findPersonByIdTest() throws Exception {
        //读取配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //根据配置文件构建 会话工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //会话工厂 创建 会话对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Person p1 = sqlSession.selectOne("com.soft.model.PersonMapper.findPersonById", 1);
        System.out.println(p1);
        sqlSession.close();
    }
    @Test
    public void findPersonByNameTest() throws Exception{
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = build.openSession();
        List<Person> o = sqlSession.selectList("com.soft.model.PersonMapper.findPersonByName", "o");
        for(Person person:o){
            System.out.println(person);
        }
        sqlSession.close();
    }
    @Test
    public void addPersonTest() throws Exception{
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = build.openSession();
        Person person = new Person();
        person.setId(20);
        person.setUsername("程序员2020");
        person.setPassword("456789");
        person.setJob("程序员");
        person.setPhone("78945612365454");
        int i = sqlSession.insert("com.soft.model.PersonMapper.addPerson", person);
        if(i>0){
            System.out.println("插入了"+i+"条数据");
        }else {
            System.out.println("插入失败");
        }
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void updatePersonTest() throws Exception {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Person person = new Person();
        person.setUsername("202003150734");
        person.setPassword("456321");
        person.setJob("程序员4");
        person.setPhone("457912345689");
        person.setId(20);
        int i = sqlSession.insert("com.soft.model.PersonMapper.updatePerson", person);
        if(i>0){
            System.out.println("修改成功,修改了: "+i+" 条数据");
        }
        sqlSession.commit();
        sqlSession.close();

    }
    @Test
    public void deletePersonTest() throws Exception {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        int d = sqlSession.delete("com.soft.model.PersonMapper.deletePerson", 15);
        if(d>0){
            System.out.println("成功删除了: "+d+" 条对象");
        }
        sqlSession.commit();
        sqlSession.close();

    }
}

findPersonByIdTest():

findPersonByNameTest():

addPersonTest():

updatePersonTest():

deletePersonTest():

注意:

​ 在使用“${}”进行SQL字符串拼接时,无法防止SQL注入问题。所以想要既能实现模糊查询,又要防止SQL注入,可以对上述映射文件PersonMapper. xml中模糊查询的 select语句进行修改,使用 MySQL中的 concat函数进行字符串拼接。

select * from person where username like concat('%',#{username},'%')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liangpi_hero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值