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

MyBatis基础篇

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

MyBatis基础篇

MyBatis基础篇 简介

注意:本篇文章主讲语法,jar包导入大家可以在网上搜索(有问题一定要学会利用搜索引擎解决!!!),全程代码会写到文章中。

     1.  MyBatis是一个半自动ORM框架(作为解决数据库发展和面向对象发展不一致的问题)

​ O:objict—面向对象

​ R:relation—关系型数据库

​ M:map—映射

​ 半自动:mybatis框架需要我们手写sql语句

​ mybatis框架不依赖于服务器

  1. 优点:

    (1):解决了SQL语句和Java代码之间的耦合

    (2):连接数据库速率比较快

    (3):取值问题会变得非常简单

数据准备
1.Flower类
mysql> select * from flower;
+----+-----------+-----------+------------+
| id | name      | price     | production |
+----+-----------+-----------+------------+
|  1 | 玫瑰花    |        15 | 中国       |
|  2 | 夕颜      |        18 | 中国       |
|  5 | 满天星    |      1314 | 挪威       |
|  6 | 牡丹      |         5 | 中国       |
|  7 | 丁香      |       188 | 锦州       |
|  8 | 杜鹃      |      1688 | 金陵       |
|  9 | 琉璃      |     18888 | 临安       |
| 10 | 彼岸花    | 188888888 | 黄泉       |
| 11 | 玫瑰花    |        15 | 咸阳       |
+----+-----------+-----------+------------+
9 rows in set (0.00 sec)

2.Student类
mysql> select * from student;
+-----+--------+---------+
| sid | sname  | clazzno |
+-----+--------+---------+
|   1 | 张三   |       1 |
|   2 | 李四   |       1 |
|   3 | 王五   |       2 |
|   4 | 赵六   |       3 |
|   5 | 田七   |       4 |
+-----+--------+---------+
5 rows in set (0.00 sec)

3.Clazz类
mysql> select * from clazz;
+---------+-----------------+
| clazzno | cname           |
+---------+-----------------+
|       1 | 505java班       |
|       2 | 509java班       |
|       3 | 402AI班级       |
|       4 | 203前端班级     |
+---------+-----------------+
4 rows in set (0.00 sec)
第一部分(基础) 框架代码
1.创建实体类(Flower)
    
package pers.szs.entity;

public class Flower {

    private Integer id;
    private String name;
    private Integer price;
    private String production;

    public Flower() {
    }

    public Flower(Integer id, String name, Integer price, String production) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.production = production;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public String getProduction() {
        return production;
    }

    public void setProduction(String production) {
        this.production = production;
    }

