MyBatis

目录

MyBatis概述

ORM

综合图解:

入门程序:

导入依赖jar包:

编写实体类

编写持久层接口,不用写实现类

UserMapper.xml的配置文件

编写主配置文件

jdbc.properties

入门程序,测试方法

代理Dao方式的CRUD操作

 动态sql

if标签

where标签

foreach标签

提取公用sql

返回类型封装


MyBatis概述

  • MyBatis是基于Java的持久层框架,内部对JDBC做了封装,使开发者只需要关注SQL语句,而不用关注JDBC的代码,使开发变得更加的简单。
  • MyBatis通过XML或者注解的方式将要执行的各种Statement对象配置起来,通过Java对象和statement中SQL的动态参数进行映射,并最终执行SQL语句。执行SQL后,最终将结果已Java对象返回。
  • 采用了ORM的思想。

ORM

ORM(对象关系映射)是一种技术,用于将对象模型和关系数据库之间进行映射。它允许开发人员使用面向对象的编程语言来操作数据库,而不需要直接编写 SQL 查询。

ORM 框架负责将应用程序中的对象转换为数据库中的表和行,并提供了一组 API 来执行常见的数据库操作,例如插入、更新、删除和查询数据。

通过使用 ORM,开发人员可以更加方便地进行数据库操作,而不需要手动编写大量的 SQL 语句。ORM 框架会自动处理对象与表之间的转换,简化了开发过程并提高了开发效率。

ORM 框架通常提供以下功能:

  1. 对象和表之间的映射:ORM 框架根据定义的映射规则,将对象的属性映射到数据库表的列。
  2. 数据库操作的抽象:ORM 框架提供了一组 API 来执行数据库操作,如插入、更新、删除和查询。
  3. 缓存管理:ORM 框架通常提供缓存机制,用于提高数据访问性能。
  4. 事务管理:ORM 框架支持事务操作,确保数据的一致性和完整性。
  5. 查询语言:ORM 框架通常提供一种查询语言,类似于 SQL,但是更加面向对象。

综合图解:

入门程序:

导入依赖jar包:

 <!--mybatis核心包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

编写实体类

/*
用户实体类
用户表
目的:演示mybasic增删改查
 */
public class User implements Serializable{

    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private Car car;

    public User() {
    }

    public User(Integer id, String username, Date birthday, String sex, String address, Car car) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
        this.car = car;
    }

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", car=" + car +
                '}';
    }
}
public class Car {
    private String carName;

    public Car(String carName) {
        this.carName = carName;
    }

    public Car() {
    }

    public String getCarName() {
        return carName;
    }

    public void setCarName(String carName) {
        this.carName = carName;
    }

    @Override
    public String toString() {
        return "Car{" +
                "carName='" + carName + '\'' +
                '}';
    }
}

编写持久层接口,不用写实现类

/**
 * 用户的持久层接口
 * 演示mybatis实现增删改查
 */
public interface UserMapper {

    /**
     * 查询所有的用户
     * @return
     */
    public List<User> findAll();
}

UserMapper.xml的配置文件

在resources目录下,创建mapper文件夹。编写UserMapper.xml的配置文件,导入约束文件。

UserMapper.xml解释:

- <mapper namespace="com.qcbyjy.mapper.UserMapper">,
叫名称空间,表明以后查找UserMapper接口中的findAll的方法。
- select id="findAll"中的id属性编写的UserMapper接口中的方法的名称,固定的。
- resultType="userMap"表明的是findAll方法的返回值类型。
<?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.qcby.mapper.UserMapper">

    <select id="findAll" resultMap="userMap">
        select id _id,username _username,birthday _birthday,sex _sex,address _address from user
    </select>
    
    <!--配置resultMap,用来进行数据封装   id="唯一的名称,用来被引用的"  type="进行封装数据的类型"-->
<resultMap id="userMap" type="com.qcby.domain.User">
    <!--
              property="JavaBean中的属性"
              column="数据库表中的字段"
          -->
    <result property="id" column="_id"/>
    <result property="username" column="_username" />
    <result property="birthday" column="_birthday" />
    <result property="sex" column="_sex" />
    <result property="address" column="_address" />
</resultMap>

</mapper>

编写主配置文件

在resources目录下创建SqlMapConfig.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>

    <!--用jdbc.properties连接数据库-->
    <properties resource="jdbc.properties"></properties>

    <!-- 配置环境们 -->
    <environments default="mysql">
        <!-- 配置具体的环境 -->
        <environment id="mysql">
            <!-- 配置事务管理类型 ,使用jdbc管理事物-->
            <transactionManager type="JDBC"/>
            <!-- 配置是否需要使用连接池,POOLED使用,UNPOOLED不使用 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>


    <!-- 加载映射的配置文件 -->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybasic_db?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

