mybatis 学习

1 什么是mybatis

MyBatis 本是apache的⼀个开源项⽬iBatis, 2010年这个项⽬由apache software foundation 迁移
到了google code,并且改名为MyBatis 。2013年11⽉迁移到Github。
iBATIS⼀词来源于"internet"和"abatis"的组合,是⼀个基于Java的持久层框架。iBATIS提供的持久
层框架包括SQL Maps和Data Access Objects(DAOs)
MyBatis 是⼀款优秀的持久层框架,它⽀持定制化 SQL、存储过程以及⾼级映射。MyBatis 避免了
⼏乎所有的 JDBC 代码和⼿动设置参数以及获取结果集。MyBatis 可以使⽤简单的 XML 或注解来配置和
映射原⽣信息,将接⼝和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的
记录。

2搭建MYbatis

创建一个普通的maven项目,然后导入依赖包
<dependencies>
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>3.4.6</version>
     </dependency>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.40</version>
     </dependency>
 </dependencies>
然后resource资源下新建mybatis.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">
<configuration>
 <!--连接数据库的环境-->
 <environments default="development"> <!--环境的id-->
 <environment id="development">
 <transactionManager type="JDBC"/>
 <dataSource type="POOLED"> <!--连接池的数据源-->
 <property name="driver" value="com.mysql.jdbc.Driver"/>
 <property name="url" value="jdbc:mysql://localhost:3306/student"/>
 <property name="username" value="root"/>
 <property name="password" value="root"/>
 </dataSource>
 </environment>
 </environments>
 <!-- 指定maper⽂件的路径(maven项⽬从resources源⽂件夹下找资源)-->
 <mappers>
 <mapper resource="包名/mapper⽂件名"/>
 </mappers>
</configuration>
新建一个类,接口,mapper,如图,

在这里插入图片描述
建立mapper的方法

类,以及其他配置文件的源码,注意,类里的属性如下,类名和表名一致,属性和列名一致,不一致会报错,还有数据库里列的字段属性,要保持一致,不然很可能报SQLException错误,
代码结构如图
在这里插入图片描述

student类

package com.bean;

public class student {
    private   int studentid;
    private String studentno;
    private  String stuname;

    public student() {
    }

    public student(int studentid, String studentno, String stuname) {
        this.studentid = studentid;
        this.studentno = studentno;
        this.stuname = stuname;
    }

    public int getStudentid() {
        return studentid;
    }

    @Override
    public String toString() {
        return "student{" +
                "studentid=" + studentid +
                ", studentno='" + studentno + '\'' +
                ", studname='" + stuname + '\'' +
                '}';
    }

    public void setStudentid(int studentid) {
        this.studentid = studentid;
    }

    public String getStudentno() {
        return studentno;
    }

    public void setStudentno(String studentno) {
        this.studentno = studentno;
    }

    public String getStudname() {
        return stuname;
    }