    @Override
    public String toString() {
        return "Flower{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", price=" + price +
                ", production='" + production + ''' +
                '}';
    }
}

        
  

        
2.配置mybatis.xml文件
    






      

    
      
          
    

    
    

        
        
    


    
      

           

              

              

                
                
                
                

            

        

    


    
    
        
        

    





属性文件(jdbc.properties):
    
m_driver=com.mysql.cj.jdbc.Driver
m_url=jdbc:mysql://localhost:3306/mybatis2?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
m_user=root
m_password=******
    
 日志文件(log4j.properties):
 log4j.rootCategory=error,console,logfile

log4j.logger.pers.szs.mapper=debug

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=- %m%n

log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=d:/bjsxt.log
log4j.appender.logfile.Append=true
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%-4r [%t] %-5p %c %x -%m%n

 
    
注:
    日志记录等级:
    FATAL>ERROR>WAR>INFO>DEBUG 
   
 

接口(FlowerMapper)
package pers.szs.mapper;

import pers.szs.entity.Flower;

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

public interface FlowerMapper {

    //1.查询所有信息
    List selectAll();


    //2.按照参数查询

    List selectMore1(int id);
    List selectMore2(String name,String production);
    List selectMore3(Flower flower);
    List selectMore4(Map map);
    
    //3.添加操作

    int insert1(int id,String name,int price,String producton);

    int insert2(Flower flower);
    
     //4.修改操作

    int update(int id,String name,int price,String producton);

    //5.删除操作
    int delete(int id);

    
}

FlowerMapper.xml










    

        id,name,price,production

    

    
    

        select * from flower where id=#{param1}

    


    

        
        select * from flower where name=#{name} and production=#{production}

    

    

        select * from flower


        
        

            

                name=#{param1}

            

            
                and production=#{param2}

            


        


    

    
    
        
        
        select * from flower where id in

        

            #{item}

        

        
    


    
        
        select * from flower 
        
        

            
                
                

                name like #{pa1}
            


            

                

                production like #{pa2}

            
            
        
        
    
    
    
    
    
    
    

        update flower

        
        

           

               name=#{name},

           

            

                price=#{price},
            

            

                production=#{production}

            

        

        where id=#{id}

    


    

        update flower

        

            

                name=#{name},

            

            

                price=#{price},
            

            

                production=#{production}

            


        

        where id=#{id}


    



疑难点:第一个update操作 name like ‘%${name}%’ 为什么不能直接写 name like ‘%#{name}%’,反而却要利用bind标签

因为"#“底层为占位符’?’,” " 底 层 为 直 接 拼 写 , 而 此 处 不 支 持 占 位 符 , 所 以 只 能 用 ′ "底层为直接拼写,而此处不支持占位符,所以只能用' "底层为直接拼写,而此处不支持占位符,所以只能用′'或者利用bind标签解决

其实学到这里大家对于mybatis应该都有了自己的理解,我个人认为mybatis关键在于一个字"拼";

好了,闲话少说,接下来继续学习多表查询

第三部分(多表查询)

三种方式:业务代码的方式

​ N+1

​ 多表查询SQL

StudentMapper(Intreface)

package pers.szs.mapper;

import pers.szs.entity.Clazz;
import pers.szs.entity.Student;

import java.util.List;

public interface StudentMapper {

    //查询所有学生的信息
    List selectAll();


    List selectAll2();

    List selectAll3();

    //按照班级编号查询班级信息
    Clazz selectOne(int clazzno);


    //根据班级编号查询学生信息
    List selectMore(int clazzno);
}

StudentMapper.xml






    

        select * from student

    

    

        select * from student

    
    


        
          
          
          

        
        

    

    
    

    select * from clazz where clazzno=#{param1}



    
    

        select * from student where clazzno=#{param1}

    

    
    

        select * from student s join clazz c on s.clazzno=c.clazzno

    

    

        
        

        

            

            
            

        


    


1.业务代码的方式(完全通过Java代码来实现多表查询)

(通过查询学生信息获取clazzno,再通过clazzno来查询班级信息)

package pers.szs.test;

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 pers.szs.entity.Clazz;
import pers.szs.entity.Flower;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.FlowerMapper2;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestB {
    public static void main(String[] args) throws IOException {

        //解析mybatis.xml文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");


        //创建sqlSession工厂

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

        //创建sqlSession对象

          //openSession(bool b) b默认为false:事务不会自动提交(即update,delete,insert操作不会自动提交至数据库,会保存到内存中,需要手动提交)
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //调用方法

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);


        List studentList = studentMapper.selectAll();

        for(Student student:studentList){

            Integer clazzno = student.getClazzno();

            Clazz clazz = studentMapper.selectOne(clazzno);

            System.out.println(student+"--->"+clazz);


        }

        System.out.println("===================================================================================");

        for(Student student:studentList){

            Integer clazzno = student.getClazzno();

            Clazz clazz = studentMapper.selectOne(clazzno);

            student.setClazz(clazz);

            System.out.println(student);

        }


        //关闭资源

        sqlSession.close();

    }
}

(通过查询班级信息获取clazzno,再通过clazzno来查询学生信息)

package pers.szs.test;

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 pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestC {
    public static void main(String[] args) throws IOException {

        //解析mybatis.xml文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");


        //创建sqlSession工厂

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

        //创建sqlSession对象

          //openSession(bool b) b默认为false:事务不会自动提交(即update,delete,insert操作不会自动提交至数据库,会保存到内存中,需要手动提交)
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //调用方法

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);

        List clazzList = clazzMapper.selectAll();
        for(Clazz clazz:clazzList){

            Integer clazzno = clazz.getClazzno();
            List studentList = clazzMapper.selectMore(clazzno);

            System.out.println(clazz+"--->"+studentList);
        }


        System.out.println("=========================================================================================");


        for(Clazz clazz:clazzList){
            Integer clazzno = clazz.getClazzno();

            List studentList = clazzMapper.selectMore(clazzno);

            clazz.setList(studentList);

            System.out.println(clazz);

        }


        //关闭资源

        sqlSession.close();

    }
}

2.N+1方式

(查询学生所有信息,包括clazz属性)

package pers.szs.test;

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 pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestD {
    public static void main(String[] args) throws IOException {

        //解析mybatis.xml文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");


        //创建sqlSession工厂

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

        //创建sqlSession对象

          //openSession(bool b) b默认为false:事务不会自动提交(即update,delete,insert操作不会自动提交至数据库,会保存到内存中,需要手动提交)
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //调用方法

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);


        List studentList = studentMapper.selectAll2();
        System.out.println(studentList);
        //关闭资源

        sqlSession.close();

    }
}

(查询班级所有信息,包括list属性)

package pers.szs.test;

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 pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestE {
    public static void main(String[] args) throws IOException {

        //解析mybatis.xml文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");


        //创建sqlSession工厂

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

        //创建sqlSession对象

          //openSession(bool b) b默认为false:事务不会自动提交(即update,delete,insert操作不会自动提交至数据库,会保存到内存中,需要手动提交)
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //调用方法

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);


        List clazzList = clazzMapper.selectAll2();
        System.out.println(clazzList);
        //关闭资源

        sqlSession.close();

    }
}

  1. 多表查询SQL
package pers.szs.test;

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 pers.szs.entity.Clazz;
import pers.szs.entity.Flower;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.FlowerMapper2;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestF {
    public static void main(String[] args) throws IOException {

        //解析mybatis.xml文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");


        //创建sqlSession工厂

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

        //创建sqlSession对象

          //openSession(bool b) b默认为false:事务不会自动提交(即update,delete,insert操作不会自动提交至数据库,会保存到内存中,需要手动提交)
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //调用方法

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        ClazzMapper clazzMapper = sqlSession.getMapper(ClazzMapper.class);

        List studentList = studentMapper.selectAll3();
        System.out.println(studentList);

        System.out.println("====================================================================================");
        List clazzList = clazzMapper.selectAll3();
        System.out.println(clazzList);


        //关闭资源

        sqlSession.close();

    }
}

学到这里大家可能会发现一个问题,每次书写Test类时都要反复书写重样的内容,包括解析mybatis.xml文件等,那么我们如何对现有的代码进行优化?

第四部分(代码优化)

优化方案一:提取工具类

工具类

package pers.szs.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 pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class DBUtil {


    //解析mybatis.xml文件
    private static SqlSessionFactory sqlSessionFactory=null;
   static {

        InputStream resourceAsStream;

        {
            try {
                resourceAsStream = Resources.getResourceAsStream("mybatis.xml");

                 sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static SqlSession getSqlSession(){


        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        return sqlSession;

    }



}

测试类

package pers.szs.test;

import pers.szs.entity.Student;
import pers.szs.mapper.StudentMapper;
import pers.szs.util.DBUtil;

import java.util.List;

public class TestG {

    public static void main(String[] args) {


        StudentMapper studentMapper = DBUtil.getSqlSession().getMapper(StudentMapper.class);


        List studentList = studentMapper.selectAll3();
        System.out.println(studentList);
    }
}

经过优化我们可以发现,测试类的代码已经大大减少,但是这仍然不是最终方案,因为我们会发现,如果用户提出一个请求需要我们查询需要后台查询所有学生和班级的信息,测试类如下:

package pers.szs.test;

import pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;
import pers.szs.util.DBUtil;

import java.util.List;

public class TestG {

    public static void main(String[] args) {

           selectA();
        
    }
    
    public static void selectA(){

        StudentMapper studentMapper = DBUtil.getSqlSession().getMapper(StudentMapper.class);

        List studentList = studentMapper.selectAll3();
        System.out.println(studentList);
        
        selectB();

    }
    
    public static void selectB(){
        ClazzMapper clazzMapper=DBUtil.getSqlSession().getMapper(ClazzMapper.class);
        List clazzList = clazzMapper.selectAll3();
        System.out.println(clazzList);

    }
}

通过测试类我们可以发现,每查询一个数据库表的信息,我们就需要使用Dbutil获取一个SqlSession对象,这样无形中造成了sqlSession对象的浪费,为此我们对DBUtil类进行优化

优化方案二:ThreadLocal 作用:在同一个线程中实现数据(sqlSession)的共享

​ 底层使用的map集合:map.put(key,value)

​ map.put(线程ID,conn)

package pers.szs.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 pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class DBUtil {


    //解析mybatis.xml文件
    private static SqlSessionFactory sqlSessionFactory;

    //创建ThreadLocal对象
    private static ThreadLocal tl=new ThreadLocal<>();

   static {

        InputStream resourceAsStream;

        {
            try {
                resourceAsStream = Resources.getResourceAsStream("mybatis.xml");

                 sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static SqlSession getSqlSession(){


       //获得ThreadLocal中的SqlSession对象
       SqlSession sqlSession=tl.get();

       if(sqlSession==null){

           sqlSession = sqlSessionFactory.openSession(true);

           //把创建好的对象放到ThreadLocal中
           tl.set(sqlSession);
       }



        return tl.get();

    }


   //关闭sqlSession
    public static void closeAll(){

        SqlSession sqlSession = tl.get();

        if(sqlSession!=null){
            sqlSession.close();
        }

        tl.set(null);
    }
}

测试类:TestG

package pers.szs.test;

import pers.szs.entity.Clazz;
import pers.szs.entity.Student;
import pers.szs.mapper.ClazzMapper;
import pers.szs.mapper.StudentMapper;
import pers.szs.util.DBUtil;

import java.util.List;

public class TestG {

    public static void main(String[] args) {

           selectA();
    }


    public static void selectA(){

        StudentMapper studentMapper = DBUtil.getSqlSession().getMapper(StudentMapper.class);

        List studentList = studentMapper.selectAll3();
        System.out.println(studentList);
        DBUtil.closeAll();

        selectB();

    }

    public static void selectB(){
        ClazzMapper clazzMapper=DBUtil.getSqlSession().getMapper(ClazzMapper.class);
        List clazzList = clazzMapper.selectAll3();
        System.out.println(clazzList);

        DBUtil.closeAll();

    }
}

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

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

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