MyBatis-1

本文介绍了MyBatis作为轻量级持久化框架的主要特点和优势,包括将SQL语句配置在XML文件中以解耦,以及MyBatis对JDBC的封装。内容涵盖了MyBatis的四大对象、全局配置文件、DAO接口实现、动态SQL和日志配置等方面,重点解析了参数处理、结果集映射和关联查询的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

和数据库交互,持久化层框架,MyBatis
sql全部写在配置文件。解耦。
*MyBaits底层就是对原生JDBC的一个简单封装。
轻量级框架。

为什么不用原生jdbc?sql语句是硬编码在程序中,数据库层和java编码耦合

(1)导包
在这里插入图片描述
日志包也导一下 log4j
依赖类路径 log4j.xml配置文件

(2)
1.创建表
2.创建javabean封装表的数据
3.操作数据库的接口 dao接口

   public Employee getEmpById(Integer userId);
    //根据员工id查询员工
    public Employee getEmpByIdAndName(@Param("userId")Integer userId,@Param("name") String name);
	//根据员工id和名字来查询员工
	public List<Employee> getAllEmps();
	//刚刚是一个员工,如果是所有员工呢,员工的list
	@MapKey("id")
	public Map<Integer,Object> getAllEmpsReturnMap();
	//刚刚是一个员工,如果是所有员工呢,员工的map
    //主键:key 对象:value
	public  Map<String,Object> getEmpByIdReturnMap(Integer userId);
	//根据员工id查询员工,返回的是map
	//列名:key,列值:value
	public int updateEmployee(Employee employee);
	public int deleteEmployee(Integer userId);
	public int insertEmployee(Integer userId);

(3)mybatis全局配置文件 (mybatis-config)
1.properties resource引入外部数据源配置
这下面是配置数据源dataSource(数据库连接池)的 ${}取外部的值

 <dataSource type="POOLED">
 <property name="driver" value="${driver}"/>
 <property name="url" value="${url}"/>
 <property name="username" value="${username}"/>
 <property name="password" value="${password}"/>
 </dataSource>

2.settings有很多属性,其中有个属性mapUnderscoreToCamelCase
开启自动驼峰命名规则
有时候可以自定义结果集,把sql语句结果 封装 成javabean对象
这个时候,因为数据库的列名写少了(比如cname)
3.关联对象延迟加载,属性按需加载
在这里插入图片描述
4.typeHandlers 类型处理器
比如数据库里面数据类型是varchar 然后javabean里面是string
在这里插入图片描述
Mybatis四大对象
执行器Executor 负责执行sql语句//
参数处理器 调用typeHandlers 类型处理器
结果集处理器 把sql语句结果封装成javabean对象
处理器

4.environment 配置具体的环境 必备:1.数据源 2.事务切面类
(后来spring来做)

  测试人员的数据源呀 另一个服务器的数据源

在这里插入图片描述

5.从mybatis全局配置文件中可以构建sqlSessionFactory

(4)dao接口不是有很多操作数据库的方法吗
如何向数据库发送sql语句????
》》写这个dao接口的配置文件相当于实现类

namespace:名称空间,告诉mybaits,配置文件实现哪个Dao接口

<mapper namespace="com.at.dao.EmployeeDao">

 select:定义一个查询操作,
 id:方法名。因为这个配置是对于某个方法的实现!!!!! 
 
 resultType:方法返回值类型,默认规则
 如果是集合(list,map),就返回集合中元素的类型 ,
 返回单条记录的map的话就是map
 resultMap:自定义结果集  
 
 增删改不用写返回值类型,返回影响多少行
 
 让mybatis自动的将自增id  赋值给  传入对象的id属性
 useGeneratedKeys="ture"
 keyProperty=将刚刚自增的id封装给哪个属性