入门程序,测试方法

/**
 * 测试查询所有数据
 */
public class TestDemo01 {

    @Test
    /**
     * 第一种方式  通过session创建UserMapper接口的代理对象 调用方法
     */
    public void run () throws IOException {

        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        // 调用查询所有的方法
        List<User> list = mapper.findAll();
        // 遍历集合
        for (User user : list) {
            System.out.println(user);
        }
        // 释放资源
        session.close();
        in.close();
    }

    @Test
    /**
     * 第二种方式  不用代理对象,会话直接获取方法(使用较少)
     */
    public void run2() throws Exception {
        // 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 构建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 获取到session对象
        SqlSession session = factory.openSession();
        // 查询所有的数据
        //不用代理对象,用会话直接获取方法
        List<User> list = session.selectList("com.qcby.mapper.UserMapper.findAll");
        // 变量集合
        for (User user : list) {
            System.out.println(user);
        }
        // 关闭资源
        session.close();
        inputStream.close();
    }

入门程序完成!!!

代理Dao方式的CRUD操作

UserMapper接口代码

/**
 * 用户的持久层接口
 * 演示mybatis实现增删改查
 */
public interface UserMapper {

    /**
     * 查询所有的用户
     * @return
     */
    public List<User> findAll();

    /**
     * 通过id查询
     * @param userId
     * @return
     */
    public User findById(Integer userId);

    /**
     * 新增
     * @param user
     */
    public void insert(User user);

    /**
     * 修改
     * @param user
     */
    public void update(User user);

    /**
     * 通过id删除
     * @param userId
     */
    public void delete(Integer userId);

    /**
     * 查询总数  聚合函数
     * @return
     */
    public Integer findByCount();

    /**
     * 模糊查询
     * @param username
     * @return
     */
    public List<User> findByName(String username);

    /**
     * 通过汽车名字carName查询
     * @param user
     * @return
     */
    public User findByCarName(User user);
}

UserMapper.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.qcby.mapper.UserMapper">

    <select id="findAll" resultMap="userMap">
        select id _id,username _username,birthday _birthday,sex _sex,address _address from user
    </select>
    <!--
        配置resultMap,用来进行数据封装
        id="唯一的名称,用来被引用的"
        type="进行封装数据的类型"
    -->
    <resultMap id="userMap" type="com.qcby.domain.User">
        <!--
                  property="JavaBean中的属性"
                  column="表中的字段"
              -->
        <result property="id" column="_id"/>
        <result property="username" column="_username" />
        <result property="birthday" column="_birthday" />
        <result property="sex" column="_sex" />
        <result property="address" column="_address" />
    </resultMap>


    <!--通过id查询-->
    <!--#就和jdbc的 ?占位符一样  但#{}和${}区别很大-->
    <select id="findById" parameterType="java.lang.Integer" resultType="com.qcby.domain.User">
        select * from user where id=#{userId}
    </select>

    <!--新增数据、保存操作-->
    <insert id="insert" parameterType="com.qcby.domain.User">
        /*
        keyProperty表示要返回的属性名称
        order取值AFTER表示插入数据后的行为
        resultType表示返回值的类型
        */
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id();
        </selectKey>
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>

    <!-- 修改 -->
    <update id="update" parameterType="com.qcby.domain.User">
        update user set username = #{username},birthday = #{birthday},sex = #{sex},address=#{address} where id = #{id}
    </update>

    <!-- 删除 -->
    <delete id="delete" parameterType="java.lang.Integer">
        delete from user where id = #{userId}
    </delete>

    <!-- 具体函数的查询 -->
    <select id="findByCount" resultType="int">
        select count(*) from user
    </select>


    <!-- 模糊查询 -->
    <select id="findByName" resultType="com.qcby.domain.User" parameterType="String">
        <!-- 第一种方式的SQL语句
        select * from user where username  like #{username}
        -->
        <!-- 第二章SQL语句的编写 强调:'%${value}%'不能修改,固定写法(不推荐使用)
          select * from user where username  like '%${value}%' -->

        select * from user where username  like '%${value}%'
    </select>

    <select id="findByCarName" parameterType="com.qcby.domain.User" resultType="com.qcby.domain.User">
        select * from user where username=#{car.carName}
    </select>


</mapper>

测试代码:

public class TestDemo01 {

    @Test
    /**
     * 第一种方式  通过session创建UserMapper接口的代理对象 调用方法
     */
    public void run () throws IOException {

        // 加载主配置文件, 目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        // 调用查询所有的方法
        List<User> list = mapper.findAll();
        // 遍历集合
        for (User user : list) {
            System.out.println(user);
        }
        // 释放资源
        session.close();
        in.close();
    }

