MyBatis 概念与CRUD

发布时间 2023-05-09 09:35:45作者: 后子子而行

MyBatis

一、 概念与简介

1.1 框架概念 ORM

  • ORM(Object Relational Mapping)对象关系映射,将程序中一个对象与表中的一行数据一一对应

  • ORM映射框架,提供持久化类与表的映射关系,在运行时参照映射文件的信息,把对象持久化到数据库中

    提供动态sql语句(set标签/sql片段/if标签/foreach遍历),提供API(SQlSession里面功能查询列表,直接获取Mapper接口代理对象),日志输出(log4j)

1.2 使用JDBC完成ORM的缺点

  • 存在大量冗余代码
  • 手工创建Connection、Statement等
  • 手工将结果集封装成实体对象
  • 查询效率低,没有对数据访问进行过优化(Not Cache)

1.3 mybatis介绍

  • 基于Java的持久层框架,支持自定义SQL,存储过程和高级映射

  • mybatis框架:"高级JDBC" ,对原有JDBC进行封装,是一个半成品,里面使用大量的设计模式,简化书写代码,提供大了的动态sql语句以及结果映射!

二、mybatis环境搭建 框架部署

2.0 创建maven项目

2.1 在pom.xml中引入mybatis核心依赖

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

<!--MySQL驱动依赖-->

2.2 创建mybatis核心配置文件

创建并配置 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">
<!--xx.dtd是xml文件约束,约束标签-->

<!--mybatis核心配置-->
<configuration>
    <!--jdbc环境配置、选中默认环境-->
    <environments default="mysql">
        <!--MySQL数据库环境配置:可以配置多个环境-->
        <environment id="mysql">
            <!--mybatis事务管理器
                        连接数据库操作
            -->
            <transactionManager type="JDBC"/>
            <!--启用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <!--配置连接池这个类中的属性参数
                    drvier/url/username/password都是
                    org.apache.ibatis.datasource.pooled.PooledDataSource信息
                -->
                <!--驱动类-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的地址 &转义&amp;-->
                <property name="url" value="jdbc:mysql://localhost:3306/myee2302_db_2"/>
                <!--用户名-->
                <property name="username" value="root"/>
                <!--登录密码-->
                <property name="password" value="12345"/>
            </dataSource>
        </environment>


        <!--配置其他环境-->
        <!--<environment id="oracle">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>  -->
    </environments>

    <!--加载mapper映射器 -->
    <mappers>
        <!--配置接口的包名建议和映射文件包结构一致(后面和spring整合值,不一致,指定映射路径地址)-->
        <package name="com.qf.mapper"/>
      <!--  <mapper resource="com/qf/mapper/UserDao.xml"></mapper>-->
    </mappers>

</configuration>

三、MyBatis开发步骤 框架使用

3.1 创建数据表

create table XXX( );

3.2 定义实体类 pojo

定义所需CURD操作的实体类

3.3 定义DAO接口--定义操作方法

mybatis的持久层接口以及它的映射文件 就相当于impl

public interface AccountDao {

    /**
     * 查询所有账户
     * @return 返回账户列表
     */
    List<Account> findAllAccounts() ;
}

3.4 创建DAO接口的映射文件--编写Mapper.xml 注册Mapper

在resources目录中创建Mapper.xml文件

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--映射器的配置
    namesapce:所需实现的接口 名称空间指定接口的完全限定名称
-->
<mapper namespace="com.mapper.AccountDao">
        <!--大量的sql标签
            id:所需要重写的抽象方法,必须和接口文件中的方法名必须一致

            当前接口中的方法有返回值,返回值如果是实体类型或者是List集合
            输出映射:resultType:查询后所需返回的对象类型,必须要指定为当前实体类型的完全限定名称
        -->
    <select id="findAllAccounts" resultType="com.pojo.Account">
        select * from account
    </select>
</mapper>

3.5 将映射文件添加到主配置文件--注册Mapper

将Mapper.xml注册到mybatis-config.xml中

<mappers>
        <!--配置接口的包名建议和映射文件包结构一致(后面和spring整合值,不一致,指定映射路径地址)-->
        <package name="com.qf.mapper"/>
      <!--  <mapper resource="com/qf/mapper/UserDao.xml"></mapper>-->
    </mappers>

四、单元测试

4.1 添加单元测试依赖

MyBatis的API操作方式

//1)准备好jar包 (mybatis核心jar包)
//2)准备mybatis核心配置文件(sql-config.xml/mybatis-config.xml)
  //   配置properties(加载外部配置文件)/配置环境/别名/插件配置/开启二级缓存/配置mapper映射器的包名
//3)准备接口文件和映射文件 
//XxxDao/XxxMapper----->XxxDao.xml/XxxMapper.xml
//4)读取核心配置文件  
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml") ;
//5)创建SqlSessionFactoryBuilder--->public SqlSessionFactory build(InputStream inputStream)
//6)创建执行对象SqlSession
SqlSession sqlSession = sqlSessionFactory对象.openSession() ;
//7)获取接口对象---jdk动态代理
XxxDao xxDao = sqlSession.getMapper(接口类型.class) ;
//8)调用接口方法

4.2 创建单元测试类

4.3 测试代码

public class MybatisTest {

