复习整理的DAY27_MyBatis

首先,什么是MyBatis

MyBatista属于ORM框架,是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射,对JDBC操作数据库的过程进行封装,使开发者只需要关注SQL本身。

这么说,可能有人不太理解,什么是ORM框架,什么又是持久层框架?

ORM即Object Relation Mapping的缩写,对象映射关系,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据访问接口,用于面向对象的对象模型和关系型数据之间的相互转换。

而持久层框架是在系统逻辑层面上,用于实现数据持久化(把数据保存到可掉电式存储设备中)的一个相对独立的领域,负责向(或从)一个或者多个数据存储器中存储(或获取)数据的一组类和组件。该层必须包括一个业务领域实体的模型。

MyBatis框架运行流程:

 注:POJO全称是Plain Ordinary Java Object / Pure Old Java Object,中文可以翻译成:普通Java类,具有一部分getter/setter方法的那种类就可以称作POJO,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。

MyBatis配置文件

SqlMapConfig.xml,是Mybatis的全局配置文件,配置了运行环境等信息。

Mapper.xml文件,即sql映射文件,配置了操作数据库的sql语句,配置这个文件,需要先在全局配置文件SqlMapConfig.xml中加载。

SqlSessionFactory

生成SqlSession的工厂,作用是返回构造的SqlSession。

SqlSession

是一个会话(Session),类似于JDBC里面的Connection,从开启这个会话,到结束这个会话,可以发送增删改查操作。

Executor:执行器接口

有两个实现,一个是基本执行器、一个是缓存执行器。

Mapped Statement:

是Mybatis的一个底层封装对象。封装了配置信息和sql映射等。

Mapper.xml与Mapped Statement的关联:Mapper.xml文件中一个sql对应一个Mapped Statement对象,其中的sql的id即是Mapped statement的id。

MyBatis具体实例(使用IDEA),

第一步,在MyBatis项目下加入一个lib的目录,lib下添加了相关jar包

asm各种版本下载:http://download.forge.ow2.org/asm/

cgllib的jar包下载:https://www.kumapai.com/open/1306-org-apache-servicemix-bundles-cglib

commons-logging的jar包下载:http://archive.apache.org/dist/commons/logging/binaries/ 

javassist的jar包下载:http://www.javassist.org/

loj4j的各种jar包下载:https://archive.apache.org/dist/logging/log4j/1.2.17/

https://archive.apache.org/dist/logging/log4j/2.0-rc1/

mybatis的jar包下载:https://www.kumapai.com/open/1306-org-apache-servicemix-bundles-mybatis

第二步,在src下面配置mybatis.xml全局配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration SYSTEM "http://mybatis.org/dtd/mybatis-3-config.dtd" PUBLIC "-//mybatis.org//DTD Config 3.0//EN">

-<configuration>


-<environments default="development">


<environment id="development">

<!-- 使用JDBC的事物管理 -->

<transactionManager type="JDBC"/>

<!-- 配饰数据库连接池 -->

<dataSource type="POOLED">

<property value="com.mysql.jdbc.Driver" name="driver"/>

<property value="jdbc:mysql://localhost:3306/java?characterEncoding=UTF-8" name="url"/>

<property value="root" name="username"/>

<property value="1234" name="password"/>

</dataSource>

</environment>

</environments>

</configuration>

第三步,在src下面创建包mybatis,在该包下创建存放实体类的包entity,在entity下创建实体类,

比如,我创建的是Student类

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
    private Integer banjiId;

    public Student() {
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getGender() {
        return gender;
    }

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

    public Integer getBanjiId() {
        return banjiId;
    }

    public void setBanjiId(Integer banjiId) {
        this.banjiId = banjiId;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", banjiId=" + banjiId +
                '}';
    }

  为了使得配置文件扫描到包中的类,我们还需要在全局配置文件中加入typeAliases标签

    <typeAliases>
		<package name="mybatis.entity"/>
	</typeAliases>

第四步,创建完实体类之后,在entity该包下创建对应的Mapper.xml,比如我创建的是

StudentMapper.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">

<mapper namespace="student">
	
	
</mapper>

不仅如此,还需要在全局配置文件中加载 

<!-- 加载映射文件 -->

<mappers>

<mapper resource="mybatis/entity/StudentMapper.xml"/>

</mappers>

第五步,在StudentMapper.xml里面添加需要的sql语句,比如我要写一个select语句,在数据库中通过id查询student表里的数据(name,age,gender,banji_id)

<!-- 通过id查找学生 -->
	<select id="selectById" parameterType="Integer" resultType="Student">
		select id,name,age,gender,banji_id from student where id=#{id}
	</select>

注:为了使类似banji_id这样有下划线的表中数据对应上banjiId这样小驼峰命名的类中属性,需要在全局配置文件mybatis.xml里面configuration标签内添加setting标签

    <settings>
		<!-- 下划线字段对应实体类驼峰命名 数据库表:banji_id 映射到类里面:banjiId -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>

第六步,为了看到结果,在mybatis包下我建了一个test包,创建了一个MyBatisTest测试类

public class MyBatisTest {
@Test
public void testSelectById() throws IOException {
   String resource = "mybatis.xml";
   InputStream inputStream = Resources.getResourceAsStream(resource);
   // 创建 SqlSessionFactory    Session:会话 (连接数据库后就建立了一次会话,有了会话就可以操作数据库)
   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
   // 得到SqlSession
   SqlSession sqlSession = sqlSessionFactory.openSession();
   // 执行sql语句
   Student student = sqlSession.selectOne("student.selectById", 1);
   System.out.println(student);
}

}

执行这个函数,如果数据库中student表有一个id为1的数据,就会在控制台打印出来。

在这里,就会用到SqlSessionFactory以及SqlSession,但是,如果每一次使用,我们都要重复这些代码,因为我们写的这些只能在这个函数使用,就会有些繁琐了,所以把重复的代码封装成一个工具类,就会简化很多,比如我在mybatis包下创建了一个工具包util,在工具包下,创建了一个工具类,MyBatisUtil

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        String resource = "mybatis.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        // 得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
}

