IBatis的使用

article/2025/9/13 8:37:24

IBatis的使用

1、IBatis是什么

回顾之前前端访问后端的整个流程:

View ------ >Controller --------> Service ---------> DAO ------> 数据库

View :前端jsp/HTML

Controller:Servlet/SpringMVC

Service :Spring

DAO:jdbc/dbutils/jdbctemplate/mybatis

mybatis实际上就是 DAO层的一个解决方案

jdbc、dbutils、jdbcTemplate、Hibernate以及mybatis的对比:

JDBC:代码非常复杂、速度快

Hibernate:代码精简、缺点(速度慢)

dbutils、jdbcTemplate:不是框架 只是对jdbc的一个简单的封装而已

mybatis:他是属于效率处于JDBC和Hibernate之间

​ 他的代码的复杂度也是趋于 JDBC和Hibernate之间、 代码灵活

iBatis和mybatis之间的关系是什么?

ibatis是以前的叫法 mybatis是现在的叫法

2、iBatis能做什么

数据库的访问(CRUD)

整合缓存、还可以给类取别名、IBatis还提供了整合Spring的第三方的包

3、IBatis的简单的使用(一)(IBatis的数据不传参的问题)

3.1、导包
 <!--导包--><!--下面就是iBatis的相关的包--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><!--mysql的驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.5.10</version></dependency><!--日志门面--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.6.1</version></dependency><!-- 单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12-beta-3</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency></dependencies>
3.2编写mybatis.xml配置文件

说明:配置文件的名字可以随意取