<select id="getEmpById" resultType="com.at.bean.Employee">
 select * from employee where id = #{id}
 </select>
 
  <update id="updateEmployee">
      update employee
          set name=#{name},gender=#{gender},email=#{email}
            where userId = #{userId}
  </update>
  
  <delete id="deleteEmployee">delete  from employee 
  where userId = #{userId}</delete>
   
   <insert id="insertEmployee"   useGeneratedKeys="true" keyProperty="userId">
   insert into employee(name,gender,email) 
   values(#{name},#{gender},#{email})
  </insert> 
  
<select id="getAllEmps" resultType="com.at.bean.Employee">
 select * from employee where id = #{id}
 </select>
 
<select id="getEmpByIdReturnMap" resultType="map">
 select * from employee where id = #{id}
 </select>

<select id="getAllEmpsReturnMap" resultType="com.at.bean.Employee">
 select * from employee where id = #{id}
 </select>

传参现象:
单参:
基本类型 #{随便写}
pojo:#{随便写}
多参:
#{}失效
除非0,1用这个参数的索引,或者param1,param2
原因:如果是传入了多个参数,mybatis会把多参封装到map中
所以取值要用map中的key(1,2。。。)

解决: 所以我们可以在方法的参数前加个@Param标签
指定封装到map中的key

为什么要写#{},参数的位置都是用?代替,参数是后来预编译设置进去的
如果写${},不是参数预编译,而是直接和sql语句进行拼串。
在这里插入图片描述

自定义结果集自己定义每一列数据和javaBean的映射规则。

应用情况:
关联查询(join查询)用它没错,你查出来的列值对应哪一个表,
分步查询可以,关联对象延迟加载,属性按需加载。在全局配置文件中。但是和数据库连接两次

解决方案:

1-1关联 javaBean对象有一个javaBean对象

  • 级联属性封装结果 property=对象名.属性
  • association标签 property=对象名 javatype=对象所在的类名
  • association标签可以分步查询 不写 javatype,写这个指定的sql ,用select=xxx (xxx为namespace.id),让mybatis调用指定的sql column=分布查询是哪一列的值

分步查询会造成严重性能的浪费,发了两个sql,结果只用到第一个sql。
在这里插入图片描述
所以分步查询可以,所有关联对象延迟加载,属性按需加载。在全局配置文件中,但是和数据库连接两次
在这里插入图片描述

1-n关联:外键在n表 javaBean对象有一个集合对象 List

  • collection标签 property=集合对象 ofType=集合元素的类名

n-n 关联: 有中间表

resultmap:自定义结果集
type:为哪一个javaBean定义映射规则

id column:指定主键列 (数据库) 
property:javaBean的哪个属性

result column:指定普通列 (数据库)
property:javaBean的哪个属性

<resultMap type="",id="">
  <id column="" property="" />
  <result column="" property="" />
  </resultMap>

级联属性封装结果:
在这里插入图片描述
两个表如果都有id,取别名: l.id 别名
在这里插入图片描述
association标签
在这里插入图片描述
分布查询
在这里插入图片描述
在这里插入图片描述

1-n
在这里插入图片描述
记得遍历List for循环
在这里插入图片描述
在这里插入图片描述
动态sql=sql语句动态拼串
应用场景:
1. Dao接口里面 select方法。如果你只是想根据传入对象的部分属性去查询
在这里插入图片描述

where=取出前面多余的and
trim: prefix=为整体sql加个where,prefixOverrides=取出前面多余的and   
<if test>
<choose> <when test>   <otherwise>
test:指定javabean属性的判断条件
xml文件中写这些 ><&&判断符,有些要写成转义符

<select id ="getTeacherByCondition"  resultMap="teacherMap">
 
 select * from t_teacher
 <trim prefix="where" prefixOverrides="and" >
 <if test="id!=null">
    and id > #{id}   
 </if>

  <if test="name!=null and name!="" ">
     and teacherName like #{name}  
 </if>
 
 <if test="birth!=null">
    and  birth_date &lt; #{birth}  
 </if>
</trim>
</select>

在这里插入图片描述
where查询后面跟着 in,也就是说你传入了一个集合,
多参封装进map,取值,规定map的key @Param
这个集合有几个对象你不知道,
也就是你这个in后面跟着几个对象你不知道
在这里插入图片描述
在这里插入图片描述


foreach collection=帮我们遍历集合,iteam=每遍历元素的值,
separator=, 

<select id ="getTeacherByIdIn"  resultMap="teacherMap">
   
   select * from t_teacher where id in 
  
   <foreach collection="ids" iteam="id_item" separator=","
    open="(" close=")" >
       #{id_item}
    </foreach>
    
  </select>
      
    

以前的更新是这个对象的全字段更新,太菜了,现在的的更新是部分字段更新
在这里插入图片描述
set:取出多余的,
在这里插入图片描述

(5)我们写的dao接口的实现文件(mapper文件)
mybatis是默认不知道的,
需要在全局配置文件中注册。

全局配置文件怎么去注册呢? 有个mapper标签

 mapper:引入我们自己编写的Dao接口的实现文件
 package name:可以批量注册我们的dao接口的实现文件
 <mappers>
 resource:可以在类路径下找资源 
 class:直接引入接口全类名,接口和实现文件同包同名
 <mapper class="com.at.bean.EmployeeDao"/>
 <mapper resource="EmployeeDao.xml"/>
 </mappers>

(6)

每个基于mybatis的应用,都是以一个SqlSessionFactory的实例为中心

1.根据全局配置文件 创建一个SqlSessionFactory

 String resource = "org/mybatis/example/mybatis-config.xml";
	 InputStream inputStream =Resources.getResourceAsStream(resource);
	SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);

2.获取数据库的一次会话 SqlSessionFactory.openSession(true)
底层就是获取到了数据库的连接
SqlSessionFactory:创建SqlSession对象(一个)
true:获取到的连接自动提交

一个SqlSession代表的就是和数据库的一次会话。
sqlSession对象,多线程不共享他,要操作就拿一个新的,
也就是不放在类下。

SqlSession openSession = SqlSessionFactory.openSession(true); 

3.SqlSession对象有个getmapper方法

EmployeeDao mapper=openSession.getMapper(EmployeeDao.class);
		int i =mapper.insertEmployee(new Employee(null,"lala","lalal@qq.com","女"));

在这里插入图片描述
没有给这个Dao接口写实现类,
Mybatis自动为这个Dao接口创建动态代理对象
class com.sun.proxy.$Proxy5

问题:
在ssm框架中,常用的日志输出为Log4j,
但按照常规的配置,涉及mybatis那部分日志不能打印出来的;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值