    @Test
    public void testFindAll() throws IOException {
        //1)读取resource下面的mybatis-config.xml文件
        //org.apache.ibatis.io.Resources --InputStream getResourceAsStream(配置文件名称)
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //2)创建一个对象SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder() ;
        //3)创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载流对象 获取到工厂对象
        //4)创建 SqlSession---就是执行对象--底层就是PreparedStatement
        SqlSession sqlSession = sqlSessionFactory.openSession();//自动提交
        //5)获取AccountDao接口对象---通过mybatis的动态代理获取接口对象
        AccountDao accountDao = sqlSession.getMapper(AccountDao.class);//接口类型字节码文件
        //6)调用方法
        List<Account> allAccounts = accountDao.findAllAccounts();
        if(allAccounts!=null || allAccounts.size()>0){
            for(Account account :allAccounts){
                System.out.println(account);
            }
        }
    }
}

五、MyBatis的CRUD操作

5.1 添加操作

5.2 删除操作

根据id删除信息

  • 在DAO中定义删除方法

  • 在XXXmapper.xml中对接口方法进行实现

  • 测试

    public class MyTest {
        private UserDao userDao ;
        private SqlSession sqlSession ;//表示mybatis与数据库之间的会话:通过工厂设计模式
        private AccountDao accountDao ;
    
        @Before//执行单元测试方法之前执行
        public void init() throws IOException {
            //try catch
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //2)创建一个对象SqlSessionFactoryBuilder
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder() ;
            //3)创建SqlSessionFactory mybatis的会话工厂
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载流对象 获取到工厂对象
            //4)创建 SqlSession---就是执行对象--底层就是PreparedStatement
            //表示mybatis与数据库之间的会话,通过工厂方法设计模式
            sqlSession = sqlSessionFactory.openSession(false);//自动提交
    
            //通过sqlsession对象调用getMapper方法获取DAO接口对象
            userDao = sqlSession.getMapper(UserDao.class) ;
            accountDao = sqlSession.getMapper(AccountDao.class) ;
        }
    
        //测试查询所用用户信息
        @Test
        public void testFindAll(){
            List<User> all = userDao.findAll();
            if(all!=null || all.size()>0){
                System.out.println("用户信息是---->");
                for(User user:all){
                    System.out.println(user);
                    List<Account> accounts = user.getAccounts();
                    for(Account account:accounts){
                        System.out.println("包含的账户信息是--->"+account);
                    }
                }
            }
        }
    
        //测试指定多个条件查询用户,加入mybatis动态if标签
        @Test
        public void testFindBycondition(){
            User user = userDao.findUserByCondition("张佳宁","渭南市" );
            System.out.println(user);
        }
    
        //测试更新操作
        @Test
        public void testUpdateUser(){
            User user = new User() ;
            user.setUserId(8) ;
            user.setUserName("刘德华") ;
            user.setUserAge(60) ;
            user.setUserGender("男") ;
    
            userDao.updateUser(user);
        }
    
        //使用mybatis动态sql值foreach标签遍历集合属性
        @Test
        public void testFindUserByQueryVo(){
            QueryVo vo = new QueryVo() ;
            List<Integer> ids = new ArrayList<>() ;
            ids.add(1) ;
            ids.add(2) ;
            ids.add(8) ;
            vo.setIds(ids);
            List<User> users = userDao.findUserByQueryVo(vo);
            if(users!=null || users.size()>0){
                for(User user:users){
                    System.out.println(user);
                }
            }
        }
    
    
        //测试查询所有账户
        @Test
        public void testFindAllAccount(){
            List<Account> allAccount = accountDao.findAllAccount();
            System.out.println("账户的信息是:");
            if(allAccount!=null || allAccount.size()>0){
                for(Account account:allAccount){
                    System.out.println(account);
                    System.out.println("==========================");
                    System.out.println("账户从属于的用户信息是");
                    System.out.println(account.getUser());
                }
            }
        }
    
    
        @After//执行单元测试方法之后执行
        public void commitAndClose(){
            //提交事务
            sqlSession.commit();
            sqlSession.close();
        }
    }
    
    

5.3 修改操作

5.4 查找操作 查所有

实体类的属性名和表字段不对应,只有用户名自动映射,其他值为null

  • 数据库起别名

    <!--解决方案1:查询sql的时候,指定字段别名,和实体类的属性名称对应
            不推荐(当字段的很多的时候,这种不合适)
        -->
       <!-- <select id="findAll" resultType="user">
            SELECT
                id userId,
                username userName ,
                gender userGender,
                age userAge ,
                address userAddress
            FROM
                USER
        </select>-->
    

5.5 查找操作 查一条

5.6 查询操作 查总记录数

5.7 添加主键回填生成的主键

  • StudentMapper.xml的添加操作--insert

    <!--useGeneratedKeys 设置添加操作是否需要回填生成的主键-->
    <!--keyProperty 设置回填的主键值赋值到参数对象的哪个属性-->
    

使用mybatis的mapper代理调用接口方法 -->注意事项

	1)接口文件名和映射文件名称一致
	2)建议 接口文件所在包的结构和映射文件的包结构一致
	3)接口映射文件XxxDao.xml 里面标签的id值必须和接口的方法名一致
	4)映射文件中的namespace名称空间必须指定为"接口的完全限定名称"