mybatis笔记

mybatis笔记,第1张

mybatis笔记

MyBatis笔记
  • MyBatis笔记
    • 一.概述
    • 二. MyBatis 环境搭建
    • 三.创建Mybatis项目步骤
      • 步骤:
        • 1.根据需求设计一个类与数据库的表
        • 2.接口(Mapper),实现对类的一些 *** 作
        • 3.全局配置文件(mybatis.xml)配置信息
          • `< typeAliases>`为类定义别名
          • 配置`< mapper>`(添加SQL映射文件)
          • 设置
            • Mybatis日志
          • 配置环境
          • 创建config. properties(存储与数据库连接的信息)
          • 引入config. properties
        • 4.接口对应的配置文件(AdminMapper.xml)
      • 驼峰映射
      • 封装步骤
      • 单元测试
      • 类型别名
      • 参数传递
          • 1.简单的参数形式不需要使用 parameterType 参数定义
          • 2. 多个参数使用@Param(“id”)绑定
        • 3.传入复杂的参数,使用Map对象传递
      • 结果处理
        • 简单类型输出映射
        • POJO对象输出映射
      • 多表关联处理查询结果集

MyBatis笔记 一.概述

MyBatis原是Apache的一个开源项目iBatis, 2010年由Apache Software Foundation 迁移到了 Google Code, iBatis3.x正式更名为MyBatis。是 一个基于Java的持久层框架。 iBatis提供的持久层框架包括SQL Maps和Data Access Objects (DAO)。

MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录,是 一种 ORM(ORM Object Relational Mapping 对象关系映射)实现. Mybatis 将基本的 JDBC 常用接口封装,对外提供 *** 作即可.

  • 是一个ORM框架.
    ORM(Object Relational Mapping)对象关系映射
  • 封装了一些关于数据库 *** 作的接口,代替了JDBC
  • 对jdbc进行了封装,简化了其 *** 作

Mybatis 中文官网: mybatis – MyBatis 3 | 入门

既然mybatis封装了JDBC,那么来看一下传统JDBC和MyBatis的区别

我们使用mybatis做一个小demo来看一下和传统JDBC的区别

使用maven构建一个Mybatis,在这里我使用的工具是IDEA

传统JDBC:

  1. 加载数据库驱动
  2. 创建并获取数据库链接
  3. 创建 statement 对象
  4. 拼写 sql 语句
  5. 设置 sql 语句中的占位符的值 (使用预编译可以防止sql注入)
  6. 执行 sql 语句并获取结果
  7. 对 sql 执行结果进行解析处理
  8. 释放资源

JDBC的编程问题

  • 数据库连接的创建、释放频繁造成系统资源浪费从而影响系统性能,如果使 用数据库连接池可解决该问题。
  • SQL 语句编写在 Java 代码中,这种硬编码造成代码不易维护,当 SQL 变动 时需要修改 java 源代码。
  • 使用 preparedStatement 向占位符传参数存在硬编码,因为 SQL 语句的 where 条件中占位符的个数可能会变化,修改 SQL 还要修改 Java 源代码, 系统不易维护.
  • 对结果集解析存在硬编码,SQL 语句变化导致解析代码变化,系统不易维护。
二. MyBatis 环境搭建
  1. 先创建一个maven的项目(搭建maven:https://blog.csdn.net/lanleihhh/article/details/120978091)

  2. 导入mybatis/mysql的坐标(maven仓库下载:https://mvnrepository.com/)

复制后粘贴到中

	
        
            org.mybatis
            mybatis
            3.4.6
        

        
        
            mysql
            mysql-connector-java
            8.0.25
        

点击’M’形状的按钮安装jar包

我们可以使用日志组件(log4j)来记录程序的信息,引入log4j的坐标

		
        
            log4j
            log4j
            1.2.17
        

注意:引入log4j的坐标后,还需在resources文件中添加配置文件:log4j.properties

log4j.rootLogger = debug,stdout,D
#System out Console
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%p] %d{yyyy-MM-dd HH:mm:ss,SSS} %m%n

#System out File
log4j.appender.D = org.apache.log4j.FileAppender
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
	# 这里设置打印日志的文件路径
log4j.appender.D.File = E://logs/mybatisLog/LogMybatisDemo.log
	
log4j.appender.D.Append = true
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ] -[%l] %m%n

创建 MyBatis 全局配置文件 MyBatis 的配置文件包含了对 MyBatis 行为的设置信息。

配置文档的顶层 结构如下(标签需要按照特定顺序排放):

  • configuration(配置)
  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
    • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

如下:





    
    
        
        
            
            
            
            
                
                
                
                
                
            
        
    
    
    
    
        
    

三.创建Mybatis项目步骤 步骤: 1.根据需求设计一个类与数据库的表

Java类:

package com.ffyc.mybatispro.model;

public class Admin {
    private int id;
    private String account;
    private String password;
    private String sex;
    
    public int getId() {
        return id;
    }

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

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSex() {
        return sex;
    }

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

