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;}@Overridepublic String toString() {return "Flower{" +"id=" + id +", name='" + name + '\'' +", price=" + price +", production='" + production + '\'' +'}';}
}2.配置mybatis.xml文件<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><properties resource="jdbc.properties"></properties>  <!--配置属性:属性文件详见下方--><!--设置--><settings>  <setting name="logImpl" value="LOG4J"></setting>  <!--设置日志:文件详见下方--></settings><!--起别名--><typeAliases><package name="pers.szs.entity"></package></typeAliases><!--主要环境构建--><environments default="mysql">  <!--默认环境--><environment id="mysql">   <!--具体环境--><transactionManager type="JDBC"></transactionManager>  <!--事务管理器--><dataSource type="POOlED">  <!--数据源--><property name="driver" value="${m_driver}"/><property name="url" value="${m_url}"/><property name="username" value="${m_user}"/><property name="password" value="${m_password}"/></dataSource></environment></environments><!--mapper文件扫描一定要配置,不然扫描不到mapper文件--><mappers><package name="pers.szs.mapper"></package></mappers></configuration>属性文件(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,logfilelog4j.logger.pers.szs.mapper=debuglog4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=- %m%nlog4j.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<Flower> selectAll();//2.按照参数查询List<Flower> selectMore1(int id);List<Flower> selectMore2(String name,String production);List<Flower> selectMore3(Flower flower);List<Flower> selectMore4(Map<String,Object> 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

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--命名空间:namespace 理论上名字可以随意起建议使用mapper接口和mapper文件所在的包的引用+mapper接口名来命名,此时mybatis会自动扫描mapper接口,并自动查找和接口同名的mapperxml文件
-->
<mapper namespace="pers.szs.mapper.FlowerMapper"><sql id="sql1">id,name,price,production</sql><!--id:方法名resultType:返回值类型如果返回值是对象则返回对象的引用,如果返回值是集合,则返回泛型的引用(注意:此处已经在mybatis.xml中起别名(typeAliases),所以只需要写实体类类名,一般小写)--><select id="selectAll" resultType="flower">select <include refid="sql1"></include> from flower</select><select id="selectMore1" resultType="flower">select * from flower where id=#{param1}</select><select id="selectMore2" resultType="flower">select * from flower where name=#{param1} and production=#{param2}</select><select id="selectMore3" resultType="flower"><!--如果传入的参数是对象,可以直接在{}中写对象属性名-->select * from flower where name=#{name} and production=#{production}</select><select id="selectMore4" resultType="flower"><!--如果传入的参数是Map集合,可以直接在{}中写key-->select * from flower where name=#{key1} and production=#{key2}</select><!--update,delete,insert操作返回值均为整数,返回值类型可以不写--><insert id="insert1"><!--flowerMapper.insert1(0, "山茶花", 1566, "四川");-->insert into flower values(default,#{param2},#{param3},#{param4})</insert><insert id="insert2">insert into flower values(#{id},#{name},#{price},#{production})</insert><update id="update">update flower set name=#{param2},price=#{param3},production=#{param4} where id=#{param1}</update><delete id="delete">delete from flower where id=#{param1}</delete></mapper>

测试类(TestA)

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.Flower;
import pers.szs.mapper.FlowerMapper;import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class TestA {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);//调用方法FlowerMapper flowerMapper = sqlSession.getMapper(FlowerMapper.class);//关闭资源sqlSession.close();}
}

​ 通过第一部分的学习,我们已经掌握了利用mybatis实现基本的增删改查操作,但是我们可能会疑惑,利用mybatis进行操作似乎与直接在命令行或者图形界面操作没有区别,额,而且好像更加复杂了,因为需要我们配置许多文件,而且测试类需要使用许多我们不了解的类和接口。接下来我们就一起来看一看mybatis的强大之处。

第二部分(动态SQL)

1.九个标签:where if when set trim foreach band sql include(加粗的重点掌握,其他的用的不多,了解一下)

FlowerMapper2