<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><!--这个文件的作用:是对mybatis的全局配置-->
<configuration><!--environments:环境+s,说明可以配置等多个环境这里配置的环境是:数据库的连接信息default:如果配置了多个环境 默认使用哪一个环境--><environments default="mysql"><!--配置一个环境:id:表示的是这个环境的名字逻辑意义上是可以随便写的--><environment id="mysql"><!--配置的是事务的类型 ,默认配置JDBC就可以了  一般情况下使用的就是这个类型--><transactionManager type="JDBC"></transactionManager><!--这个配置的是数据源  这里你可以认为是固定写法--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///test"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment><!--这里是可以配置多个环境的  要使用哪一个环境那么就就配置上面的default就可以了 --><environment id="oracle"><transactionManager type=""></transactionManager><dataSource type=""></dataSource></environment></environments><!--在全局配置文件中引入mapper.xml的配置文件--><!--不带参数--><mappers><mapper resource="UserMapper.xml"></mapper></mappers>
</configuration>
3.3、编写UserMapper.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 namespace="UserMapper"><!--insert:标签:表示的是 添加数据到数据库id:表示的是方法的名字备注:标签之间 就是写SQL语句的地方--><!--添加数据--><insert id="insert">insert into t_user (username,password) values ('李四','12344');</insert><!--修改数据--><update id="update">update  t_user set username='王五'</update><!--查询数据--><!--resultType:表示返回数据的数据类型--><select id="select" resultType="com.szq.User">select * from t_user where id=1</select><!--删除数据--><delete id="delete">delete from t_user where username='王五'</delete></mapper>
3.3、编写测试代码(CRUD)
package com.szq;
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 org.junit.Test;
import java.io.IOException;
import java.io.Reader;
public class Test001 {/*** 测试程序*/@Testpublic void testA() throws IOException {//1.找到mybatis.xml配置文件Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");//2.创建SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);//通过工厂构建sqlSession对象//sqlSession这个对象就是用来操作 数据库的对象SqlSession sqlSession = sqlSessionFactory.openSession();//接下来就可以操作数据库了//添加数据
//        sqlSession.insert("UserMapper.insert");//修改数据
//        sqlSession.update("UserMapper.update");//查询数据
//       User o = sqlSession.selectOne("UserMapper.select");
//        System.out.println(o);//删除数据sqlSession.delete("UserMapper.delete");sqlSession.commit();//提交sqlSession.close();//关闭}
}

4、iBatis的基本的工具类的使用

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.Reader;/*** 帮助类* mybatis帮助类*/
public class MyBatisUtils {//这个类是可以成为成员变量的(没有成员变量,不存在线程安全问题)private SqlSessionFactory sqlSessionFactory=null;//保存一个线程局部变量private ThreadLocal<SqlSession> threadLocal;{try {//需要加载资源threadLocal = new ThreadLocal();Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsReader);} catch (Exception e) {e.printStackTrace();}}/*** 获取操作数据库的对象**/public SqlSession getSqlSession(){/*** 编写访问数据库*    1:在一个方法体里面  你调用任何多次数据库  我们只是要求 打开一次数据库 以及关闭一次就可以了*    2;简单的说连接是可以重用的*/SqlSession sqlSession = threadLocal.get();if(null!=sqlSession){//说明不是第一次访问数据库return sqlSession;}//是第一次访问数据库sqlSession = sqlSessionFactory.openSession();//方法线程中去threadLocal.set(sqlSession);return sqlSession;}/*** 关闭*/public void close(){SqlSession sqlSession = threadLocal.get();if(null!=sqlSession){sqlSession.commit();sqlSession.close();//将线程中的局部变量置空threadLocal.remove();}}
}

5、IBatis的简单使用(二)(IBatis的数据传参的问题)

5.1、传递简单参数问题
5.1.1、编写mybatis.xml配置文件
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><!--这个文件的作用:是对mybatis的全局配置-->
<configuration><!--environments:环境+s,说明可以配置等多个环境这里配置的环境是:数据库的连接信息default:如果配置了多个环境 默认使用哪一个环境--><environments default="mysql"><!--配置一个环境:id:表示的是这个环境的名字逻辑意义上是可以随便写的--><environment id="mysql"><!--配置的是事务的类型 ,默认配置JDBC就可以了  一般情况下使用的就是这个类型--><transactionManager type="JDBC"></transactionManager><!--这个配置的是数据源  这里你可以认为是固定写法--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///test"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment><!--这里是可以配置多个环境的  要使用哪一个环境那么就就配置上面的default就可以了 --><environment id="oracle"><transactionManager type=""></transactionManager><dataSource type=""></dataSource></environment></environments><!--在全局配置文件中引入mapper.xml的配置文件--><!--带参数--><mappers><mapper resource="UserMapper1.xml"></mapper></mappers>
</configuration>
5.1.2、编写UserMapper1.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 namespace="UserMapper"><!--传递简单参数  通过id更新数据parameterType:表示的是传进去的参数的数据类型这个数据类型有两种写法1:写Java中数据类型的全路径   java.lang.String   java.lang.Integer2:使用mybatis中的数据类型  这个数据类型与 java中的数据类型是一一对应的之前的占位符?在这里写成:#{写对应的key的名字}简单的数据类型  一个字符串   一个int  一个float  没有key  那么这个时候 这个key可以随便写 但是为了见名之意   一般写成value--><insert id="insert" parameterType="map">insert into t_user(username,password) values (#{username},#{password});</insert><update id="update" parameterType="string">update  t_user set username='王五' where username=#{username};</update><select id="select" parameterType="int" resultType="com.szq.User">select * from t_user where id=#{value};</select><delete id="delete" parameterType="int">delete from t_user where id=#{id}</delete></mapper>
5.1.3、编写测试代码(CRUD)
package com.szq.parameter;import com.szq.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.HashMap;public class Test002 {/*** 测试带参数*/@Testpublic void testUpdate(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();sqlSession.update("UserMapper.update","张三");myBatisUtils.close();}@Testpublic void testSelect(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();Object o = sqlSession.selectOne("UserMapper.select", 2);System.out.println(o);myBatisUtils.close();}@Testpublic void testDelete(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();sqlSession.delete("UserMapper.delete",2);myBatisUtils.close();}
}
5.2、传递map集合
5.2.1 、编写xml配置文件
<insert id="insert" parameterType="map">insert into t_user(username,password) values (#{username},#{password});</insert>
5.2.2、编写测试代码
   @Testpublic void testInsert(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();HashMap<Object, Object> objectObjectHashMap = new HashMap<>();objectObjectHashMap.put("username","张三");objectObjectHashMap.put("password","2222");sqlSession.insert("UserMapper.insert",objectObjectHashMap);myBatisUtils.close();}
5.3 、传递数组
5.3.1 、编写xml配置文件
<!--传递数组--><!--动态sql传递数组的问题通过一连串的id 找用户对象select * from t_user where id in (6,7,8)<if>标签用来做条件判断如果前端传递的是数组类型的数据  那么 这里使用  list来接收遍历数据的时候 那么还是使用 array来做遍历collection:表示的是要遍历的这个集合或者数组open:sql语句的构成 以什么开始close:SQL语句的构成以什么结束separator:遍历出来的数据之间使用什么进行分割item:每一次遍历出来的数据的名字注意:每一次遍历出来的数据 要使用  #{遍历的名字} 去进行获取--><select id="findUserById" resultType="com.szq.User" parameterType="list">select * from t_user<if test="array!=null">where id in<foreach collection="array" open="(" close=")" separator="," item="id">#{id}</foreach></if></select>
5.3.2、编写测试代码
    /*** 传递数组*/@Testpublic void testFindUserById(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();int arr[]={4,5,6};List<User> users = sqlSession.selectList("UserMapper.findUserById", arr);System.out.println(users);myBatisUtils.close();}
5.4、传递集合
5.4.1、编写xml配置文件
 <!--传递集合--><select id="findUserById2" resultType="com.szq.User" parameterType="list">select * from t_user<if test="list !=null">where id<foreach collection="list" open="in (" close=")" separator="," item="id">#{id}</foreach></if></select>
5.4.2、 编写测试代码
  /*** 传递集合*/@Testpublic void testFindUserById2(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();ArrayList<Object> objects = new ArrayList<>();objects.add(4);objects.add(6);List<User> users = sqlSession.selectList("UserMapper.findUserById2", objects);System.out.println(users);myBatisUtils.close();}
5.5、传递自定义的类的对象
5.5.1、编写xml文件
 <!--通过用户名和密码找到用户对象表示的是传递的是 用户对象--><!--传递自定义数据类型User--><select id="select1" parameterType="com.szq.User" resultType="com.szq.User">select * from t_user t where  t.username=#{username} and t.password=#{password};</select>
5.5.2、编写测试代码
public void testSelect(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();
//        User user = new User(1,"张三","123");User user=new User();user.setUsername("张三");user.setPassword("123");User o = sqlSession.selectOne("UserMapper.select1",user);System.out.println(o);myBatisUtils.close();
}

说明:不能一次性传递多个简单的参数

因为后端在接受数据的时候 采用的key是随机的 也就说 可以随便写的 假设你传递了多个简单的参数 那么后端无法区分 这个值是哪一个的

没有办法进行传递 ------ 如果要进行传递 那么你就封装成 map集合 或者 java的类

6、动态SQL的问题

什么是动态SQL? 在进行查询的时候 会根据前端传递数据的条件 来动态的进行SQL语句的拼接的这种方法 就称为动态SQL

需求:前端随地的给定一串id 要求的是 这一串的id的用户信息全部查询出来 这一串id可以是任意的

id:1,2,3,4 或者3,2,4,5

select * from t_user where id in(不确定)

动态sql解决的问题

6.1、传递数组
<!--传递数组--><!--动态sql传递数组的问题通过一连串的id 找用户对象select * from t_user where id in (6,7,8)<if>标签用来做条件判断如果前端传递的是数组类型的数据  那么 这里使用  list来接收遍历数据的时候 那么还是使用 array来做遍历collection:表示的是要遍历的这个集合或者数组open:sql语句的构成 以什么开始close:SQL语句的构成以什么结束separator:遍历出来的数据之间使用什么进行分割item:每一次遍历出来的数据的名字注意:每一次遍历出来的数据 要使用  #{遍历的名字} 去进行获取--><select id="findUserById" resultType="com.szq.User" parameterType="list">select * from t_user<if test="array!=null">where id in<foreach collection="array" open="(" close=")" separator="," item="id">#{id}</foreach></if></select>
6.2、传递集合
 <!--传递集合--><select id="findUserById2" resultType="com.szq.User" parameterType="list">select * from t_user<if test="list !=null">where id<foreach collection="list" open="in (" close=")" separator="," item="id">#{id}</foreach></if></select>
6.3、更新数据
<!--插入数据prefix:前缀  拼接的前缀suffix:拼接的后缀suffixOverrides:这个是去掉结束位置的某一个符号  可以是任意的prefixOverrides:去掉开始的符号  这个符号是任意的--><insert id="insert222" parameterType="com.szq.User">insert into t_user<trim prefix="(" suffix=")" suffixOverrides="," prefixOverrides=""><if test="userName != null">userName,</if><if test="password !=null">password</if></trim><trim prefix="values(" suffix=")" suffixOverrides=","><if test="userName != null">#{userName},</if><if test="password !=null">#{password}</if></trim></insert>
6.4、动态sql和sql片段
<select id="findUserByCondition" parameterType="com.qf.cd.helloworld.User" resultType="com.qf.cd.helloworld.User">select * from t_user where 1=1<if test="userName != null">and userName=#{userName}</if><if test="password !=null">and password=#{password}</if></select><select id="findUserByCondition1" parameterType="com.szq.User" resultType="com.szq.User">select * from t_user<include refid="aa"></include></select><!--抽取sql标签抽取的sql在任何地方都可以进行调用--><sql id="aa"><where><if test="userName != null">and userName=#{userName}</if><if test="password !=null">and password=#{password}</if></where></sql>
7、iBatis的结果集的返回问题
7.1、返回简单数据
  <!--返回简单参数需求:通过用户名 查询用户id--><select id="findIdByUserName" parameterType="string" resultType="int">select id from t_user where userName=#{value}</select>
   @Testpublic void testFindIdByUsername(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();Object id = sqlSession.selectOne("UserMapper.findIdByUserName", "张三");System.out.println(id);myBatisUtils.close();}
7.2、返回自定义的类的对象
 <!--返回简单参数需求:通过id   查询用户对象--><select id="findUserById" parameterType="int" resultType="com.szq.User">select * from t_user where id=#{value}</select>
  @Testpublic void testFindUserByUsername(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();Object user = sqlSession.selectOne("UserMapper.findUserById", 6);System.out.println(user);myBatisUtils.close();}
7.3、返回list集合 但是集合中是常见的数据类型
   <!--返回list集合 但是集合中是常见的数据类型-->
<!--    需求:通过一连串的id 查询一连串的名字-->
<!--    如果返回集合的数据类型 那么下面的结果集的返回只用写 集合中泛型的数据类型就OK了--><select id="select2" parameterType="string" resultType="string">select username from t_user where id in(4,5,6);</select>
  /*** 返回list集合 但是集合中是常见的数据类型*/@Testpublic void testFindUserById(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<String> str = sqlSession.selectList("UserMapper.select2");System.out.println(str);myBatisUtils.close();}
7.4、返回一个集合 集合中的泛型是自定义的类的类型
 <!--返回一个集合 集合中的泛型是自定义的类的类型--><select id="select3" resultType="com.szq.User">select * from t_user ;</select>
/*** 返回集合,集合是自定义数据类型*/@Testpublic void testFindAllUser(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<User> users = sqlSession.selectList("UserMapper.select3");System.out.println(users);myBatisUtils.close();}
8、数据库的字段和实体不对应问题
8.1、解决问题之取别名
 <!--数据库的字段和实体不对应--><!--解决方法1:使用别名--><select id="findUserAll"  resultType="com.szq.parameter1.User"><!--数据库字段  as  实体类字段-->select id as userId,username as user_Name,password as pass_Word from t_user;</select>
  /*** 通过别名的方式*/@Testpublic void testFindUserById(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<User> o = sqlSession.selectList("UserMapper.findUserAll");System.out.println(o);myBatisUtils.close();}
8.2、通过结果集映射解决问题
 <!--通过结果集映射解决这个问题--><!--配置结果集映射关系--><!--type:是结果集返回的类型--><resultMap id="findUserAll2ResultMap" type="com.szq.parameter1.User"><!--配置主键映射--><!--property:写实体的字段 column:写数据库的字段--><id property="userId" column="id"></id><!--配置普通字段映射--><result property="user_Name" column="username"></result><result property="pass_Word" column="password"></result><result property="age" column="age"></result></resultMap><select id="findUserAll2"  resultType="com.szq.parameter1.User" resultMap="findUserAll2ResultMap">select * from t_user;</select>
 /*** 配置结果集映射*/@Testpublic void testFindUserById2(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<User> o = sqlSession.selectList("UserMapper.findUserAll2");System.out.println(o);myBatisUtils.close();}
9、一对一映射关系

需求:一个用户拥有一个身份证、一个身份证唯一的对应了一个用户

用户与身份证–>是一对一的关系 在查询 用户的时候 ,希望的是能查询出身份证

9.1、用户实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String username;private String password;private Integer age;//维护private IdCard idCard;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class IdCard {private int id;private String idNum;private int userId;
}
9.2 、编写方法的配置
<?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 namespace="UserMapper"><!--一对一映射关系--><!--查询到所有的用户以及各自的身份证号码--><!--配置结果集映射--><resultMap id="findUserAllResultMap" type="com.szq.oneToone.User"><!--配置主键--><id property="id" column="id"></id><!--配置普通字段的映射--><result property="username" column="username"></result><result property="password" column="password"></result><result property="age" column="age"></result><!--接下来配置一对一的映射关系property:这个实际上就是 java实体中 对象关系的名字javaType:数据类型(全限定名)column:这个是为了将上面的某一个列的内容给映射下来相当于 调用方法的时候要传值select:相当于要调用另外的mapper来实现整个逻辑--><association property="idCard" javaType="com.szq.oneToone.IdCard"><!--配置主键映射关系--><id property="id" column="cardid"></id><result property="idNum" column="idNum"></result><result property="userId" column="userId"></result></association></resultMap><select id="findUserAll"  resultMap="findUserAllResultMap">select * from t_user t1,t_idcard t2 where t1.id=t2.userId</select>
9.3、测试
/*** 一对一映射关系*/
public class Test001 {@Testpublic void testOneToOne(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<User> o = sqlSession.selectList("UserMapper.findUserAll");System.out.println(o);myBatisUtils.close();}
}
10、一对多映射关系

一个部门有多名员工,在查询部门时需求查出部门下的员工

10.1、部门以及员工实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {private int id;private String deptName;private String deptDes;private List<Emp> empList;}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {private int id;private String empName;private int gender;
}
10.2、编写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 namespace="DeptMapper"><!--一对多映射关系--><!--获取所有的部门,并且要获取一个部门下面的员工--><resultMap id="findDeptResultMap" type="com.szq.oneToMore.Dept"><!--主键映射--><id property="id" column="id"></id><!--配置普通字段映射--><result property="deptName" column="deptName"></result><result property="deptDes" column="deptDes"></result><!--一对多--><collection property="empList" ofType="com.szq.oneToMore.Emp"><id property="id" column="empid"></id><result property="empName" column="empName"></result><result property="gender" column="gender"></result></collection></resultMap><select id="findDept" resultMap="findDeptResultMap">select * from t_dept t1,t_emp t2 where t2.deptid=t1.id;</select>
10.3、测试

/*** 一对多映射关系*/
public class Test001 {@Testpublic void testOneToMore(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<Dept> o = sqlSession.selectList("DeptMapper.findDept");System.out.println(o);myBatisUtils.close();}
}
11、取别名的问题

为什么要整个别名? 因为我们很多时候在写 这个java类型的时候 都写的的全路径

简单的说就是为了解决 传入参数的类型过长 以及 返回参数的类型 过长的问题

mybatis.xml中进行配置

<!--取别名--><typeAliases><!--type:是要取别名的这个java类型alias:这个是别名的名字别名一般情况下是取给java实体类的  po   dto--><!-- <typeAlias type="com.szq.one2many.Dept" alias="deptbobo"></typeAlias><typeAlias type="com.szq.one2many.Employee" alias="empbobo"></typeAlias>--><!--这个就表示的是给这个包里所有的类都取别名默认的别名的名字是 类名的首写字母小写--><package name="com.szq.one2many"></package></typeAliases>
12、懒加载的问题
12.1、关闭积极的加载、开启懒加载
<!--iBatis本身的设置 -->
<!--mybatis.xml里面设置:注意放置顺序--><settings><!--是否使能延迟的加载 --><setting name="lazyLoadingEnabled" value="true" /><!--关闭那个积极的加载 --><setting name="aggressiveLazyLoading" value="false" /></settings>
12.2、xml配置问题
<!--mybatis.xml里面的mappers配置如下--><mappers><mapper resource="UserMapper4.xml"></mapper><!--懒加载配置如下--><mapper resource="IdCardMapper.xml"></mapper></mappers>
<?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 namespace="UserMapper"><!--一对一映射关系--><!--查询到所有的用户以及各自的身份证号码--><!--配置结果集映射--><resultMap id="findUserAllResultMap" type="com.szq.oneToone.User"><!--配置主键--><id property="id" column="id"></id><!--配置普通字段的映射--><result property="username" column="username"></result><result property="password" column="password"></result><result property="age" column="age"></result><!--接下来配置一对一的映射关系property:这个实际上就是 java实体中 对象关系的名字javaType:数据类型(全限定名)column:这个是为了将上面的某一个列的内容给映射下来相当于 调用方法的时候要传值select:相当于要调用另外的mapper来实现整个逻辑--><!--懒加载--><association property="idCard" column="id" javaType="com.szq.oneToone.IdCard" select="IdCardMapper.findIdCard" fetchType="lazy"></association></resultMap><select id="findUserAll"  resultMap="findUserAllResultMap">select * from t_user  where id=4;</select>
</mapper>
12.3、测试代码
/*** 测试懒加载*/
public class Test002 {@Testpublic void test(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<Object> objects = sqlSession.selectList("UserMapper.findUserAll");
//        System.out.println(objects);myBatisUtils.close();}
}
13、二级缓存的问题

缓存:简单的说就是将查询出来的数据 放到一个地方,下一次查询相同的数据的时候不用去查询数据库

直接从缓存里面取数据,这样能够减轻SQL数据库的压力。

13.1、一级缓存

一级缓存又叫做session缓存。整个缓存的生命周期由session来进行管理 ,session死了,那么缓存也没有了。

也就是说 一级缓存 实际上存在的范围是 sqlsession的创建完成到sqlsession的关闭之前。