    @Override
    public String toString() {
        return "Admin{" +
                "id=" + id +
                ", account='" + account + ''' +
                ", password='" + password + ''' +
                ", sex='" + sex + ''' +
                ", userName='" + userName + ''' +
                '}';
    }
}

数据库表:

CREATE DATAbase mybatis_db CHARSET utf8

CREATE TABLE admin(
  id INT PRIMARY KEY AUTO_INCREMENT,
  sex CHAr(1),
  account VARCHAr(20),
  PASSWORD VARCHAr(20)
)

2.接口(Mapper),实现对类的一些 *** 作
package com.ffyc.mybatispro.mapper;
import com.ffyc.mybatispro.model.Admin;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface AdminMapper {
    //插入
    void saveAdmin(Admin admin);

    //更新
    void updateAdmin(Admin admin);

    //删除
    void deleteAdmin(int AdminId);

    //修改
    Admin findAdminById(int AdminId);

    //传多个参数,使用注解标签@Param("acc")  acc:传向xml文件中 #{acc}
    Admin findAdmin(@Param("acc")String account,@Param("sex")String sex);

    //传入键值对参数
    Admin findAdmin(Map map);

    //查询所有管理员对象
    List findAllAdmin();

    //查询管理员总人数
    int adminCount();
}
3.全局配置文件(mybatis.xml)配置信息

几个.xml配置文件的区别

< typeAliases>为类定义别名
  • type:全类名
  • alias:别名
	
    
        
    
配置< mapper>(添加SQL映射文件)

设置 Mybatis日志

Mybatis 内置的日志工厂提供日志功能,具体的日志实现有以下几种方式:

  • SLF4J
  • LOG4J
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING
  • NO_LOGGING

具体选择哪个日志实现由 MyBatis 的内置日志工厂确定。它会使用最先找到的配置日志


    
    

配置环境
   
        
        
            
            
            
            
         		
                
                
                
                
            
        
    
创建config. properties(存储与数据库连接的信息)
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username=root
password=lanlei6843
引入config. properties