package pers.szs.mapper;import pers.szs.entity.Flower;import java.util.List;
import java.util.Map;public interface FlowerMapper2 {//1.查询操作//ifList<Flower> selectMore1(String name,String production);//choose when otherwiseList<Flower> selectMore2(String name,String production);//foreachList<Flower> selectMore3(List<Integer> list);//bind(模糊查询)List<Flower> selectMore4(String name,String production);List<Flower> selectMore5(String name,String production);//2.修改操作int update1(Flower flower);int update2(Flower flower);

FlowerMapper2.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="pers.szs.mapper.FlowerMapper2"><!--动态SQL--><select id="selectMore1" resultType="flower">select * from flower<!-- where if<where>:自动添加"where"关键字,并自动把多余的第一个and去掉--><where><if test="param1!=null and param1!=''">name=#{param1}</if><if test="param2!=null and param2!=''">and production=#{param2}</if></where></select><!--  where choose when otherwise--><select id="selectMore2" resultType="flower">select * from flower<where><choose>   <!--类似于switch()--><when test="param1!=null and param1!=''">name=#{param1}</when><when test="param2!=null and param2!=''">and production=#{param2}</when><otherwise>1=1</otherwise></choose></where><!--foreach--></select><select id="selectMore3" resultType="flower">select * from flower where id in<foreach collection="list" open="(" separator="," close=")" item="item">#{item}</foreach></select><select id="selectMore4" resultType="flower">select * from flower<where><if test="param1!=null and param1!=''">name like '%${param1}%'</if><if test="param2!=null and param2!=''">and production like '%${param2}%'</if></where></select><select id="selectMore5" resultType="flower">select * from flower <where><if test="param1!=null and param1!=''"><bind name="pa1" value="'%'+param1+'%'"/>name like #{pa1}</if><if test="param2!=null and param2!=''"><bind name="pa2" value="'%'+param2+'%'"/>production like #{pa2}</if></where></select><!--set--><update id="update1">update flower<!--set:自动添加"set"关键字,自动去除最后面多余的逗号;--><set><if test="name!=null and name!=''">name=#{name},</if><if test="price>0">price=#{price},</if><if test="production!=null and production!=''">production=#{production}</if></set>where id=#{id}</update><update id="update2">update flower<trim prefix="set" suffixOverrides=","><if test="name!=null and name!=''">name=#{name},</if><if test="price>0">price=#{price},</if><if test="production!=null and production!=''">production=#{production}</if></trim>where id=#{id}</update></mapper>

疑难点:第一个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<Student> selectAll();List<Student> selectAll2();List<Student> selectAll3();//按照班级编号查询班级信息Clazz selectOne(int clazzno);//根据班级编号查询学生信息List<Student> selectMore(int clazzno);
}

StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="pers.szs.mapper.StudentMapper"><select id="selectMore" resultType="student">select * from student where clazzno=#{param1}</select><!--业务代理方式--><select id="selectAll" resultType="student">select * from student</select><select id="selectOne" resultType="clazz">select * from clazz where clazzno=#{param1}</select><!--N+1--><select id="selectAll2" resultMap="rm1">select * from student</select><resultMap id="rm1" type="student"><!--  主键使用 <id></id>其他列使用 <result></result>如果数据库列名和实体类属性名一致1,2,3可以省略,但公共字段不建议省略,即第三个:clazzno为student和clazz表的公共字段--><id column="sid" property="sid"></id>  <!--1--><result column="sname" property="sname"></result>  <!--2--><result column="clazzno" property="clazzno"></result>  <!--3--><!--select:调用的方法column:希望数据库的哪一列作为参数javaType:返回值类型property:将返回值赋给对象的哪一个属性--><association  select="pers.szs.mapper.ClazzMapper.selectOne" column="clazzno" javaType="clazz" property="clazz"></association></resultMap><!--mybatis多表查询SQL--><select id="selectAll3" resultMap="rm2">select * from student s join clazz c on s.clazzno=c.clazzno</select><resultMap id="rm2" type="student"><id column="sid" property="sid"></id><result column="sname" property="sname"></result><result column="clazzno" property="clazzno"></result><association property="clazz" javaType="clazz"><id column="clazzno" property="clazzno"></id><result column="cname" property="cname"></result></association></resultMap></mapper>

ClazzMapper(Intreface)

package pers.szs.mapper;import pers.szs.entity.Clazz;
import pers.szs.entity.Student;import java.util.List;public interface ClazzMapper {//查询所有班级信息List<Clazz> selectAll();List<Clazz> selectAll2();List<Clazz> selectAll3();//按照班级编号查询学生信息List <Student> selectMore(int clazzno);//按照指定编号查询班级信息Clazz selectOne(int clazzo);}

ClazzMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="pers.szs.mapper.ClazzMapper"><select id="selectOne" resultType="clazz">select * from clazz where clazzno=#{param1}</select><!--业务代理方式--><select id="selectAll" resultType="clazz">select * from clazz</select><select id="selectMore" resultType="student">select * from student where clazzno=#{param1}</select><!--N+1--><select id="selectAll2" resultMap="rm1">select * from clazz</select><resultMap id="rm1" type="clazz"><id column="clazzno"  property="clazzno"></id><result column="cname" property="cname"></result><collection select="pers.szs.mapper.StudentMapper.selectMore" column="clazzno" ofType="student" property="list"></collection></resultMap><!--mybatis中的多表查询SQL--><select id="selectAll3" resultMap="rm2">select * from student s join clazz c on s.clazzno=c.clazzno</select><resultMap id="rm2" type="clazz"><id column="clazzno" property="clazzno"></id><result column="cname" property="cname"></result><collection property="list" ofType="student"><id column="sid" property="sid"></id><result column="sname" property="sname"></result><result column="clazzno" property="clazzno"></result></collection></resultMap></mapper>

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<Student> 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<Clazz> clazzList = clazzMapper.selectAll();for(Clazz clazz:clazzList){Integer clazzno = clazz.getClazzno();List<Student> studentList = clazzMapper.selectMore(clazzno);System.out.println(clazz+"--->"+studentList);}System.out.println("=========================================================================================");for(Clazz clazz:clazzList){Integer clazzno = clazz.getClazzno();List<Student> 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<Student> 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<Clazz> 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<Student> studentList = studentMapper.selectAll3();System.out.println(studentList);System.out.println("====================================================================================");List<Clazz> 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<Student> 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<Student> studentList = studentMapper.selectAll3();System.out.println(studentList);selectB();}public static void selectB(){ClazzMapper clazzMapper=DBUtil.getSqlSession().getMapper(ClazzMapper.class);List<Clazz> 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<SqlSession> 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();}//关闭sqlSessionpublic 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<Student> studentList = studentMapper.selectAll3();System.out.println(studentList);DBUtil.closeAll();selectB();}public static void selectB(){ClazzMapper clazzMapper=DBUtil.getSqlSession().getMapper(ClazzMapper.class);List<Clazz> clazzList = clazzMapper.selectAll3();System.out.println(clazzList);DBUtil.closeAll();}
}

