项目已托管到GitHub,大家可以去GitHub查看下载!并搜索关注微信公众号 码出Offer 领取各种学习资料!

一、框架概述

1.1 什么是框架?

1.2 什么是ORM框架?

1.3 使用JDBC完成ORM的缺点

二、MyBatis概述

2.1 什么是MyBatis

2.2 官网

2.3 使用

三、搭建MyBatis项目

3.1 创建一个Maven项目

3.2 导入MyBatis依赖

<!--MyBatis核心依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

<!--日志依赖-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<!--MySql驱动依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

3.3 创建MyBatis配置文件

<?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">

<!--MyBatis配置-->
<configuration>
    <!--JDBC环境配置、选中默认环境-->
    <environments default="MySqlDB">
        <!--MySql数据库环境配置-->
        <environment id="MySqlDB">
            <!--事务管理-->
            <transactionManager type="JDBC"/>
            <!--连接池-->
            <dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!-- &转义&amp; -->
                <property name="url" value="jdbc:mysql://localhost:3306/x?useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!--Mapper注册-->
    <mappers>
        <!--注册Mapper文件的所在位置-->
        <mapper resource="xxxMapper.xml"/>
    </mappers>

</configuration>

3.4 建表

create table tb_user
(
    id       int auto_increment
        primary key,
    username varchar(30null,
    password varchar(30null,
    gender   char        null,
    birth    date        null
charset = utf8;

3.5 书写实体类代码

package com.mylifes1110.bean;

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

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private Boolean gender;
    private Date birth;
}

3.6 定义Dao层接口

package com.mylifes1110.dao;

import com.mylifes1110.bean.User;

public interface UserDao {
    User selectUserById(int id);
}

3.7 创建并编写Mapper.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">

<!--namespace:所需实现的接口全限定名-->
<mapper namespace="com.mylifes1110.dao.UserDao">
    <!--id:所需重写的接口抽象方法;resultType:查询后所需返回的对象类型-->
    <select id="selectUserById" resultType="com.mylifes1110.bean.User">
        <!--select标签是查询标签,里面包裹着查询的sql语句,其中id = #{arg0}是id = ?的意思-->
        <!--#{arg0}是指id等于方法中第一个形参,也就是id-->
        select id, username, password, gender, birth from tb_user where id = #{arg0}
    </select>
</mapper>

3.7 注册Mapper

<!--Mapper注册-->
<mappers>
    <!--注册Mapper文件的所在位置-->
    <mapper resource="xxxMapper.xml"/>
</mappers>

3.8 测试方式1(常用)

package com.mylifes1110.dao;

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.IOException;
import java.io.InputStream;

public class UserMapperTest {
    @Test
    public void selectUserByIdTest() throws IOException {
        // 获得读取MyBatis核心配置文件的流对象
        InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
        // 根据流对象构建SqlSession连接对象的工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
        // 通过工厂获得连接对象sqlSession
        SqlSession sqlSession = factory.openSession();
        // 通过连接对象获得接口实现类对象
        UserDao userDaoImpl = sqlSession.getMapper(UserDao.class);
        // 打印结果
        System.out.println(userDaoImpl.selectUserById(1));
    }
}

3.9 测试方式2(了解)

package com.mylifes1110.dao;

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.IOException;
import java.io.InputStream;

public class UserMapperTest {
    @Test
    public void selectUserByIdTest2() throws IOException {
        // 获得读取MyBatis核心配置文件的流对象
        InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
        // 根据流对象构建SqlSession连接对象的工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
        // 通过工厂获得连接对象sqlSession
        SqlSession sqlSession = factory.openSession();
        // 通过连接对象直接调用接口中的方法
        Object o = sqlSession.selectOne("com.mylifes1110.dao.UserDao.selectUserById"1);
        // 打印结果
        System.out.println(o);
    }
}

四、MyBatis框架使用细节

4.1 解决mapper.xml存放在resources以外路径中的读取问题

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include><!-- 新添加 */代表1级目录 **/代表多级目录 -->
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include><!-- 新添加 */代表1级目录 **/代表多级目录 -->
                <include>**/*.properties</include><!--添加properties文件-->
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

4.2 解决JDBC写死问题

创建jdbc.properties配置文件

#jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/temp?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

修改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">

<!--MyBatis配置-->
<configuration>
    <properties resource="jdbc.properties" />
    <!--JDBC环境配置、选中默认环境-->
    <environments default="MySqlDB">
        <!--MySql数据库环境配置-->
        <environment id="MySqlDB">
            <!--事务管理-->
            <transactionManager type="JDBC"/>
            <!--连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <!-- &转义&amp; -->
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--Mapper注册-->
    <mappers>
        <!--注册Mapper文件的所在位置-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

4.3 类型别名

<!--定义别名二选一-->
<typeAliases>
    <!--定义类的别名-->
    <typeAlias type="com.mylifes1110.bean.User" alias="User" />

    <!--自动扫描包,将原类名作为别名-->
    <package name="com.mylifes1110.bean" />
</typeAliases>

4.4 使用log4j日志依赖

向pom.xml文件中添加log4j依赖

<!-- log4j日志依赖 https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

创建并配置log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.com.mylifes1110.dao=TRACE
# 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

日志信息

4.5 注册Mapper

4.5.1 扫描包注册Mapper
<!--扫描包方式Mapper注册-->
<mappers>
    <!--dao层路径-->
    <package name="com.mylifes1110.dao"/>
</mappers>
4.5.2 单一注册Mapper路径问题
<!--Mapper注册-->
<mappers>
    <!--注册Mapper文件的所在位置-->
    <mapper resource="mappers/UserMapper.xml"/>
</mappers>

五、MyBatis的CURD操作

5.1 参数绑定

5.1.1 序号参数绑定
// Dao层接口
User selectUserByUserNameAndPassword(String username, String password);

// Mapper.xml
<select id="selectUserByUserNameAndPassword1" resultType="User">
    SELECT * FROM t_user
    WHERE username = #{arg0} and password = #{arg1}
</select>
5.1.2 注解参数绑定
// Dao层接口
User selectUserByUserNameAndPassword(@Param("username") String username, @Param("password")String password);

// Mapper.xml
<select id="selectUserByUserNameAndPassword2" resultType="User">
    SELECT * FROM t_user
    WHERE username = #{username} and password = #{password}
</select>
5.1.3 Map参数绑定
// Dao层接口
User selectUserByUserNameAndPassword(String username, String password);

// 测试类创建Map集合,封装数据
Map<String, Object> map = new HashMap<>();
// 自定义key,绑定参数
map.put("username""root");
map.put("password""123456");
User user = userDao.selectUserByUserNameAndPassword(map);

// Mapper.xml
<select id="selectUserByUserNameAndPassword3" resultType="User">
    SELECT * FROM t_user
    WHERE username = #{username} and password = #{password}    <!-- 通过key获得value -->
</select>
5.1.4 对象参数绑定
// Dao层接口
User selectUserByUserNameAndPassword(User user);

// Mapper.xml
<select id="selectUserByUserNameAndPassword4" resultType="User">
    SELECT * FROM t_user
    WHERE username = #{username} and password = #{password}    <!-- 对象中取出的字段值 -->
</select>

5.2 查询操作

5.2.1 查询标签
5.2.2 普通查询
// Dao层接口
User selectUserByUserNameAndPassword(@Param("username") String username, @Param("password")String password);

// Mapper.xml
<select id="selectUserByUserNameAndPassword2" resultType="User">
    SELECT * FROM t_user
    WHERE username = #{username} and password = #{password}
</select>
5.2.3 查询总数据条数
// Dao层接口
long selectUserCount();

// Mapper.xml
<select id="selectUserCount" resultType="java.lang.Long">
    select count(1) from tb_user
</select>

// 测试类
@Test
public void selectUserCount() throws IOException 
{
    InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
    SqlSession sqlSession = factory.openSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    System.out.println(userDao.selectUserCount());
}
5.2.4 模糊查询
// Dao层接口
List<User> selectUserListByUsername1(@Param("username") String username);

// Mapper.xml
<select id="selectUserListByUsername1" resultType="com.mylifes1110.bean.User">
    select id, username, password, gender, birth
    from tb_user
    where username like concat('%',#{username},'%')
</select>

// 查询包含Z的username
@Test
public void selectUserListByUsername1() throws IOException 
{
    InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
    SqlSession sqlSession = factory.openSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    System.out.println(userDao.selectUserListByUsername1("Z"));
}

5.3 删除操作

5.3.1 删除标签
5.3.2 删除
// Dao层接口
int deleteUserById(@Param("id") int id);

// Mapper.xml
<delete id="deleteUserById">
    delete from tb_user where id = #{id}
</delete>

5.4 修改操作

5.4.1 修改标签
5.4.2 修改
// Dao层接口
int updateUserById(User user);

// Mapper.xml
<update id="updateUserById">
    update tb_user set
    username = #{username}, password = #{password}, gender = #{gender}, birth = #{birth}
    where id = #{id}
</update>

5.5 新增操作

5.5.1 新增标签
5.5.2 新增
// Dao层接口
int insertUser(User user);

// Mapper.xml
<insert id="insertUser">
    insert into tb_user
    (username, password, gender, birth)
    values 
    (#{username}, #{password}, #{gender}, #{birth})
</insert>

5.6 主键回填操作

5.6.1 什么是主键回填?
5.6.2 主键回填标签
5.6.3 通过last_insert_id()查询主键(int)
// 表使用的是User表

// Dao层接口
int insertUser(User user);

// Mapper.xml
<insert id="insertUser">
<selectKey keyProperty="id" resultType="int" order="AFTER">
    select last_insert_id()<!--适用于整数类型自增的主键-->
</selectKey>
    insert into tb_user
    (username, password, gender, birth)
    values
    (#{username}, #{password}, #{gender}, #{birth})
</insert>

// 测试类
@Test
public void insertOrder() 
{
    OrderDao orderDao = MyBatisUtils.getMapper(OrderDao.class);
    Order order = new Order();
    order.setMoney(11.1D);
    order.setUserId(2);
    System.out.println(orderDao.insertOrder(order));
    System.out.println(order.getId());
    MyBatisUtils.commit();
}
5.6.4 通过uuid()查询主键(String)
// 创建订单表
create table tb_order
(
    id      varchar(32)
 not null
        primary key,
    money   double      null,
    user_id int         null
) charset 
= utf8;

// Dao层接口
int insertOrder(Order order);

// Mapper.xml
<insert id="insertOrder" parameterType="com.mylifes1110.bean.Order">
<selectKey keyProperty="id" resultType="string" order="BEFORE">
    select replace(UUID(), '-', '')
</selectKey>
    insert into tb_order
    (id, money, user_Id)
    values
    (#{id}, #{money}, #{userId})
</insert>

六、封装工具类

6.1 封装工具类分析

6.2 MyBatis工具类

package com.mylifes1110.utils;

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 java.io.InputStream;

/**
 * @ClassName MyBatisUtils
 * @Description MyBatis工具类
 * @Author Ziph
 * @Date 2020/7/11
 * @Since 1.8
 * @Version 1.0
 */

public class MyBatisUtils {
    // 获得SqlSession工厂
    private static SqlSessionFactory factory;

    // 创建ThreadLocal绑定当前线程中的SqlSession对象
    private static final ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>();

    static {
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获得连接(从tl中获得当前线程SqlSession)
    private static SqlSession openSession(){
        SqlSession session = tl.get();
        if(session == null){
            session = factory.openSession();
            tl.set(session);
        }
        return session;
    }

    // 释放连接(释放当前线程中的SqlSession)
    public static void closeSession(){
        SqlSession session = tl.get();
        session.close();
        tl.remove();
    }

    // 提交事务(提交当前线程中的SqlSession所管理的事务)
    public static void commit(){
        SqlSession session = openSession();
        session.commit();
        closeSession();
    }

    // 回滚事务(回滚当前线程中的SqlSession所管理的事务)
    public static void rollback(){
        SqlSession session = openSession();
        session.rollback();
        closeSession();
    }

    // 获得接口实现类对象
    public static <T extends Object> getMapper(Class<T> clazz){
        SqlSession session = openSession();
        return session.getMapper(clazz);
    }
}
07-12 04:43