    @Test
    /**
     * 第二种方式  不用代理对象,会话直接获取方法(使用较少)
     */
    public void run2() throws Exception {
        // 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 构建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 获取到session对象
        SqlSession session = factory.openSession();
        // 查询所有的数据
        //不用代理对象,用会话直接获取方法
        List<User> list = session.selectList("com.qcby.mapper.UserMapper.findAll");
        // 变量集合
        for (User user : list) {
            System.out.println(user);
        }
        // 关闭资源
        session.close();
        inputStream.close();
    }

    /**
     * 测试查询单一数据   通过id查询  使用代理对象的形式
     */
    @Test
    public void run3() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        // 调用查询所有的方法
        User user1 = mapper.findById(5);
        System.out.println(user1);
        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

    /**
     * 测试新增数据
     */
    @Test
    public void run4() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        // 调用新增的方法
        User user=new User();
        user.setUsername("小王1");
        user.setBirthday(new Date());
        user.setSex("女");
        user.setAddress("香港");
        mapper.insert(user);

        session.commit();
        System.out.println(user.getId());
        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

    /**
     * 测试修改数据
     */
    @Test
    public void run5() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        User user=new User();
        user.setId(31);
        user.setUsername("beautiful01");
        user.setBirthday(new Date());
        user.setSex("woman02");
        user.setAddress("HongKong03");
        mapper.update(user);
        session.commit();
        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

    /**
     * 测试删除数据
     */
    @Test
    public void run6() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        mapper.delete(31);
        session.commit();
        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

    /**
     * 测试  查询数据总量
     */
    @Test
    public void run7() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        Integer byCount = mapper.findByCount();
        System.out.println(byCount);
        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

    /**
     * 测试  模糊查询
     */
    @Test
    public void run8() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        List<User> userList = mapper.findByName("张");
        for (User user : userList) {
            System.out.println(user);
        }

        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

    /**
     * 测试多表查询查询 根据carname查询
     */
    @Test
    public void run9() throws IOException {
        //1.加载环境
        // 加载主配置文件,目的是构建SqlSessionFactory的对象
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 使用SqlSessionFactory工厂对象创建SqlSession对象
        SqlSession session = factory.openSession();
        // 通过session创建UserMapper接口的代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);

        User user=new User();
        Car car=new Car();
        car.setCarName("张三");
        user.setCar(car);
        User user1 = mapper.findByCarName(user);
        System.out.println(user1);
        //关闭资源 会话关闭
        session.close();
        //流关闭
        in.close();
    }

}

模糊查询符号使用的区别 

  1. 通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
  2. 通过$可以将传入的内容拼接在中且不进行类型转换,${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。

 动态sql

if标签

 
    <select id="findByWhere" parameterType="com.example.domain.User" resultType="com.example.domain.User">
        select * from user where 1 = 1
        <if test="username != null and username != ''">
          and username like #{username}
        </if>
        <if test="sex != null and sex != ''">
            and sex = #{sex}
        </if>
    </select>

where标签

 
    <!--使用where关键字-->
    <select id="findByWhere" parameterType="com.example.domain.User" resultType="com.example.domain.User">
        select * from user
        <where>
            <if test="username != null and username != ''">
                and username like #{username}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
        </where>
    </select>

foreach标签

需要将要用到的数组封装进实体类中

    // 主键
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    
    // 定义ids属性,用来存储所有的id
    private List<Integer> ids;
 
    <!--foreach标签 select * from user where id = 1 or id = 2 or id = 3 -->
    <select id="findByIds" parameterType="com.example.domain.User" resultType="com.example.domain.User">
        select * from user
        <where>
            <foreach collection="ids" open="id = " separator="or id = " item="i">
                #{i}
            </foreach>
        </where>
    </select>

提取公用sql

    <!--提取公共的SQL-->
    <sql id="findAllSql">
        select * from user
    </sql>
 
 
    <select id="findAll" resultType="com.example.domain.User">
        <include refid="findAllSql" />
        /*select * from user*/
    </select>

返回类型封装

account中包含id,uid,money三个基本类型以及一个对象可以使用下面的方式来封装返回的数据。

    <!--进行数据封装-->
    <resultMap id="accountMap" type="com.example.domain.Account">
        <result property="id" column="id" />
        <result property="uid" column="uid"/>
        <result property="money" column="money"/>
        <association property="user" javaType="com.example.domain.User">
            <result property="username" column="username"/>
            <result property="address" column="address"/>
        </association>
    </resultMap>

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值