概述

ORMapping: Object Relationship Mapping 对象关系映射

对象指⾯面向对象
关系指关系型数据库
Java 到 MySQL 的映射,开发者可以以⾯面向对象的思想来管理理数据库。

image.png
image.png
image.png

image.png
image.png

如何使用

1 新建Maven工程,pom.xml

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.southwind</groupId>
  7. <artifactId>aimybatis</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <dependencies>
  10. <dependency>
  11. <groupId>org.mybatis</groupId>
  12. <artifactId>mybatis</artifactId>
  13. <version>3.4.5</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>mysql</groupId>
  17. <artifactId>mysql-connector-java</artifactId>
  18. <version>8.0.11</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.projectlombok</groupId>
  22. <artifactId>lombok</artifactId>
  23. <version>1.18.6</version>
  24. <scope>provided</scope>
  25. </dependency>
  26. </dependencies>
  27. <!--使java文件里面的xml文件可读-->
  28. <build>
  29. <resources>
  30. <resource>
  31. <directory>src/main/java</directory>
  32. <includes>
  33. <include>**/*.xml</include>
  34. </includes>
  35. </resource>
  36. </resources>
  37. </build>
  38. </project>

2 新建数据表

use mybatis;
create table t_account(
    id int primary key auto_increment,
    username varchar(11),
    password varchar(11),
    age int
)

3 新建数据表对应的实体类Account

Account.java

package com.southwind.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
    private long id;
    private String username;
    private String password;
    private int age;
}

4 创建MyBatis的配置文件 config.xml 文件名可自定义

放在resources目录下

<?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>
    <!-- 配置MyBatis运⾏环境 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置JDBC事务管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- POOLED配置JDBC数据源连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8"></property>
                <property name="username" value="root"></property>
                <property name="password" value="123456"></property>
            </dataSource>
        </environment>
    </environments>

</configuration>

5 MyBatis开发方式一 使用原生接口

1、MyBatis 框架需要开发者⾃定义 SQL 语句,写在 Mapper.xml ⽂件中,实际开发中,会为每个实体类创建对应的 Mapper.xml ,定义管理该对象数据的 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.southwind.mapper.AccoutMapper">
    <insert id="save" parameterType="com.southwind.entity.Account">
        insert into t_account(username,password,age) values (#{username},#{password},#{age})
    </insert>
</mapper>
  • namespace 通常设置为⽂件所在包+⽂件名的形式。

  • insert 标签表示执行添加操作。

  • select 标签表示执行查询操作。
  • update 标签表示执行更新操作。
  • delete 标签表示执⾏删除操作。

  • id 是实际调⽤ MyBatis ⽅法时需要⽤到的参数。

  • parameterType 是调用对应⽅法时参数的数据类型。

2、在全局配置文件 config.xml 中注册 AccountMapper.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>
    <!-- 配置MyBatis运⾏环境 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置JDBC事务管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- POOLED配置JDBC数据源连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8"></property>
                <property name="username" value="root"></property>
                <property name="password" value="123456"></property>
            </dataSource>
        </environment>
    </environments>

    <!-- 注册AccountMapper.xml -->
    <mappers>
        <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
    </mappers>

</configuration>

3、调用MyBatis的原生接口执行添加操作

测试类

package com.southwind.test;

import com.southwind.entity.Account;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test {
    public static void main(String[] args) {
        //加载MyBatis的配置文件
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("config.xml");

        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        String statement =  "com.southwind.mapper.AccoutMapper.save";  //namespace.id
        Account account = new Account(1L,"张三","123123",22);
        sqlSession.insert(statement, account);
        sqlSession.commit();
    }
}

5 MyBatis开发方式二 通过Mapper代理实现自定义接口

  • 自定义接口,定义相关业务方法
  • 编写与方法相对应的Mapper.xml

Tips:咱们只需要定义接口和Mapper.xml,实现类和对象都是Mapper自动生成的

1、自定义接口

image.png

package com.southwind.repository;

import com.southwind.entity.Account;

import java.util.List;

public interface AccountRepository {
    public int save(Account account);
    public int update(Account account);
    public int deleteById(Long id);
    public List<Account> findAll();
    public Account findById(Long id);
}

2、创建接⼝对应的 Mapper.xml,定义接口⽅方法对应的 SQL 语句。

statement 标签可根据 SQL 执行的业务选择 insert、delete、update、select。
MyBatis 框架会根据规则⾃动创建接⼝实现类的代理对象。
规则:
Mapper.xml 中 namespace 为接⼝的全类名。
Mapper.xml 中 statement 的 id 为接⼝中对应的方法名。
Mapper.xml 中 statement 的 parameterType 和接⼝中对应方法的参数类型一致。
Mapper.xml 中 statement 的 resultType 和接⼝中对应方法的返回值类型⼀致。

image.png

image.png

<?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.southwind.repository.AccountRepository">
    <insert id="save" parameterType="com.southwind.entity.Account">
        insert into t_account(username,password,age) values(#{username},#{password},#{age})
    </insert>

    <update id="update" parameterType="com.southwind.entity.Account">
        update t_account set username = #{username},password = #{password},age= #{age} where id = #{id}
    </update>

    <delete id="deleteById" parameterType="long">
        delete from t_account where id = #{id}
    </delete>

    <select id="findAll" resultType="com.southwind.entity.Account"><!--不要写集合,应该写集合里的范型的类型-->
        select * from t_account
    </select>

    <select id="findById" parameterType="long" resultType="com.southwind.entity.Account">
        select * from t_account where id = #{id}
    </select>
</mapper>


3、在 config.xml 中注册 AccountRepository.xml

追加即可

<!-- 注册AccountMapper.xml -->
    <mappers>
        <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
        <mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
    </mappers>

4、调⽤用接⼝的代理对象完成相关的业务操作

测试类Test2.java

package com.southwind.test;

import com.southwind.entity.Account;
import com.southwind.repository.AccountRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

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

public class Test2 {
    public static void main(String[] args) {
        //加载配置文件
        InputStream inputStream = Test2.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //获取实现接口的代理对象
        AccountRepository accountRepository = sqlSession.getMapper(AccountRepository.class);

        //添加对象
//        Account account = new Account(2L,"cheung","12345",20);
//        int save = accountRepository.save(account);
//        sqlSession.commit();
//        System.out.println("影响了" + save + "行");

        //查询对象
//        List<Account> list = accountRepository.findAll();
//        for(Account account:list){
//            System.out.println(account);
//        }

        //通过id查询对象
//        Account account = accountRepository.findById(3L);
//        System.out.println(account);

        //update修改对象
//        Account account = accountRepository.findById(3L);
//        account.setUsername("⼩小明");
//        account.setPassword("000");
//        account.setAge(18);
//        int result = accountRepository.update(account);
//        sqlSession.commit();
//        System.out.println("影响了" + result + "行");


        //通过id删除对象
//        int result = accountRepository.deleteById(3L);
//        sqlSession.commit();
//        System.out.println(result);

        sqlSession.close();
    }
}

Mapper.xml

Tips:environment是告诉mybatis怎么连接数据库,mapper是说,我怎么跟数据库里的表映射的。

statement标签:select、update、dalete、insert分别对应查询、修改、删除、添加操作。

parameterType:参数数据类型

1、基本数据类型,通过id查询Account

<select id="findById" parameterType="long" resultType="com.southwind.entity.Account">
    select * from t_account where id = #{id}
</select>

2、String类型,通过name查询Account

<select id="findByName" parameterType="java.lang.String" resultType="com.southwind.entity.Account">
  select * from t_account where username = #{username}
</select>

3、包装类,通过id查询Account
Tips:为什么要用包装类 因为基本数据类型不能接受null值

<select id="findById2" parameterType="java.lang.Long" resultType="com.southwind.entity.Account">
        select * from t_account where id = #{id}
  </select>

4、多个参数,通过name和age查询Account

parameterType写谁呢?我直接不写
Mapping.xml

 <select id="findByNameAndAge" resultType="com.southwind.entity.Account">
  select * from t_account where username = #{arg0} and age = #{arg1}
</select>

Tips:读参通过下标来取
image.png
arg从0开始 param从1开始

5、Java Bean
常用的修改 就是传bean进去

 <update id="update" parameterType="com.southwind.entity.Account">
  update t_account set username = #{username},password = #{password},age =#{age} where id = #{id}
</update>

resultType:结果类型

1、基本数据类型,统计Account总数

<select id="count" resultType="int">
    select count(id) from t_account
</select>

image.png

2、包装类,统计Account总数

 <select id="count2" resultType="java.lang.Integer">
    select count(id) from t_account
</select>

3、String类型,通过id查询Account的name

 <select id="findNameById" resultType="java.lang.String">
    select username from t_account where id = #{id}
</select>

4、Java Bean

 <select id="findById" parameterType="long" resultType="com.southwind.entity.Account">
    select * from t_account where id = #{id}
</select>

及联查询

一对多(学生查班级)

image.pngimage.png


1 建对应实体类

Student.java

package com.southwind.entity;

import lombok.Data;

@Data
public class Student {
    private long id;
    private String name;
    private Classes classes;
}

Classes.java

package com.southwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Classes {
    private long id;
    private String name;
    private List<Student> students;
}

大概要怎么查询呢?
image.png

2 写接口

package com.southwind.repository;

import com.southwind.entity.Student;

public interface StudentRepository {
    public Student findById(long id);
}

3 写mapping.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="com.southwind.repository.StudentRepository">

    <resultMap id="studentMap" type="com.southwind.entity.Student">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <association property="classes" javaType="com.southwind.entity.Classes">
            <id column="cid" property="id"></id>
            <result column="cname" property="name"></result>
        </association>
    </resultMap>

    <select id="findById" parameterType="long" resultMap="studentMap">
        select s.id,s.name,c.id as cid,c.name as cname from student s,classes c where s.id = #{id} and s.cid = c.id;
    </select>

</mapper>

主键用 其他字段全部用
column对应了结果集的字段
property对应了实体类的属性

javaType指的是property的数据类型
image.png

4 在config.xml里面注册mapper

<!-- 注册AccountMapper.xml -->
    <mappers>
        <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
        <mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
        <mapper resource="com/southwind/repository/StudentRepository.xml"></mapper>
    </mappers>

5 测试

image.png

一对多(班级查学生)

接口

package com.southwind.repository;

import com.southwind.entity.Classes;

public interface ClassesRepository {
    public Classes findById(long id);
}

Mapping.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="com.southwind.repository.ClassesRepository">
    <resultMap id="classesMap" type="com.southwind.entity.Classes">
        <id column="cid" property="id"></id>
        <result column="cname" property="name"></result>
        <collection property="students" ofType="com.southwind.entity.Student">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
        </collection>
    </resultMap>

    <select id="findById" parameterType="long" resultMap="classesMap">
        select s.id,s.name,c.id as cid,c.name as cname from student s,classes c where c.id = #{id} and s.cid = c.id;
    </select>

</mapper>

在config里注册mapper

<!-- 注册AccountMapper.xml -->
    <mappers>
        <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
        <mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
        <mapper resource="com/southwind/repository/StudentRepository.xml"></mapper>
        <mapper resource="com/southwind/repository/ClassesRepository.xml"></mapper>

    </mappers>

测试

image.png


多对多(查顾客购买的商品)

数据库表

image.png
image.png
image.png

JavaBean

package com.southwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Customer {
    private long id;
    private String name;
    private List<Goods> goods;
}
package com.southwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Goods {
    private long id;
    private String name;
    private List<Customer> customers;
}

接口

package com.southwind.repository;

import com.southwind.entity.Customer;

public interface CustomerRepository {
    public Customer findById(long id);
}

mapping.xml并在config中注册

<?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.southwind.repository.CustomerRepository">
    <resultMap id="customerMap" type="com.southwind.entity.Customer">
        <id column="cid" property="id"></id>
        <result column="cname" property="name"></result>
        <collection property="goods" ofType="com.southwind.entity.Goods">
            <id column="gid" property="id"></id>
            <result column="gname" property="name"></result>
        </collection>

    </resultMap>

    <select id="findById" parameterType="long" resultMap="customerMap">
        select c.id cid,c.name cname,g.id gid,g.name gname from customer c,goods g,customer_goods cg where c.id = #{id} and cg.cid = c.id and cg.gid = g.id;
    </select>
</mapper>
<!-- 注册AccountMapper.xml -->
    <mappers>
        <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
        <mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
        <mapper resource="com/southwind/repository/StudentRepository.xml"></mapper>
        <mapper resource="com/southwind/repository/ClassesRepository.xml"></mapper>
        <mapper resource="com/southwind/repository/CustomerRepository.xml"></mapper>
    </mappers>

测试

image.png

多对多(查询某商品被哪些顾客买走了)

image.png
image.png
image.png
image.png