Mybatis的基础学习

  • Mybatis是一个持久层的框架、也是一个半自动的ORM(object relational mapping)框架

核心配置文件

properties属性

可以创建一个properties文件,将驱动、url、用户名和密码存放在其中

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql:///数据库的名称
db.username=用户名
db.password=密码

好处:我们切换数据的时候只需要更改properties文件中的配置即可
核心配置文件引用properties的方法

<properties resource="db.properties">

typeAliases类型别名的设置

当我们正常使用映射文件的时候,要求resultType必须要写全名称,若我们在核心配置文件中设置别名,就可以简写

<!--当映射文件中出现person就表示是com.jiale.beans.Person的对象-->
<typeAliases>
	<typeAlias type="com.jiale.beans.Person" alias="Person">
</typeAliases>

注意:别名可以忽略大小写
若项目中的别名有很多,需要配置很多的别名,可以通过package的方式来配置

<!--表示当前包下的所有实体类都配置了别名,别名的名称是类名-->
<typeAliases>
	<package name="com.jiale.beans">
</typeAliases>

environments 环境配置

配置数据库中的连接环境

<!--在配置的多个环境中,默认使用哪一个-->
<environments  default="development">
	<!--单个环境的唯一标识,和default中的必须写一样的-->
	<environment id="development">
		<!--事务管理,当前的连接是否使用事务-->
		<transactionManager  type="JDBC"/>
		<!--dateSource数据源 连接数据库的基础设置-->
		<dateSource type="POOLED">
			<property name="driver" value="${db.driver}"/>
			<property name="url" value="${db.url}"/>
			<property name="username" value="${db.username}"/>
			<property name="password" value="${db.password}"/>
		</dateSource>
	</environment>
</environments>
  1. transcationManager配置事务管理,目前可以配置两个参数
  • JDBC:使用jdbc的事务管理,也意味着开启了事务
  • MANAGED:不使用事务,mybatis不使用事务,适合mybatis和其他框架、插件配合使用,其他框架来做事务管理
  1. dateSource 数据源属性 type属性
  • POOLED:直接使用jdbc的连接池,但是使用连接池的概念,插件连接后,将连接放入到容器中来使用
  • UNPOOLED:不使用连接池的概念,每次访问都是新建一个连接
  • JNDI:使用第三方的连接池 c3p0 dbcp

添加映射文件

<mappers>
	<mapper resource="PersnMapper.xml">
</mappers>

plugings分页插件的使用

  1. 添加依赖
  2. 核心配置文件中添加设置
<!--配置第三方的插件-->
<plugins>
	<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
  1. 正常查询的时候添加分页设置
//添加分页设置
PageHelper.startPage(2,4);//当前的页数为2,每页的条数为4
  1. 可以使用分页提供的工具类
    pageNum:当前的页数 pageSize:每页的条数 size:当前页的条数 prePage:上一页的页码
    nextPage:下一页的页码 isFirstPage:是不是第一页 isLastPage:是不是最后一页 total:数据的总条数

类的映射文件

namespace命名空间

<mapper namespace="">

增删改查的sql标签

