栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MyBatis学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MyBatis学习笔记

MyBatis

ORMapping: Object Relationship Mapping 对象关系映射
对象指⾯向对象
关系指关系型数据库
Java 到 MySQL 的映射,开发者可以以⾯向对象的思想来管理数据库。
Mybatis是对JDBC的一个封装
SQL写在了XML里面,耦合度不高。(java程序不用怎么改了)
缺点是要写很多的SQL语句,然后你写的这些SQL语句都是依赖于你的数据库的,你数据库改起来不是很方便,移植性差。
(hibernate是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行)

如何使用
  • 新建Maven工程,pom.xml


    4.0.0

    com.southwind
    aiMybatis
    1.0-SNAPSHOT

    
        8
        8
    
    
        
            org.mybatis
            mybatis
            3.4.5
        
        
            mysql
            mysql-connector-java
            5.1.44
        
        
            org.projectlombok
            lombok
            1.18.6
            provided
        
    
    
        
            
                src/main/java
                
                    **/*.xml
                
            
        
    


在这里插入代码片
  • 新建数据表
use mybatis;
create table t_account(
 id int primary key auto_increment,
 username varchar(11),
 password varchar(11),
 age int
) 
  • 新建数据表对应的实体类Account(在 java 里创建一个com.southwind.entity的package)
package com.southwind.entity;

import lombok.Data;

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

  • 创建MyBatis的配置文件config.xml



    
    
        
            
            
            
            
                
                
                
                
                
                
            
        
    

    
    
        
    

使用原生接口

1、MyBatis 框架需要开发者⾃定义 SQL 语句,写在 Mapper.xml ⽂件中,实际开发中,会为每个实体
类创建对应的 Mapper.xml ,定义管理该对象数据的 SQL。




    
        insert into t_account(username,password,age) values(#{username},#{password},#{age})
    

(插播一下我们的表t_account长这个样子,怕看到后面忘了)

  • namespace 通常设置为⽂件所在包+⽂件名的形式。
  • insert 标签表示执⾏添加操作。
  • select 标签表示执⾏查询操作。
  • update 标签表示执⾏更新操作。
  • delete 标签表示执⾏删除操作。
  • id 是实际调⽤ MyBatis ⽅法时需要⽤到的参数。
  • parameterType 是调⽤对应⽅法时参数的数据类型。
  • #会把传入的数据都当成一个字符串来处理,会在传入的数据上面加一个双引号来处理。而$则是把传入的数据直接显示在sql语句中,不会添加双引号。

2、在全局配置⽂件 config.xml 中注册 AccountMapper.xml(就是刚刚写好的对象和数据库之间的对应关系)




    
    
        
            
            
            
            
                
                
                
                
                
                
            
        
    

    
    
        
    

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.AccountMapper.save";
        Account account = new Account(1L, "张三", "123123", 22);
        sqlSession.insert(statement, account);
        sqlSession.commit();
        sqlSession.close();

    }
}


通过mapper代理实现自定义接口
  • 自己定义增删改查的接口(也就是写相应的业务代码)
  • 自己去写接口对应的mapper.xml,mapper里写sql,与对象数据进行交互

1、自定义接口
D:mysoft_downloadaiMybatissrcmainjavacomsouthwindrepositoryAccountRepository.java

package com.southwind.repository;

import com.southwind.entity.Account;

import java.util.List;

public interface AccountRepository {
    //返回int值
    public int save(Account account);
    public int update(Account account);
    public int deleteById(long id);
    public List findAll();
    public Account find(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 和接⼝中对应⽅法的返回值类型⼀致。

D:mysoft_downloadaiMybatissrcmainjavacomsouthwindrepositoryAccountRepository.xml

resultType是int可以不用写,list<“T”> 作为返回值写T的全类名就行。
全类名是指com.southwind.entity.Account,Account.java是实体类
返回int是指这次sql操作改变了多少行数据
没有输入参数,可以不写parameterType




    
        
        insert into t_account(username,password,age) values(#{username},#{password},#{age})
    

    
        update t_account set username = #{username},password = #{password},age = #{age} where id = #{id}
    

    
        delete from t_account where id = #{id}
    

    
        select * from t_account where id = #{id}
    



3、在 config.xml 中注册 AccountRepository.xml
D:mysoft_downloadaiMybatissrcmainresourcesconfig.xml

    
    
        
        
    

4、调⽤接⼝的代理对象完成相关的业务操作
D:mysoft_downloadaiMybatissrcmainjavacomsouthwindtestTest1.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 Test1 {
    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();
        //获取实现接口的代理对象
        AccountRepository accountRepository = sqlSession.getMapper(AccountRepository.class);
//        //1.测试添加对象
//        Account account1 = new Account(6L,"张三","1231111",18);
//        accountRepository.save(account1);
//        //改变之后要提交commit
//        sqlSession.commit();
//        //使用完要关闭close
//        sqlSession.close();
//        //2.测试更新对象
//        Account account1 = new Account(6L,"张三","1231111",22);
//        int result = accountRepository.update(account1);
//        System.out.println(result);
//        sqlSession.commit();
//        sqlSession.close();
//        //3.测试删除方法
//        int result = accountRepository.deleteById(5L);
//        sqlSession.commit();
//        sqlSession.close();
//        //4.测试findAll方法
//        List lists= accountRepository.findAll();
//        for(Account list:lists){
//            System.out.println(list);
//        }
//        sqlSession.close();
        //5.测试find方法
        System.out.println(accountRepository.find(6L));
        sqlSession.close();

    }
}

(以上代码配合Navicat观察数据库对象食用,注意好像用Navicat直接删除对象之后,再添加对象的id也就是主键是有问题的!!!)

mapper.xml
  • statement 标签:select、update、delete、insert 分别对应查询、修改、删除、添加操作
  • parameterType:参数数据类型
    1、剧本数据类型,通过id查询Account
    src/main/java/com/southwind/repository/AccountRepository.xml

        select * from t_account where  id = #{id}
    

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

src/main/java/com/southwind/repository/AccountRepository.java

public Account findByNameAndAge(String name,int age);

src/main/java/com/southwind/repository/AccountRepository.xml


 select count(id) from t_account


2、包装类,统计 Account 总数


 select username from t_account where id = #{id}

4、Java Bean


        select s.id as student_id,s.name student_name,c.id as class_id,c.name as class_name from student s,classes c where s.id = #{id} and s.cid = c.id
    

在config.xml中注册StudentRepository.xml

    
    
        
        
        
    

建立测试函数
src/main/java/com/southwind/test/Test2.java

package com.southwind.test;

import com.southwind.repository.StudentRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test2 {
    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();
        //获取实现接口的代理对象
        StudentRepository studentRepository = sqlSession.getMapper(StudentRepository.class);
        System.out.println(studentRepository.findById(2L));
        sqlSession.close();
    }
}

主体思路就是,先写一个接口类StudentRepository.java,因为我要写关于他的一些操作方法,增删改查之类的,这里只写了一个方法findById。
通过student 的id,返回一个Student的对象,具体怎么实现,怎么从Mysql中拿到数据,然后再映射到Student这个对象上,要看下面的Mapper怎么写。

StudentRepository.xml 先利用sql语句从Mysql中拿数据,然后通过studentMap将Mysql的结果与对象进行映射。

Test2.java,具体实现就比较简单啦!

输出Classes对象

创建学生接口方法与对应的Mapper
src/main/java/com/southwind/repositoryClassesRepository.java

package com.southwind.repository;

import com.southwind.entity.Classes;

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

src/main/java/com/southwind/repository/ClassesRepository.xml




    
        
        
        
            
            
        
    


    
        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;
    

写src/main/resources/config.xml

    
    
        
        
        
        
        

    

写src/main/java/com/southwind/test/Test3.java

package com.southwind.test;

import com.southwind.repository.CustomerRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test3 {
    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();
        CustomerRepository customerRepository =sqlSession.getMapper(CustomerRepository.class);
        System.out.println(customerRepository.findById(1L));
        sqlSession.close();
    }
}

最后输出结果如下,符合预期

输出Goods对象

在输出customer对象的时候就已经定义好了Customer 和Goods这两个对象,只需要开始写对应的方法接口和mapper文件,并在config.xml中注册,并调用业务方法进行测试就行了。
src/main/java/com/southwind/repository/GoodsRepository.java

package com.southwind.repository;

import com.southwind.entity.Goods;

public interface GoodsRepository {
    public Goods findById(long id);
}

src/main/java/com/southwind/repository/GoodsRepository.xml




    
        
        
        
            
            
        
    


    
        select c.id ,c.name from classes c where c.id = #{id}
    

src/main/java/com/southwind/repository/StudentRepository.java
(写好方法接口)

public Student findByIdLazy(long id);

src/main/java/com/southwind/repository/StudentRepository.xml

    
        
        
        
    


    
        select * from t_account
    

    
        select * from t_account where username = #{name}
    

    
        select * from t_account where username = #{arg0} and age = #{arg1}
    




  • 实体类实现序列化接⼝

src/main/java/com/southwind/entity/Account.java

package com.southwind.entity;

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

import java.io.Serializable;

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

测试类


2、ehcache ⼆级缓存

  • pom.xml 添加相关依赖
        
            org.mybatis
            mybatis-ehcache
            1.0.0
        
        
            net.sf.ehcache
            ehcache-core
            2.4.3
        
        
        
            org.slf4j
            slf4j-simple
            1.7.25
        

  • 添加 ehcache.xml
    src/main/resources/ehcache.xml

    
    
    

  • config.xml 配置开启⼆级缓存
    
        
        
        
        
        
        
    

  • Mapper.xml 中配置⼆级缓存
    src/main/java/com/southwind/repository/AccountRepository.xml
    
        
        
        
        
        
        
    
  • 实体类不需要实现序列化接⼝(不需要像自带二级缓存那样了)
package com.southwind.entity;

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

import java.io.Serializable;

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

  • 测试方法
    src/main/java/com/southwind/test/Test6.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;

public class Test6 {
    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();
        AccountRepository accountRepository = sqlSession.getMapper(AccountRepository.class);
        Account account = accountRepository.findById(6L);
        System.out.println(account);
        sqlSession.close();
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        AccountRepository accountRepository2 = sqlSession2.getMapper(AccountRepository.class);
        Account account1 = accountRepository2.findById(6L);
        System.out.println(account1);
        sqlSession.close();
        System.out.println("account:"+account.hashCode()+"   account1:"+account1.hashCode());

    }
}

结果


从实验结果可以看到,不同sqlsession只进行了一次查询,并且得到的两个对象的hashcode是相同的。

MyBatis 动态 SQL
  • 现在先尝试说修改一下接口和mapper,来演示一下动态sql的用处,因为sql是写在mapper里的嘛,所以mapper文件肯定是要改的,然后就是接口方法可能就是说用来演示sql需要用到新的查询方法。教程里是根据一个部分初始化的Account的对象,从数据库中找到对应的数据,然后再返回一个或者多个完整的Account对象,看起来有点脱裤子放屁的感觉,不过为了演示的话,就这样了吧,之后遇到实际的场景再说。

src/main/java/com/southwind/repository/AccountRepository.java

 public Account findByAccount(Account account);

src/main/java/com/southwind/repository/AccountRepository.xml

    
    select * from t_account 
    
        
            
                id = #{id}
            
            
                username = #{username}
            
            
                password = #{password}
            
            
                age = #{age}
            
        
    

trim 标签

trim 标签中的 prefix 和 suffix 属性会被⽤于⽣成实际的 SQL 语句,会和标签内部的语句进⾏拼接,如
果语句前后出现了 prefixOverrides 或者 suffixOverrides 属性中指定的值,MyBatis 框架会⾃动将其删
除。


    select * from t_account
    
        
            #{id}
        
    

结果
也算是用到for-each。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/874076.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号