    @Testpublic void test1(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();User users=sqlSession.selectOne("UserMapper.findUserAll");User users1=sqlSession.selectOne("UserMapper.findUserAll");User users3=sqlSession.selectOne("UserMapper.findUserAll");User users4=sqlSession.selectOne("UserMapper.findUserAll");User users5=sqlSession.selectOne("UserMapper.findUserAll");User users6=sqlSession.selectOne("UserMapper.findUserAll");User users7=sqlSession.selectOne("UserMapper.findUserAll");//清空一级缓存sqlSession.clearCache();sqlSession.commit();sqlSession.close();}

查询相同的数据,也就是说sql语句相同,在sqlsession的创建完成到sqlsession的关闭之前,相同的sql语句只会执行一次----一级缓存。一级缓存是不能跨session的 ,现实开发中并没有什么用 ,而且这个缓存的维护 ,也并不需要我们人为的去完成,缓存的使能和销毁都是由session自身去完成的

13.2、二级缓存

二级缓存解决了一级缓存的缺点,它能够session进行使用 ,在开发中 一般我们使用的都是二级缓存。

开启二级缓存

 <!--开启二级缓存--><setting name="cacheEnabled" value="true"></setting>

导入mybatis的ehcache的支持包

github上下载:https://github.com/mybatis/ehcache-cache/releases

在这里插入图片描述

在这里插入图片描述

在resource目录下配置ehcache.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcacheupdateCheck="false"><!-- 缓存写入文件目录    不需要你引入的  只是配置好就可以  他会默认来找当前的这个位置--><diskStore path="d:\\mytemp"/><!-- 数据过期策略 --><defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"/>
</ehcache>

在需要缓存内容的mapper上 使用cache标签

<!--二级缓存的地方-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
 * 测试二级缓存*/
@Test
public void test2(){MyBatisUtils myBatisUtils = new MyBatisUtils();SqlSession sqlSession = myBatisUtils.getSqlSession();List<Object> objects1 = sqlSession.selectList("UserMapper.findUserAll");myBatisUtils.close();MyBatisUtils myBatisUtils1 = new MyBatisUtils();SqlSession sqlSession1= myBatisUtils1.getSqlSession();List<Object> objects2 = sqlSession1.selectList("UserMapper.findUserAll");myBatisUtils1.close();MyBatisUtils myBatisUtils2 = new MyBatisUtils();SqlSession sqlSession2 = myBatisUtils2.getSqlSession();List<Object> objects3 = sqlSession2.selectList("UserMapper.findUserAll");myBatisUtils2.close();
}

**测试结果**![在这里插入图片描述](https://img-blog.csdnimg.cn/20200625204852339.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NzA4NDg1Nw==,size_16,color_FFFFFF,t_70#pic_center)

http://chatgpt.dhexx.cn/article/RwmUoT6Z.shtml

相关文章

IBatis——初步总结

IBatis是持久层的框架&#xff0c;也就是我们说的Dao层框架&#xff0c;关注数据库操作以及和Java对象之间的关联&#xff0c;我们将这样的框架也称之为ORM&#xff08;Object/Relaction Mapping&#xff09;框架.而这里映射的主要是我们的表和实体&#xff08;bean&#xff09…

XMind导入Markdown(利用Typora导出opml)

安装Xmind XMind 是一款非常实用的商业思维导图软件 首先&#xff0c;安装Xmind并打开。通过"帮助"——>“关于Xmind”&#xff0c;可以获取到当前的版本号为 XMind 8 Update 9 在"文件"——>“导入”&#xff0c;可以看到Xmind支持的导入格式仅有…

推荐一款高效Cpp解析xml工具--RapidXml

解析效率比Xerces DOM 快50-100倍&#xff0c;tinyxml快30-60 &#xff0c;作者自己牛逼哄哄的说这是他所知道的最快的xml解析库了~~ 作者介绍说&#xff1a;" The table below compares speed of RapidXml to some other parsers, and to strlen() function executed on…

C++中rapidxml用法及例子

rapidxml是一个快速的xml库&#xff0c;比tinyxml快了50-100倍。本文给出创建、读取、写入xml的源码。 由于新浪博客不支持文本文件上传&#xff0c;在使用下面代码需要先下载 rapidxml&#xff0c;关于这个库的下载地址为&#xff1a; 官方网站&#xff1a; http://rapidxml.…

C++ Xml解析的效率比较(Qt/TinyXml2/RapidXml/PugiXml)

C Xml解析的效率比较&#xff08;Qt/TinyXml2/RapidXml/PugiXml&#xff09; C Xml解析的效率比较QtTinyXml2RapidXmlPugiXml 问题背景测试环境Qt - QDomDocumentTinyXml-2RapidXmlPugiXml总结 通常我们在一些软件的初始化或者保存配置时都会遇到对XML文件的操作&#xff0c;包…

SlimXml和TinyXml,RapidXml的性能对比

July 18th, 2010 zero Leave a comment Go to comments 前两天有朋友问&#xff0c;我的SlimXml有没有和RapidXml对比过效率&#xff1f;我是第一次听说这个库&#xff0c;更不用说对比效率了&#xff0c;于是上他们网站看了下。 好家伙&#xff0c;居然号称比TinyXml快30&…

RapidXml使用

vs2017 rapidxml-1.13 1 RapidXml使用 1.1 创建xml #include <iostream> #include "rapidxml/rapidxml.hpp" #include "rapidxml/rapidxml_utils.hpp" #include "rapidxml/rapidxml_print.hpp"using namespace rapidxml;void crateXml(…

使用rapidxml解析xml

rapidxml是一个由C模板实现的高效率xml解析库&#xff0c;号称解析速度比tinyxml快50倍&#xff08;忽悠&#xff09;&#xff0c;并作为boost::property的内置解析库&#xff1a; 其独立版本的官网&#xff1a;http://rapidxml.sourceforge.net/ 使用rapidxml的方法tinyxml极其…

RapidXml读取并修改XML文件

RapidXml读取并修改XML文件 RapidXml介绍RapidXml读取与修改xml文件 RapidXml介绍 RapidXml尝试创建最快的XML解析器&#xff0c;同时保留可用性&#xff0c;可移植性和合理的W3C兼容性。它是一个用现代C 编写的原位解析器&#xff0c;解析速度接近strlen在同一数据上执行的函数…

c++开源库rapidxml介绍与示例

官方地址&#xff1a;http://rapidxml.sourceforge.net/ 官方手册&#xff1a;http://rapidxml.sourceforge.net/manual.html 也可以在github上下载到别人上传的rapidxml:https://github.com/dwd/rapidxml 1.头文件 一般我们用到的头文件只有这三个 #include "rapidx…

Ubuntu 18.04 LDAP认证

将ubuntu配置为通过ldap认证&#xff0c;使其成为ldap client&#xff0c;系统版本ubuntu 18.04。 一 软件安装 apt-get install ldap-utils libpam-ldap libnss-ldap nslcd配置1 配置2 配置3 配置4 配置5 配置6 配置7 配置8 配置8 二 认证方式中添加Ldap #auth-client-conf…

LDAP认证服务器

1.要准备的环境与软件(这里测试环境是Centos6.0-64位系统) alfresco-community-4.2.c-installer-linux-x64.bin (注: alfresco是一个免费开源系统&#xff0c;可以自己去下载) apache-tomcat-7.0.42.tar db-4.5.20.tar jdk-6u45-linux-x64.bin openldap-stable-20100219.tar ph…

Jumpserver部署+Ldap认证

内容导航 &#xff08;一&#xff09;jumpserver快速部署1&#xff0c;部署内容2&#xff0c;附上安装脚本3&#xff0c;解决github无法连接4&#xff0c;修改配置 &#xff08;二&#xff09;使用jumpserver1&#xff0c;登录信息2&#xff0c;添加主机3&#xff0c;web终端登…

SVN使用LDAP认证

前言 SVN架构 用户访问SVN服务器分为两个部分&#xff1a;认证与授权。 SVN内置了有认证与授权机制&#xff0c;其认证是通过SVN仓库内的passwd文件提供&#xff0c;但它是明文、静态的&#xff0c;不方便且安全性低。 SVN还支持外部的认证&#xff0c;比如SASL&#xff0c;…

ldap 认证 java_Java实现LDAP认证(上)

Baidu脑残&#xff0c;把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法&#xff0c;大同小异&#xff0c;第一种是通过Spring&#xff0c;适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求&#xff0c;用户名和密…

Harbor 整合ldap认证

前提&#xff1a; ldap服务器已经安装&#xff1a;OpenLDAP安装部署 harbor服务器已经安装&#xff1a;Harbro v1.8.0部署 一、ldap组织结构 1、登录信息 2、查看用户信息 二、harbor配置 1、使用默认密码登录&#xff0c;admin/Harbor12345 2、认证模式 3、测试ldap服务器…

ldap认证 java_Java实现LDAP认证(上) | 学步园

Baidu脑残&#xff0c;把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法&#xff0c;大同小异&#xff0c;第一种是通过Spring&#xff0c;适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求&#xff0c;用户名和密…

Zabbix 整合ldap认证

前提&#xff1a; zabbix部署完成&#xff1a;CentOS7.3 64位&#xff0c;搭建Zabbix3.4 ldap部署完成&#xff1a;OpenLDAP安装部署 一、LDAP服务端 1、ldap登录信息 2、查看ldap组织架构 3、添加zabbix默认用户Admin 二、Zabbix网页端 1、使用zabbix默认管理员用户登录 …

linux+配置ldap认证,Linux LDAP 认证配置

Linux通过LDAP方式&#xff0c;使用windows AD帐户登录linux shell&#xff0c;这个想法很cool吧。之前配置过一次&#xff0c;但过了太久忘记了&#xff0c;因此&#xff0c;今天把配 Linux通过LDAP方式&#xff0c;使用windows AD帐户登录linux shell&#xff0c;这个想法很c…

JumpServer 整合ldap认证

前提&#xff1a; ldap服务器已经安装&#xff1a;OpenLDAP安装部署 一、JumpServer安装 官网安装地址安装部署 - JumpServer 文档 1、一键部署 #系统版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) #默认会安装到 /opt/jumpser…