    public void setStudname(String studname) {
        this.stuname = studname;
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>Mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
 <dependencies>
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>3.4.6</version>
     </dependency>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.40</version>
     </dependency>
 </dependencies>

</project>

dao接口

package com.dao;

import com.bean.student;

import java.util.List;

public interface studentDao {
  //定义增删改查的方法
    public List<student> getall();
}

测试类Test1

package com;


import com.bean.student;
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.Reader;
import java.util.List;

public class Test1 {
 public static void main(String[] args) {
     try {
         //1加载配置文件
         Reader reader=Resources.getResourceAsReader("mybatis.xml");
         /*    2得到SQLSessionFactoryBuilder*/
         SqlSessionFactoryBuilder builder =new SqlSessionFactoryBuilder();
         SqlSessionFactory build =builder.build(reader);
         //3得到SQLSession
         SqlSession session=build.openSession();
         //4操作sql
         List<student> list =session.selectList("com.dao.studentDao.getall");//调取sql完整路径=namespace+id
         //5遍历
         for (student stu : list){
             System.out.println(stu);
         }
         //6关闭资源
         session.close();
         reader.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
 }
}

mybatis.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">
<configuration>
 <!--连接数据库的环境-->
 <environments default="development"> <!--环境的id-->
 <environment id="development">
 <transactionManager type="JDBC"/>
 <dataSource type="POOLED"> <!--连接池的数据源-->
 <property name="driver" value="com.mysql.jdbc.Driver"/>
 <property name="url" value="jdbc:mysql://localhost:3306/student"/>
 <property name="username" value="root"/>
 <property name="password" value="root"/>
 </dataSource>
 </environment>
 </environments>
 <!-- 指定maper⽂件的路径(maven项⽬从resources源⽂件夹下找资源)-->
 <mappers>
 <mapper resource="studentMapper.xml"/>
 </mappers>
</configuration>

studnetMapper.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.dao.studentDao">
  <select id="getall" resultType="com.bean.student">
      select *from stud;
  </select>
</mapper>

查询成功截图
在这里插入图片描述
在这里插入图片描述

mybatis的执行过程

1 先读取xml文件,指定数据库连接信息,和mapper,读取完之后连接,读取到mapper后就可以读取里边的对应关系,
2创建SQLsessionFactoryBuilder,
3就是上面代码里,利用selectList里边传值
4关闭打开的资源

配置多数据源

在这里插入图片描述
这个里边一种对应一种数据源,可以复制内容,下边可以配置多种数据源,如果要切换数据源,在这个里边添加第二个参数,另一个数据源的id值
在这里插入图片描述

CURD操作

1 单个基本类型参数或 String 类型:
mapper读取参数:#{参数名(也可以是⾃定义名称)}
修改如下操作 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实现新增
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果此时提交到数据库里的是乱码的话,需要修改编码方式
在这里插入图片描述
添加多个值的时候用map集合
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
增加成功
在这里插入图片描述
在做查询时,如果需要将查询的结果和实体类属性⾃动对应的话,要求:属性名=列名
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加:session.insert(“namespace+id”[,传递给sql的参数值]);
修改:session.update(“namespace+id”[,传递给sql的参数值]);
删除:session.delete(“namespace+id”[,传递给sql的参数值]);
单⾏:session.selectOne(“namespace+id”[,传递给sql的参数值]);
多⾏:session.selectList(“namespace+id”[,传递给sql的参数值]);
处理多个聚合函数:使⽤map作为⽅法的返回值,默认key是列名

注意这里有些是只能传入一个值

注意:增删改的时候需要提交事务
session.commit();
//1.加载配置⽂件
Reader r=Resources.getResourceAsReader(“mybatis-config.xml”);
//2.创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder();
//3.得到session⼯⼚
SqlSessionFactory factory=builder.build®;
//4.得到session
SqlSession session= factory.openSession();
//5.调取sql语句,insert(“⽅法的完整路径”),路径=namespace+id
int rs=session.insert(“dao.EmpDao.insertEmp”,e);
session.commit();

session.rollback();
查询的时候要添加resultType属性

getMapper调取方法

package com;

import com.bean.student;
import com.dao.studentDao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

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

public class TestDemo {
    public static void main(String[] args) {
        try {
            //1,获取SQLSession对象
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            SqlSession session =new SqlSessionFactoryBuilder().build(reader).openSession();
            //2得到要调用的方法
            studentDao stuDao=session.getMapper(studentDao.class);//这里是一个反射的应用
            List<student> studentList=stuDao.getall();//调用方法的全路径实现
            for (student stu:studentList)
            {
                System.out.println(stu);
            }
            //3关闭资源

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ThreadLocal

普通存值实现线程共享,ThreadLocal实现线程独立

看如下代码:

package com;

import java.util.ArrayList;
import java.util.List;

public class TestThread {
 private  ThreadLocal<String> threadLocal=new ThreadLocal<>();
 private List<String> list=new ArrayList<String >();
  class A extends Thread{  /*基础Thread类重写里边的方法*/
      @Override
      public void run() {
         /*存值*/
          System.out.println("A 开始存值");
          threadLocal.set("thread 内容");
          list.add("list内容");
          System.out.println("A--ThreadLocal="+threadLocal.get());
      }
  }
    class B extends Thread{  /*基础Thread类重写里边的方法*/
        @Override
        public void run() {
            /*取值*/
            try {
                Thread.sleep(2000);//为了避免未存值B线程就抢到了
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B开始取值");
            System.out.println(threadLocal.get());
            System.out.println(list.get(0));;
            System.out.println("B--ThreadLocal="+threadLocal.get());
        }
    }

    public static void main(String[] args) {
        TestThread testThread =new TestThread();
        TestThread.A a=testThread.new A();
        TestThread.B b=testThread.new B ();
        a.start();
        b.start();
    }
}

运行结果:
在这里插入图片描述
原理解释:
ThreadLocal并⾮是⼀个线程的本地实现版本,它并不是⼀个
Thread,⽽是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局
部变量(ThreadLocal)其实的功⽤⾮常简单,就是为每⼀个使⽤该变量的线程都提供⼀个变量值的副本,
是Java中⼀种较为特殊的线程绑定机制,是每⼀个线程都可以独⽴地改变⾃⼰的副本,⽽不会和其它线
程的副本冲突。

Thre优化SQLSession
package com.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.Reader;

public class SqlSessionUtil {
    private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();
    private  static SqlSessionFactory sqlSessionFactory;
static {
    try {
        Reader resourceReader= Resources.getResourceAsReader("mybatis.xml");
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceReader);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

    public static SqlSession getSession(){  //单例模式
    SqlSession  session =threadLocal.get();
    if (session==null){
        session=sqlSessionFactory.openSession();
        threadLocal.set(session);
    }
    return  session;
    }
    public static void closeSession(){
     SqlSession session=threadLocal.get();
     if(session!=null){
         session.close();
         threadLocal.remove();
     }
    }
}

给类起别名

为了简便
在这里插入图片描述
还可以指定包的路径

获得新增数据的id

在这里插入图片描述
在Mapper.xml配置文件中新增数据的后边加上上边的两个属性,表示将自动增加的id附到userid上去

Log4J日志

在mybatis里显示sql语句
首先添加依赖包

<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.5</version>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.7.30</version>
 </dependency>
 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.17</version>
 </dependency>

然后新建一个配置文件
log4j.properties

log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

log4j就是将日志信息打印出来,可以输出到控制台,文件数据库等
如图,进行插入一条信息以后,控制台打印出来对应的日志信息
在这里插入图片描述

mybatis的复杂查询

in查询

foreach标签中属性说明:
item 表示集合中每⼀个元素进⾏迭代时的别名,等同于c 标签中的var
index 指定⼀个名字,⽤于表示在迭代过程中,每次迭代到的位置,可以不写
open 表示该语句以什么开始,
separator 表示在每次进⾏迭代之间以什么符号作为分隔符,
close 表示以什么结束,
注意:在使⽤foreach 的时候最关键的也是最容易出错的就是collection 属性,
collection该属性是必须指定的
list 时取值list,数组时取值array,map 时取值map 的key 值
(1)参数是list
首先复制一份原来的mapper,做修改

 <select id="finda" resultType="com.bean.student">
      select *from stud where studentid in
       <foreach collection="list" item="sid" open="(" close=")" separator=",">
           #{sid}
       </foreach>
  </select>

然后定义一个新的接口

  public List<student> finda(List list);

创建一个新的测试类

package com;
import com.bean.student;
import  com.dao.studentDao2;
import com.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;
import java.util.List;

public class TestIN {
    public static void main(String[] args) {
        SqlSession session=SqlSessionUtil.getSession();
        studentDao2 stuDao2=session.getMapper(studentDao2.class);
       List list=new ArrayList();
       list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
       List<student> students= stuDao2.finda(list);
        for (student student : students) {
            System.out.println(student);
        }
        SqlSessionUtil.closeSession();
    }


}

运行成功
在这里插入图片描述
在这里插入图片描述
第二种方法使用数据进行遍历,只需要修改一下传值方式,并且collection里边改为array,

第三种方式,map集合。map集合不同于其他点的是map集合是以键值对来存储的,可以进行多个值的查询
同理,以上三种方法代码如下

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.dao.studentDao2">
  <select id="finda" resultType="com.bean.student">
      select *from stud where studentid in
       <foreach collection="list" item="sid" open="(" close=")" separator=",">
           #{sid}
       </foreach>
  </select>
    <select id="findb" resultType="com.bean.student">
        select *from stud where studentid in
        <foreach collection="array" item="sid" open="(" close=")" separator=",">
        #{sid}
        </foreach>
    </select>
    <select id="findc" resultType="com.bean.student">
        select *from stud where studentid in
        <foreach collection="ids" item="sid" open="(" close=")" separator=",">
            #{sid}
        </foreach>
    </select>
</mapper>

dao
package com.dao;

import com.bean.student;

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

public interface studentDao2 {
//in 查询
    public List<student> finda(List list);
    public List<student> findb(int [] ids);
    public List<student> findc(Map map)
            ;
}

Test
package com;
import com.bean.student;
import  com.dao.studentDao2;
import com.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestIN {
    public static void main(String[] args) {
        SqlSession session=SqlSessionUtil.getSession();
        studentDao2 stuDao2=session.getMapper(studentDao2.class);
     /*  List list=new ArrayList();
       list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
       List<student> students= stuDao2.finda(list);*/
        //数组
        /*int [] ids=new int[] {1,3,5,7};
        List<student> students= stuDao2.findb(ids);
*/
        //map
        Map map=new HashMap();
        List list=new ArrayList();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        map.put("ids",list);
        List <student> students=stuDao2.findc(map);
        for (student student : students) {
            System.out.println(student);
        }
        SqlSessionUtil.closeSession();
    }


}

模糊查询

如果传递的参数是多个时?------使⽤Map 集合
模糊查询:
注意:test属性中读取属性值时直接写属性名
模糊查询读取属性时使el 表达式,${属性名}
除以上位置外,都使⽤#{属性名}
多个条件时使⽤and,or 拼接
如果传递过来的是map类型,则test属性中写的是key
#{}:相当于占位符
#{id}:其中的id可以表示输⼊参数的名称,如果是简单类型名称可以任意
${}:表示拼接sql语句
v a l u e : 表 示 获 取 输 ⼊ 的 参 数 值 , {value}:表示获取输⼊的参数值, value,{}会引起SQL注⼊,⼀般情况下不推荐使⽤。
示例:
Mapper.xml

  <select id="findd" resultType="com.bean.student">
        select *from  stud where 1=1
        <if test="stuname!=null and stuname !=''">
        and  stuname like "%"#{stuname}"%"
        </if>
        <if test="sno!=null and sno!=''">
            and studentno=#{sno}
        </if>

    </select>

TestLike 类

package com;

import com.bean.student;
import com.dao.studentDao2;
import com.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

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

public class TestLike {
    public static void main(String[] args) {
        SqlSession session=SqlSessionUtil.getSession();
        studentDao2 stuDao2=session.getMapper(studentDao2.class);
        Map map=new HashMap();
        map.put("stuname","张");
        map.put("sno","s1101");
        List<student> students=stuDao2.findd(map);
        for (student student : students) {
            System.out.println(student);
        }
    }
}

Dao接口

 public List<student> findd(Map map);

map和实体类的区别,传入的值是不一样的
在这里插入图片描述
student传入的是类的属性,必须和student里的属性名相同
在这里插入图片描述
在这里插入图片描述

区间查询

两种方法,一种是between and
另一种是 >= <= ,这里要注意的一点是注释的时候另一条语句移出去,我就是因为在同一个select下注释的导致半天没有找到错误在哪
在这里插入图片描述
现附上区间查询的代码
TestBetween 类

package com;

import com.bean.student;
import com.dao.studentDao2;
import com.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

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

public class TestBetween {
    public static void main(String[] args) {
        SqlSession session=SqlSessionUtil.getSession();
        studentDao2 stuDao2=session.getMapper(studentDao2.class);
        Map map=new HashMap();
        map.put("begin",1);
        map.put("end",3);
        List<student> students=stuDao2.findf(map);
        for (student student : students) {
            System.out.println(student);
        }
        SqlSessionUtil.closeSession();
    }
}

mapper.xml类

<!--    select *from stud where studentid between  #{begin} and #{end}-->
    <select id="findf" resultType="com.bean.student">

select * from stud where studentid>=#{begin}   and studentid <![CDATA[<=]]> #{end} <!--//这里因为<和里边重复,所以需要进行转移-->
    </select>

dao接口的
在这里插入图片描述

resultMap处理列名不一致问题

查询结果映射
此处列名为stuage,但是在student中定义为age,列名不一样

在这里插入图片描述
在这里插入图片描述
resultMap可以自定义属性名和列名,方便操作
在这里插入图片描述

Test测试类
package com;


import com.bean.student;
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.Reader;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Test0 {
 public static void main(String[] args) {
     try {
         //1加载配置文件
         Reader reader=Resources.getResourceAsReader("mybatis.xml");
         /*    2得到SQLSessionFactoryBuilder*/
         SqlSessionFactoryBuilder builder =new SqlSessionFactoryBuilder();
         SqlSessionFactory build =builder.build(reader);
         //3得到SQLSession
         SqlSession session=build.openSession();
         //4操作sql
        List<student> list = session.selectList("com.dao.studentDao.getall");

        //5遍历
         for (student student : list) {
             System.out.println(student);
         }

         session.commit();//做完修改得需要提交事务

         //6关闭资源
         session.close();
         reader.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
 }
}

age查询成功
在这里插入图片描述

多表查询

代码在下边整体附上
两表联查:⼀对多和多对⼀
注:如果是单表查询,select 中使⽤resultType 设置返回的类型即可
但是如果是多表联查,那么select 查询的结果需要单独使⽤resultMap 标签来
进⾏结果的映射
存的是集合的话使⽤Collection ⼦标签
存的是⼀⽅的话使⽤association ⼦标签
resultType 和resultMap 属性只能出现⼀个

遵循一个原则 :多方有一方的对象,一方有多方的集合

多对一

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
查询结果
在这里插入图片描述

多对一

查询学生信息以及对应的年及信息
在这里插入图片描述

查询成功
在这里插入图片描述
JavaType和ofType都是⽤来指定对象类型的,但是JavaType是⽤来指定pojo中属性的类型,⽽ofType指
定的是映射到list集合属性中pojo的类型。

多对多
一对一,注意这里千万不要有空格

空格引发的bug
在这里插入图片描述

mybatis分页

sql 语句只需要查询数据,不实现分⻚代码
⽅式1:
Mybatis使⽤RowBounds对象进⾏分⻚,它是针对ResultSet结果集执⾏的内存分⻚,⽽⾮物理分⻚。可
以在sql内直接书写带有物理分⻚的参数来完成物理分⻚功能,也可以使⽤分⻚插件来完成物理分⻚。
优缺点
物理分⻚每次都要访问数据库,逻辑分⻚只访问⼀次
物理分⻚占⽤内存少,逻辑分⻚相对较多
物理分⻚数据每次都是最新的,逻辑分⻚有可能滞后
实现内存分页
在这里插入图片描述
⽅式2:使⽤分⻚插件
分⻚插件的基本原理是使⽤Mybatis提供的插件接⼝,实现⾃定义插件,在插件的拦截⽅法内拦截待执⾏
的sql,然后重写sql,根据dialect⽅⾔,添加对应的物理分⻚语句和物理分⻚参数。

(a)导⼊jar 包
分⻚插件:pagehelper.jar
sql 解析⼯具:jsqlparser.jar

<dependency>
         <groupId>com.github.pagehelper</groupId>
         <artifactId>pagehelper</artifactId>
         <version>5.1.6</version>
     </dependency>

(b) 在MyBatis 的总体⽂件中配置插件
放到之前

 <plugins>
 <!-- PageHelper4.1.6 -->
 <plugin interceptor="com.github.pagehelper.PageHelper">
 <property name="dialect" value="mysql"/>
 </plugin>
 </plugins>

注意:插件5.1以后interceptor不同,并且不需要指定数据库名字

<plugins>
 <plugin interceptor="com.github.pagehelper.PageInterceptor">
 </plugin>
</plugins>

在这里插入图片描述

© 在执⾏查询之前设置
PageHelper.startPage(当前⻚,每⻚条数)
//分⻚查询(注意事项:设置分⻚的值⼀定要在查询之前)
//1.在⼯具类中指定⻚码值和显示条数
PageHelper.startPage(2,5);
//2.调取查询的⽅法,得到结果集
Student student1=new Student();
//student1.setStuname(“aa”);
// student1.setAddress1(“昌平”);
List list=dao.findall(student1);
//3.将list集合封装到PageInfo对象中
PageInfo pageInfo=new PageInfo(list);
List list2= pageInfo.getList();
//4.得到结果
for (Student student :list2) {
System.out.println(student.getStuname());
}
System.out.println(“每⻚显示条数:”+pageInfo.getPageSize());
System.out.println(“当前⻚的条数:”+pageInfo.getSize());
System.out.println(“总条数:”+pageInfo.getTotal());
System.out.println(“总⻚数:”+pageInfo.getPages());
System.out.println(“上⼀⻚:”+pageInfo.getPrePage());
System.out.println(“下⼀⻚:”+pageInfo.getNextPage());
System.out.println(“当前⻚:”+pageInfo.getPageNum());

分页测试类
package com;


import com.bean.student;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.RowBounds;
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.Reader;
import java.util.List;

public class TestPage {
 public static void main(String[] args) {
     try {
         //1加载配置文件
         Reader reader=Resources.getResourceAsReader("mybatis.xml");
         /*    2得到SQLSessionFactoryBuilder*/
         SqlSessionFactoryBuilder builder =new SqlSessionFactoryBuilder();
         SqlSessionFactory build =builder.build(reader);
         //3得到SQLSession
         SqlSession session=build.openSession();
         //4操作sql
         //4.1指定分页的参数
         PageHelper.startPage(2,3);
          //42调取dao层方法
         List<student> list = session.selectList("com.dao.studentDao.getall");
         //创建分页工具类对象
         PageInfo<student> info=new PageInfo<student>(list);
         //从分页数据中获得数据
         for (student stud : info.getList()) {
             System.out.println(stud);
         }
         System.out.println("每⻚显示条数:"+info.getPageSize());
         System.out.println("当前⻚的条数:"+info.getSize());
         System.out.println("总条数:"+info.getTotal());
         System.out.println("总⻚数:"+info.getPages());
         System.out.println("上⼀⻚:"+info.getPrePage());
         System.out.println("下⼀⻚:"+info.getNextPage());
         System.out.println("当前⻚:"+info.getPageNum());

        //5遍历
       /*  for (student student : list) {
             System.out.println(student);
         }
*/
         session.commit();//做完修改得需要提交事务

         //6关闭资源
         session.close();
         reader.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
 }
}

在这里插入图片描述

mybatis缓存

⼀级缓存
SqlSession 的缓存 ------>⾃动开启
⼆级缓存:
做到从不同的缓存中共享数据
SqlSessionFactory 的缓存 —>需要⼿动开启
映射配置⽂件中配置

<mapper namespace="接⼝路径">
 <cache eviction="FIFO"
 flushInterval="60000"
 size="512"
 readOnly="true"/>
</mapper>

说明:
eviction: ⼆级缓存中,缓存的对象从缓存中移除的策略,回收策略为先进先出
flushInterval: 刷新缓存的事件间隔,单位:毫秒
size: 缓存对象的个数
readOnly: 是否是只读的

//不同qlSession,要同⼀个sqlSessionFactory
SqlSessionFactory factory= new SqlSessionFactoryBuilder()
 .build(Resources.getResourceAsReader("mybatis-config.xml"));
SqlSession sqlSession1=factory.openSession();
Student student = sqlSession1.selectOne("com.yhp.dao.StudentDao.findbystuid",
1);
System.out.println(student.getSname());
sqlSession1.close();
System.out.println("===================================");
SqlSession sqlSession2= factory.openSession();
student = sqlSession2.selectOne("com.yhp.dao.StudentDao.findbystuid", 1);
System.out.println(student.getSname());
sqlSession2.close();

cache元素⽤来开启当前mapper的namespace下的⼆级缓存,该元素的属性设置如下:
flushInterval:刷新间隔,可以被设置为任意的正整数,⽽且它们代表⼀个合理的毫秒形式的时间段,
默认情况下是不设置的,也就是没有刷新间隔,缓存仅仅调⽤语句时刷新。



//不同qlSession,要同⼀个sqlSessionFactory
SqlSessionFactory factory= new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsReader(“mybatis-config.xml”));
SqlSession sqlSession1=factory.openSession();
Student student = sqlSession1.selectOne(“com.yhp.dao.StudentDao.findbystuid”,
1);
System.out.println(student.getSname());
sqlSession1.close();
System.out.println("===================================");
SqlSession sqlSession2= factory.openSession();
student = sqlSession2.selectOne(“com.yhp.dao.StudentDao.findbystuid”, 1);
System.out.println(student.getSname());
sqlSession2.close();
size:缓存数⽬,可以被设置为任意正整数,要记住你的缓存对象数⽬和你运⾏环境可⽤内存资源数
⽬,默认值是1024.
readOnly:只读,属性可以被设置为true或false,只读的缓存会给所有调⽤者返回缓存对象的相同实
例,因此这些对象不能被修改。这提供了很重要的性能优势,可读写的缓存会返回缓存对象的拷⻉(通
过序列化),这会慢⼀些,但是安全,因此默认是false。
eviction:收回策略,默认为LRU,有如下⼏种:
LRU:最近最少使⽤的策略,移除最⻓时间不被使⽤的对象。
FIFO:先进先出策略,按对象进⼊缓存的顺序来移除它们。
SOFT:软引⽤策略,移除基于垃圾回收器状态和软引⽤规则的对象。
WEAK:弱引⽤策略,更积极地移除基于垃圾收集器状态和弱引⽤规则的对象。
注意:使⽤⼆级缓存时,与查询结果映射的java对象必须实现java.io.Serializable接⼝的序列化和反序列
化操作,如果存在⽗类,其成员都需要实现序列化接⼝,实现序列化接⼝是为了对缓存数据进⾏序列化
和反序列化操作,因为⼆级缓存数据存储介质多种多样,不⼀定在内存,有可能是硬盘或者远程服务
器。
以上源码都在资源mybatis里,如有需要可自行下载

Mybatis 注解

从注解这开始的源码都在资源里Mybatis001里
在mybatis中可以将sql语句通过注解的⽅式定义在java中,此时配置⽂件扫描该注解的位置即可,代码
如下:

@Insert("insert into student(username,password,birthday) values(#
{user_name},#{password},#{birthday})")
 @Options(useGeneratedKeys = true,keyProperty = "userid")
 public int insertstu(Student student);
@Delete("delete from student where userid=#{userid}")
 public int deleteuser(int userid);
@Update("update student set username=#{user_name},sex=#{sex} where userid=#
{userid}")
public int updateuser(Student stu);
 @Select("select * from student")
 /* @Results({
 @Result(id = true, property = "id", column = "test_id")
 @Result(column = "username",property = "user_name")
 })*/
 

注意:多个@Result的时候两侧加⼤括号{}

lombok插件

在这里插入图片描述
在这里插入图片描述

<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <scope>provided</scope>
 </dependency

lombok的使⽤
@Data 注解在类上;提供类所有属性的 getting 和 setting ⽅法,此外还提供了equals、canEqual、
hashCode、toString ⽅法
@Setter :注解在属性上;为属性提供 setting ⽅法
@Getter :注解在属性上;为属性提供 getting ⽅法
@Log4j :注解在类上;为类提供⼀个 属性名为log 的 log4j ⽇志对象
@NoArgsConstructor :注解在类上;为类提供⼀个⽆参的构造⽅法
@AllArgsConstructor :注解在类上;为类提供⼀个全参的构造⽅法
@Cleanup : 可以关闭流
@Builder : 被注解的类加个构造者模式
@Synchronized : 加个同步锁
@SneakyThrows : 等同于try/catch 捕获异常
@NonNull : 如果给参数加个这个注解 参数为null会抛出空指针异常
@Value : 注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会⽣
成set⽅法。
@ToString 重写toString()⽅法

mybatis 自动化

源码在mybatis003里

作⽤:反向⽣成实体类,接⼝,mapper.xml
添加依赖包

<dependency>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-core</artifactId>
 <version>1.3.5</version>
 </dependency>

加载插件

<build>
 <plugins>
 <plugin>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-maven-plugin</artifactId>
 <version>1.3.5</version>
 <configuration>
 <!--配置⽂件的路径-->

<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
 <overwrite>true</overwrite>
 </configuration>
 <dependencies>
 <dependency>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-core</artifactId>
 <version>1.3.5</version>
 </dependency>
 </dependencies>
 </plugin>
 </plugins>
 </build>

修改配置文件
里面的一些配置信息需要修改成自己本地的

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
 PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
 "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 <!-- 配置⽣成器 -->
<generatorConfiguration>
 <!--数据库驱动jar -->
 <classPathEntry
 location="F:\yhp\jar\mysql驱动\mysql-connector-java-5.0.8-bin.jar"
/>
 <context id="MyBatis" targetRuntime="MyBatis3">
 <!--去除注释 -->
 <commentGenerator>
 <property name="suppressAllComments" value="true" />
 </commentGenerator>
 <!--数据库连接 -->
 <jdbcConnection driverClass="com.mysql.jdbc.Driver"
 connectionURL="jdbc:mysql://localhost:3306/chaoshi"
 userId="root"
 password="123456">
 </jdbcConnection>
 <!--⽣成实体类 指定包名 以及⽣成的地址 (可以⾃定义地址,但是路径不存在不会⾃动创建
 使⽤Maven⽣成在target⽬录下,会⾃动创建) -->
 <javaModelGenerator targetPackage="com.yhp.bean"

targetProject="F:\yhp\three\workspace\mybatis_001\src\main\java">
 <property name="trimStrings" value="true" />
 </javaModelGenerator>
 <!--⽣成SQLmapper⽂件 -->
 <sqlMapGenerator targetPackage="mapper"

targetProject="F:\yhp\three\workspace\mybatis_001\src\main\resources">
 </sqlMapGenerator>
 <!--⽣成Dao⽂件,⽣成接⼝ -->
 <javaClientGenerator type="XMLMAPPER"
 targetPackage="com.yhp.dao"
 targetProject="F:\yhp\three\workspace\mybatis_001\src\main\java">
 </javaClientGenerator>
 <table tableName="student" enableCountByExample="false"
 enableUpdateByExample="false" enableDeleteByExample="false"
 enableSelectByExample="false" selectByExampleQueryId="false">
 </table>
 <table tableName="grade" enableCountByExample="false"
 enableUpdateByExample="false" enableDeleteByExample="false"
 enableSelectByExample="false" selectByExampleQueryId="false">
 </table>
 <table tableName="subject" enableCountByExample="false"
 enableUpdateByExample="false" enableDeleteByExample="false"
 enableSelectByExample="false" selectByExampleQueryId="false">
 </table>
 </context>
</generatorConfiguration>

数据库驱动包在本地的maven仓库里
在这里插入图片描述
在这里插入图片描述
**加粗样式**在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
可以看到自动生成了
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌晨里的无聊人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值