MyBatis基础篇相关推荐

  1. Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 萌芽阶段 很久之前就开始打算整理一下自己的技术博客了,由于各种原因( ...

  2. Spring+SpringMVC+MyBatis整合基础篇

    基础篇 Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介 Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试 Spring+S ...

  3. 你所需要的java基础篇和提升篇大总结

    好好学java 致力于java知识分享 关注 精彩内容 你所需要的java全套视频教程 你所需要的java电子图书 你所需要的大数据视频教程 你所需要的java练习项目 如 / 诗 近半个月,每天一篇 ...

  4. 黑马SpringBoot --基础篇

    目录 导读 1.快速上手 1.1SpringBoot入门程序开发 1.1.1基础创建方式--常规 1.1.2手动创建方式--补充 1.1.3基础创建方式--下载 1.1.4基础创建方式--阿里云 1. ...

  5. SpringBoot2基础篇

    目录 前言 从今天开始进入微服务阶段 一. HelloWorld 1.1.什么是SpringBoot 1.3.微服务架构 二.第一个SpringBoot程序 2.1.环境配置 2.2.创建基础项目说明 ...

  6. 谷粒商城分布式基础篇1-个人版

    基础篇 1 项目简介 1.1 项目背景 1.2 电商模式 市面上有5种常见的电商模式 B2B.B2C.C2B.C2C.O2O 1.2.1 B2B 模式 B2B(Business to Business ...

  7. Mybatis基础学习之万能的Map和模糊查询

    前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个Mybatis ...

  8. Java面试通关要点汇总集(基础篇之基本功,非原作者)

    Java面试通关要点汇总集(部分解答) 说明 如果你有幸能看到的话, 1.本文整体框架来自@阿里.梁桂钊的博文,总结的非常不错.值得我们学习,它的博客部分做了解答. 2.由于自己能力有限,没能实现心中 ...

  9. 【谷粒商城基础篇】仓储服务:仓库维护

    谷粒商城笔记合集 分布式基础篇 分布式高级篇 高可用集群篇 ===简介&环境搭建=== 项目简介与分布式概念(第一.二章) 基础环境搭建(第三章) ===整合SpringCloud=== 整合 ...

最新文章

  1. 一图分析华为最新AI生态与未来趋势
  2. 在GitHub上使用Hexo 搭建自己的博客
  3. classmethod和staticmethod
  4. 交互式计算机图形学总结:第一章 图形系统和模型
  5. 第九篇 并发(进程和线程)
  6. PP视频如何查看上下集的快捷键
  7. 启动go服务_go微服务框架go-micro深度学习 rpc方法调用过程详解
  8. cisco Router专线路由器配置
  9. 空间回归分析笔记3——OLS、GWR输出结果的意义
  10. PPT视频无法播放,编解码器不可用
  11. IDEA:Cannot determine Java VM executable in selected JDK
  12. trilateration三边测距算法及C语言实现(适用stm32)
  13. 急需“五彩连珠”小游戏的代码
  14. LightOJ - 1341 Aladdin and the Flying Carpet 唯一分解定理
  15. (Google Scholar)谷歌学术打不开怎么办,图文详解
  16. B站李沐讲论文笔记Transformer
  17. 易语言和python混合编程_Python脚本可以嵌入易语言程序吗 |
  18. 《数字图像处理》第4讲——线性运算与空间图像增强
  19. 微机原理与接口技术:接口概述 详细笔记
  20. html flash闹钟,教你用Flash制作可以定时闹钟

热门文章

  1. 利用python预测交通拥堵_Python pyecharts 绘制的交通拥堵情况地图
  2. 代理IP的主要用途和使用注意事项
  3. K近邻算法学习(KNN)
  4. 手电筒安卓_安利一款演唱会必备APP——随手电筒
  5. aop实现原理 - JDK动态代理(实例+源码解析)
  6. 以前写的代码感觉很有用
  7. JAVA 环境配置JDK
  8. microsoft word 自动生成目录
  9. 作为程序员创业者,来谈一下“老罗与王自如对战”
  10. DBSCAN: 基于密度对空间含噪声数据中不规则形状进行聚类