这样,在使用时,可以直接调用工具类封装的sqlSession对象,

@Test
public void testSelectById() {
   SqlSession sqlSession = MyBatisUtil.getSqlSession();
   // 执行sql语句
   Student student = sqlSession.selectOne("student.selectById", 1);
   System.out.println(student);
}

增删改查操作

在StudentMapper.xml中

如果每次都要用到student表的id,name,age,gender,banji_id(这里是数据库表中显示的名字),都要自己写一遍,会很繁琐,所以,可以用sql标签,在使用时用include标签

<sql id="studentColumn">
        id,name,age,gender,banji_id
</sql>

查找:

<select id="selectAll" resultType="Student">
        select <include refid="studentColumn"></include>
        from student
</select>
    @Test
    public void testSelectAll() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        List<Student> list = sqlSession.selectList("student.selectAll");
        for (Student student : list) {
            System.out.println(student);
        }
    }

删除(根据Id):

    <delete id="deleteById" parameterType="Integer">
        delete
        from student
        where id = #{id}
    </delete>
    @Test
    public void testDeleteById() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        int count = sqlSession.delete("student.deleteById" , 3);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

插入:

    <insert id="insert" parameterType="Student">
        insert into student(name, age, gender)
        values (#{name}, #{age}, #{gender})
    </insert>
    @Test
    public void testInsert() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        Student student = new Student();
        student.setName("王柳");
        student.setAge(23);
        student.setGender("男");
        int count = sqlSession.insert("student.insert", student);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

更新(根据Id):

    <update id="update" parameterType="Student">
        update student
        set name=#{name},
            age=#{age},
            gender=#{gender}
        where id = #{id}
    </update>
    @Test
    public void testUpdate() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        Student student = new Student();
        student.setId(25);
        student.setName("深蓝");
        student.setAge(24);
        student.setGender("男");
        int count = sqlSession.update("student.update", student);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

对于更新类的操作返回的是影响的函数,resultType不需要写;

对于更新类操作,sqlSession对象一定要提交,因为MyBatis把JDBC的autocommit(自动提交)设置为false,当执行更新类操作的时候并没有真正提交到数据库,需要手动提交。

resultType与parameterType:

result表示返回值,parameterType表示传递过来的参数

一些类型

int/Integer/ineger:在配置int时通过上表可以看出,即可以是java中的基本类型int,也可以是java中的包装类型Integer,不过在配置为包装类型是必须是java.lang.Integer,所以在配置为int是我们的java接口中的参数类型最好是Integer的。

string/String:对应java中的java.lang.String

map:对应java.util.Map

hashmap:对应java.util.HashMap

list:对应java.util.List

arraylist:对应java.util.ArrayList

这些不需要我们自己映射,mybatis自己已经映射好了,我们使用的时候,只需要在Mapper.xml文件中直接写类型对应名字即可。

比如:

<select id="selectByPage" parameterType="Map" resultType="Student">
        select<include refid="studentColumn"></include> from student limit #{offset}, #{pageSize}
</select>
    @Test
    public void testSelectByPage() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        int pageNo = 2;
        int pageSize = 5;
        int offset = (pageNo - 1) * pageSize;
        Map<String, Object> map = new HashMap<>();
        map.put("offset", offset);
        map.put("pageSize", pageSize);
        List<Student> list = sqlSession.selectList("student.selectByPage", map);
        for (Student student : list) {
            System.out.println(student);
        }
    }

当实体类的属性名和表的字段名不一致的时候,一定要用resultMap映射之后才写sql语句,返回类型是resultMap的id名称 。不过通常情况下,即使我们表中名字和类中名字能够一一对应,也会用resultMap。

<resultMap type="Student" id="studentMap">
   <!-- 映射主键属性:如果有多个主键字段,则定义多个id -->
   <!-- property:类的属性名 -->
   <!-- column:表的字段名 -->
   <id property="id" column="id"/>
   <!-- result定义普通属性 -->
   <result property="name" column="student_name"/>
   <result property="age" column="age"/>
   <result property="gender" column="gender"/>
   <result property="banjiId" column="banji_id"/>
</resultMap>

<select id="selectAll" resultMap="studentMap">
   select id,student_name,age,gender,banji_id from student
</select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值