4.接口对应的配置文件(AdminMapper.xml)




    	
	
        insert into admin(account,password,sex,user_name)values(#{account},#{password},#{sex},#{userName})
    

测试方法:saveAdmin()

package com.ffyc.mybatispro.test;

import com.ffyc.mybatispro.mapper.AdminMapper;
import com.ffyc.mybatispro.model.Admin;
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.IOException;
import java.io.InputStream;
import java.io.Reader;


public class Test1 {
    public static void main(String[] args) throws IOException {
        Admin admin = new Admin();
              admin.setAccount("admin");
              admin.setPassword("123");
              admin.setSex("男");
        
        
        InputStream reader = Resources.getResourceAsStream("mybatis.xml");

        
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

        
        SqlSession sqlSession= sqlSessionFactory.openSession();
        //获得映射接口的代理对象
        //MapperProxy动态实现了自定义接口
        //adminMapper对象实质是MapperProxy对象 org.apache.ibatis.binding.MapperProxy@79ad8b2f
        //使用代理对象
        AdminMapper adminMapper =  sqlSession.getMapper(AdminMapper.class);
                    adminMapper.saveAdmin(admin);
                    sqlSession.commit();//提交事务
                    sqlSession.close();//关闭与数据库会话连接

    }
}

运行一下:

查看数据库:

我们使用另一中传值方式


        insert into admin(account,password,sex)values('${account}','${password}','${sex}')
    

运行:

	传列:  ${属性名}
    传值: 
	'${属性名}':${} 拼接符,会传入参数字符串,取值以后再去编译 SQL 语句,$方式无法防止sql注入
	#{属性名} :#{} 占位符,是经过预编译的,编译好 SQL 语句再取值,#方式能够防止 sql 注入
	values('','',''):字符串拼接方式
    values(?,?,?):预编译,是安全的,可以防止sql注入

注意:MyBatis 排序时使用 order by 动态参数时需要注意,用$而不是#
驼峰映射

在mybatis中默认java属性名和数据库字段名一一对应

如:

java: account

mysql:account

但两者定义语法不同

  • java属性采用小驼峰(userName)
  • 数据字段采用下划线(user_name)

很多时候没法将Java属性与数据库字段定义为相同的,因为要遵循规范

解决方法:

  1. 在sql语句中使用As设置别名,如(user_name As userName),设置与Java属性相同

  2. mybatis的settings配置中有一个name为mapUnderscoreToCamelCase的参数,默认是false,设置为true,即可开启驼峰映射

    可以从Java属性userName映射到数据库字段user_name,方便了很多


我们测试一下

在数据库中修改表列命名为经典下划线

-- 修改列名
ALTER TABLE admin CHANGE PASSWORD pass_word VARCHAr(20) 

在java中修改属性

//private String password;原属性
private String passWord;

sql映射中修改sql语句

insert into admin(account,pass_word,sex)values(#{account},#{passWord},#{sex})

测试运行:

成功运行了,这就是驼峰映射

我们将属性与字段再修改为原来的password

封装步骤

将步骤繁多的流程封装起来,我们使用的时候直接访问该封装类的方法

package com.ffyc.mybatispro.util;

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

public class MybatisUtil {

    static SqlSessionFactory sqlSessionFactory = null;

    static {
        
        InputStream reader = null;
        try {
            reader = Resources.getResourceAsStream("mybatis.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }

    public static SqlSession getSqlSession(){//返回sqlSession对象
        return sqlSessionFactory.openSession();
    }
}
单元测试

概念

  • java单元测试是最小的功能单元测试代码

  • 单元测试就是针对某个Java方法的测试

  • java程序的最小功能单元是方法

使用单元测试的好处

  • 不用再在main()方法中一个一个调用,测试完毕后再删除
  • 确保单个方法正常运行
  • 每个单元测试用例相对独立,不需要添加额外语句
  • 只需查看测试结果,就可以了解整个项目的的方法接口是否通畅

我们借助juit工具进行测试

先在pom.xml中依赖单元测试的jar包,将其jar包下载到本地仓库中,然后依赖它

		
        
            junit
            junit
            4.12
            provided
        

在想要测试的方法前添加注解标签@Test,如下:

	@Test
    public void update(){
        Admin admin = new Admin();
        admin.setAccount("admin");
        admin.setPassword("123456");
        admin.setSex("男");
        //创建SqlSession对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        //获取代理对象
        AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);
        mapper.updateAdmin(admin);
        sqlSession.commit();//提交事务
        sqlSession.close();//关闭连接
    }

类型别名

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:


    

    
    	

当这样配置时,Admin可以在任何使用 com.ffyc.mybatispro.model.Admin 的地方。

可以在mybatis的jar包中找org.apache.ibatis.type.TypeAliasRegistry

里面定义了各种基本类型和引用类型的别名;如图

下面是mybatis为Java类库中的一些类和简单类型定义的别名

别名映射的类型_bytebyte_longlong_shortshort_intint_integerint_doubledouble_floatfloat_booleanbooleanstringStringbyteBytelongLongshortShortintIntegerintegerIntegerdoubleDoublefloatFloatbooleanBooleandateDatedecimalBigDecimalbigdecimalBigDecimalobjectObjectmapMaphashmapHashMaplistListarraylistArrayListcollectionCollectioniteratorIterator 参数传递 1.简单的参数形式不需要使用 parameterType 参数定义

如:

	//删除
    void deleteAdmin(int AdminId);

    //修改
    Admin findAdminById(int AdminId);	
	
    
        delete from admin where id=#{id}
    

    
	
        SELECT * FROM admin WHERe account=#{acc} and sex=#{sex}
    

java测试代码

 	@Test
    public void find3(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);
        Admin admin = mapper.findAdmin("admin","男");
        System.out.println(admin);
        sqlSession.commit();
        sqlSession.close();
    }

3.传入复杂的参数,使用Map对象传递

Mapper接口方法

	//传入键值对参数
    Admin findAdmin(Map map);

xml中的实现

对于简单类型可不写parameterType属性,使用Java类库中的类作为参数时,使用mybatis为其定义的别名

这里可以通过mybatis3官方手册查看,XML配置–>类型别名https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases

    
	
        SELECT count(*) FROM admin
    
	@Test
    public void find6(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);
        int count = mapper.adminCount();
        System.out.println("管理员总人数:"+count);
        sqlSession.commit();
        sqlSession.close();
    }

POJO对象输出映射
  • 如果表中的类名与类中的属性名完全相同,mybatis会自动将查询结果封装 到POJO对象中
  • 如果java中使用标准驼峰命名,数据库中使用下划线连接命名,可以开启全局设置实现自动转换

resultMap:

  • resutlMap 的 id 属性是 resutlMap 的唯一标识
  • resutlMap 的 id 属性是映射的 POJO 类
  • id 标签映射主键,result 标签映射非主键
  • property 设置 POJO 的属性名称,column 映射查询结果的列名称

将admin表中列名password修改为pass_word

	
        SELECT
        d.id,
        d.name dname,
        e.name ename,
        a.account
        FROM dept d LEFT JOIN employee e ON d.id=e.dept_id
                     LEFT JOIN admin a ON d.admin_id=a.id
                     WHERe d.id=1
    

    

    
    
        
        
        
            
        
        
            
        
    
    

测试根据id查部门

	@Test
    public void  findDept(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);

        Dept dept = mapper.findDeptById(1);
        List deptList = dept.getEmployeeList();
        System.out.println("部门"+dept.getName());
        for(Employee employee : deptList){
            System.out.println("所属员工:"+employee.getName());
        }
        sqlSession.commit();
        sqlSession.close();
    }

测试查所有部门

	@Test
    public void  findDeptList(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        List depts = mapper.findDeptList();
        for(Dept dept : depts){
            System.out.println("部门名称:"+dept.getName());
            for(Employee emp : dept.getEmployeeList()){
                System.out.println("部门职工:"+emp.getName());
            }
            System.out.println(" *** 作人:"+dept.getAdmin().getAccount());
        }
        sqlSession.commit();
        sqlSession.close();
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4968583.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-13

发表评论

登录后才能评论

评论列表(0条)

保存