<insert id="addPerson" parameterType="com.jiale.beans.Person">
	insert into person (name,sex,age) values(#{name},#{sex},#{age})
</insert>
<select id="getPerById" parameterType="int" resultType="com.jiale.beans.Person">
	select * from person where id=#{id}
</select >
  • 每个增删改查都有一个id,作为当前sql语句的唯一标识
  • parameterType:表示当前sql传入的参数,如果传入的参数是对象,必须要写全名称
  • resultType:只能在select标签中使用,表示查询后返回的结果去映射的那个对象,如果返回的是多个数据,mybatis会自动封装为list集合,我们需要配置的是list集合的泛型类型

ResultMap的使用

使用前提:创建的对象和数据库表不能自动映射(对象的属性和数据库中的名称不一样),可以通过手动的方法来实现

<!--自定义映射结果集 id的唯一标识  type 将结果映射到那个类中-->
<resultMap id="baseUser" type="User">
	<!--配置标签有两个id和result,效果是一样的-->
	<!--每个标签中都可以设置property对象的属性和column数据库的列-->
	<id property="id" column="id"/>
	<result property="name" column="uname"/>
	<result property="age" column="uage"/>
</resultMap>
<!--使用resultMap,必须是使用手动映射-->
<select id="getPerById" parameterType="int" resultType="baseUser">
	select * from person where id=#{id}
</select >

数据添加后返回主键selectKey

<insert id="addPerson" parameterType="com.jiale.beans.Person">
	<!--在添加语句后执行对应的查询,将查询的结果赋值到id中-->
	<selectKey order="AFTER" keyProperty="id" resultType="int">
		SELECT LAST_INSERT_ID()
	</selectKey >
	insert into person (name,sex,age) values(#{name},#{sex},#{age})
</insert>

sql片段

类似于java中的封装,将重复出现的sql语句封装到sql片段中,在标签内进行调用

<!--添加一个sql片段将重复的SQL进行封装-->
<sql id="selectColumn">
	select id,name,sex,age from person
</sql>

<!--调用-->
<include refid="selectColumn">

Mybatis的动态sql

if where标签

  • if:if条件如果成立,sql就执行,如果使用多个使用and和or连接
  • where:判断where标签内是否有sql语句,有就添加,没有就不添加,可去掉sql最前面的and或or
select * from person
	<where>
		<if test="name != null and name != ''">
			and name like concat("%",concat(#{name},"%"))
		</if>
		<if test="sex!= null and sex!= ''">
			and sex = #{sex}
		</if>
		<if test="hobby != null and hobby != ''">
			and hobby= #{hobby}
		</if>
	</where>

choose标签

  • 一套判断,该判断里面只有一个判断是正确的
select * from person
	<choose>
		<when test="name != null and name != ''">
			where name like concat("%",concat(#{name},"%"))
		</when>
		<when test="sex!= null and sex!= ''">
			where sex = #{sex}
		</when>
		<when test="hobby != null and hobby != ''">
			where hobby= #{hobby}
		</when>
		<otherwise>
			where age = 28
		</otherwise>
	</choose>

set标签

  • 自动在标签的sql语句前面添加set,自动去掉后面的
update person
	<set>
		<if test="name != null and name != ''">
			and name like concat("%",concat(#{name},"%"))
		</if>
		<if test="sex!= null and sex!= ''">
			and sex = #{sex}
		</if>
		<if test="hobby != null and hobby != ''">
			and hobby= #{hobby}
		</if>
	</set>
	<where>
		 <if test="id != null and id != ''">
			and id= #{id}
		</if>
	</where>
  • 使用set标签的优点:避免了传递对象没有属性,在数据库中将对应的参数修改为null的情况

trim标签

去掉SQL语句的前后空格,还有个特殊的属性

  • prefix:添加前缀 suffix:添加后缀 prefixOverrides:去掉前缀 suffixOverrides:去掉后缀
select * from person
		<trim prefix="where" prefixOverrides="and">
		<where>
			<if test="name != null and name != ''">
				and name like concat("%",concat(#{name},"%"))
			</if>
			<if test="sex!= null and sex!= ''">
				and sex = #{sex}
			</if>
			<if test="hobby != null and hobby != ''">
				and hobby= #{hobby}
			</if>
		</where>

foreach标签

遍历标签,如果传递的数据是个数组或者集合,才会使用遍历标签
标签的属性:

  • collection:需要遍历的集合 item:表示迭代后每个对象的名称 open:在遍历开始前sql语句前面添加的内容
  • close:在遍历开始后sql语句前面添加的内容 separator:在遍历的过程中每次遍历中间添加的内容
insert into person (name,sex,age)
	<foreach collection="list" item="per" open="values(" close=")" separator="),(">
		#{per.name},#{per.sex},#{per.age}
	</foreach>

Mybatis的延迟加载

  1. 延迟加载的概述
    只能在嵌套循环里面使用,延迟加载也叫懒加载、按需加载
    在数据使用的情况下去加载数据,不使用就不加载,mybatis默认是关闭的,在正常使用中,如果加载的数据是大量的数据,加载的时候就会发生延迟,降低用户的使用体验,延迟加载根据具体的使用情况来决定是否使用
  2. 延迟加载的实现
    (1)导入依赖cglib
    (2)局部延迟加载:fetchType=“lazy”
    局部延迟加载的配置:必须在所有的association和collection标签中添加fetchType,如果不添加就没有延迟加载,会将所有的数据都查询
    (3)全局延迟加载
    在核心配置文件中设置
<settings>
	<!--开启全局的延迟加载-->
	<setting name="lazyLodingEnabled" value="true"/>
	<!--将读取任意属性就加载所有数据关闭-->
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

全局延迟加载的配置简单,但是不能精确的定义延迟加载具体的使用

mybatis的缓存机制

  • 查询的时候,同一个查询执行多次,浪费数据库的资源,在mybatis中可以使用查询缓存,查询的结果放入内存中,下一次查询直接获取
  • 如果要使用缓存,需要将对象做序列化的操作

一级缓存

sqlsession级别的缓存,默认是开启的
缓存的数据什么时候清理?

  1. 关闭sqlsession的时候
  2. 执行对应的删改语句

二级缓存

  • sqlsessionFactory级别的缓存,sqlsessionFactory在项目运行的时候创建,在项目关闭的时候销毁。二级缓存是默认关闭的。二级缓存是分块的,根据命名空间区分的。
  • 开启二级缓存,实体类必须序列化们没有序列化会报异常
    implements Serializeable
    在核心配置文件的settings里面设置
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true">

在映射文件中配置

<!--开启当前映射文件的二级缓存-->
<cache/>

二级缓存是一般项目优化最常用的一种

Mybatis的核心API介绍

Resources

  • 作用:读取一个文件将文件转化为字节流文件
//读取核心配置文件,转化为一个流对象
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactoryBuilder

  • 作用:将读取到的流对象创建一个sqlsession工厂
//创建一个sqlsession工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);

SqlSessionFactroy

  • 作用:生产sqlsession对象
//生产sqlsession对象
SqlSession sqlSession = factory.openSession();

SqlSession

  • 作用:可以调用五个方法来操作数据库insert update delete selectOne selectList
int i = sqlSession.insert("namespace.方法",p);

在执行增删改方法的时候使用commit方法,提交事务
还可以调用一个close方法 关闭sqlsesion

基于接口代理方式实现开发

优点:调用方法的入参都是由自己定义的,返回值类型包括是否增删改查的方法都是自己判断的

  1. 接口的开发规则
    - 在映射文件中,namespace必须是接口的全名称
    - 接口中的方法名必须和映射文件中标签的id一致
    - 接口中的方法对应的入参必须和映射文件中标签中的parameterType一致
    - 接口中的方法对应的返回值必须要和映射文件标签中的resultType类型一样(如果返回的是集合,映射文件配置的是泛型的类型,接口要配置list
  2. 配置calss实现接口的开发
    - 接口必须和映射文件的名字一样
    - 接口必须和映射文件在同一个目录下,在resouces中创建和接口同名的文件夹来存放。
<mappers>
	<!--通过calss来配置-->
	<mapper calss="con.jiale.mapper.Test"/>
</mappers>
<mappers>
	<!--表示该包下的所有接口都配置了calss-->
	<package name="con.jiale.mapper"/>
</mappers>

Mybatis的多表联合查询

关联查询

一次性将所有表的数据都查询出来

多对一查询

在dog类中添加一个person 表示多对一的关系
映射文件的配置

<mapper namespace="com,jiale.mapper.DogMapper">
	<!--自定义结果集  需要将person的数据进行匹配-->
	<resultMap id="baseDog" type="Dog">
		<id property="did" column="did"/>
		<result property="dname" column="dname"/>
		<result property="color" column="color"/>
		<!--专门设置多对一的标签 association-->
		<association property="per" javaType="Person">
			<id property="id" column="id"/>
			<result property="name" column="name"/>
			<result property="sex" column="sex"/>
			<result property="age" column="age"/>
		</association>
	</resultMap>

一对多查询

在person中添加一个List集合,表示所有的dog
映射文件的配置

<mapper namespace="com,jiale.mapper.DogMapper">
	<!--自定义结果集  需要将person的数据进行匹配-->
	<resultMap id="basePerson" type="Person">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="sex" column="sex"/>
		<result property="age" column="age"/>
		<!--专门设置一对多的标签 collection  ofType:集合泛型的类型-->
		<collection property="dogs" javaType="Dog">
			<id property="did" column="did"/>
			<result property="dname" column="dname"/>
			<result property="color" column="color"/>
		</collection>
	</resultMap>

多对多查询

  • 创建学生类有List集合,表示一个学生对应多个中间表的课程
  • 创建课程类有LIst集合,表示每个课程对应多个中间表的学生
  • 创建中间表有学生和课程
    映射文件的配置
<!--自定义结果集  学生类型-->
<resultMap id="baseStudent" type="Student">
	<id property="sid" column="sid"/>
	<result property="sname" column="sname"/>
	<result property="ssex" column="ssex"/>
	<result property="sage" column="sage"/>
	<!--配置学生和中间表的一对多关系-->
	<collection property="sc" javaType="Dog">
		<id property="scid" column="scid"/>
		<result property="score" column="score"/>
	</collection>
	<!--配置中间表和课程之间的关系-->
		<association property="co" javaType="Course">
			<id property="cid" column="cid"/>
			<result property="cname" column="cname"/>
			<result property="ctime" column="ctime"/>
		</association>
</resultMap>

嵌套查询

多对一查询

根据颜色查询Dog,并根据id查询Person

<!--自定义结果集-->
<resultMap id="baseDog" type="Dog">
	<id property="did" column="did"/>
	<!--设置多对一的关联关系  column:将第一次查询结果的某个列的值放入第二次查询中-->
	<!--select:查询person表要找的方法-->
	<association property="per" javaType="Person" column="pid" select="findPerById">
</resultMap>
<!--根据颜色查询Dog-->
<select id="findDogByColor" parameterType="String" resultMap="baseDog">
	select * from dog where color = #{color}
</select >
<!--根据pid查询person-->
<select id="findPerById" parameterType="int" resultType="Person">
	select * from person where id= #{pid}
</select >

一对多

根据id查询person,再根据pid查询对应的dog

<!--自定义结果集-->
<resultMap id="basePerson" type="Person">
	<!--设置一对多的关联关系-->
	<collection property="dogs" javaType="Dog" column="id" select="findDogByPid">
</resultMap>
<!--根据id查询person-->
<select id="findPerById" parameterType="int" resultMap="basePerson">
	select * from person where id= #{pid}
</select >
<!--根据pid查询dog-->
<select id="findDogById" parameterType="int" resultType="Dog">
	select * from dog where pid= #{id}
</select >

多对多

查询大于某个课时时间的课程

<!--自定义课程结果集-->
<resultMap id="baseCourse" type="Course">
	<id property="cid" column="cid">
	<!--设置一对多的关联关系-->
	<collection property="sc" javaType="SC" column="cid" select="findDogByPid">
</resultMap>
<!--根据课时查询课程-->
<select id="findCourseByTime" parameterType="int" resultMap="baseCourse">
	select * from course where ctime &gt; #{time}
</select >
<!--自定义课程结果集-->
<resultMap id="baseSC" type="SC">
	<!--设置多对一的关联关系-->
	<association property="st" javaType="Student" column="sid" select="findStudentBySid">
</resultMap>
<!--根据课程的cid查询中间表的方法-->
<select id="findSCByCid" parameterType="int" resultMap="baseSC">
	select * from student_course where cid= #{cid}
</select >
<!--根据sid查询学生的方法-->
<select id="findStudentBySid" parameterType="int" resultType="Student">
	select * from student where sid= #{sid}
</select >

Mybatis的注解

常用的注解

  • @insert @delete @update @select :curd
  • @results:和resultMap一样,自定义结果集 @result:在results下面使用,做列和属性的映射
  • @one :配置多对一映射 @many:配置一对多映射
@Insert("insert into person (name,sex,age) values (#{name},#{sex},#{age})")
//多对一
@Select("select * from dog where did = #{did}")
@Results({	
	@Result(property = "did",column="did"),
	@Result(property = "person",javaType="Person.calss"column="pid"),
	one = @One(select = "findPerById")
})
Dog findDogByDid(Integer did);
//一对多
@Select("select * from person where id= #{id}")
@Results({	
	@Result(property = "id",column="id"),
	@Result(property = "dogs",javaType="List.calss"column="id"),
	many= @Many(select = "findDogByPid")
})
Dog findPerById(Integer id);

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值