MyBatis

Posted on 2022-03-19 14:44  夜雨初凉  阅读(105)  评论(0编辑  收藏  举报

准备工作

具备的知识

  • java基础

  • jdbc技术

  • mysql数据库

  • maven工具

  • xml

环境

  • jdk 1.8

  • Mysql 5.7

  • maven 3.6.1

  • idea

一、MyBatis

1、MyBatis框架是什么?

框架:我们只要按照它的规则编写少量代码和配置就能使用它提供功能。

生活举例:去医院看病填写表格,那张表格就是别人准备好的条条框框

MyBatis是一个持久层的框架

 

2、持久层

2.1、持久化是什么?

程序里的数据从瞬时状态到持久状态的一个转换过程。

内存:断电即失 磁盘:持久数据

2.2、为什么需要持久化?

  • 程序中有些对象不允许丢失

  • 内存价格比较昂贵

  • 生活举例:冷藏

2.3、持久层是什么?

我们之前学过三层架构

  • dao(数据访问)层

  • service(业务逻辑处理)层、

  • controller(请求控制/处理)层。。。

持久化是一个动作,而dao层是所有完成数据持久化的代码块,层的界限更加的清晰

3、mybatis提供好处

  • 支持自定义sql、存储过程以及高级映射。

  • 帮我们几乎免除了所有的jdbc代码以及设置参数和获取结果集等工作。

  • 可以通过简单xml或注解来配置和映射原始类型、接口、java对象为数据库中的记录。

ORM(对象关系映射,object relational mapping)

java程序 ---------- 数据库 类 ---------- 表 属性 ---------- 字段 对象 ---------- 表记录

4、为什么要学MyBatis?

  • 帮助程序员将数据存入数据库中

  • 方便,传统的jdbc代码太复杂了,帮助我们简化它。

  • 用的人多

优点

  • 简单易学(本身就很小很简单,只要2个jar包+一点点配置文件就可以安装上mybatis了)

  • 灵活(mybatis不会对现有的程序或数据库加强有任何影响;sql语句都是写在xml配置文件里面,便于统一管理和优化)

  • 解除程序代码和sql语句的耦合度

  • 提供映射标签,支持对象与数据库字段关系映射

  • 提供对象关系映射标签,支持对象关系组建维护(数据库里面1对1、1对多、多对多在mybatis如何配置才能映射到java对象)

  • 提供xml标签,支持编写动态sql

5、开始使用MyBatis

5.1、文档

官方文档:https://mybatis.org/mybatis-3/zh/index.html

官方文档是最详细的,任何一个老师讲基本不会比它更详细了,我们老师只能简化它,将重要的提取出来。

5.2、创建一个maven工程

maven仓库地址:https://mvnrepository.com/

告诉同学们去Maven仓库中寻找MyBatis的jar,找到后...

pom.xml中添加 Mybatis 的jar包依赖,如下

<!-- mybatis -->
<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.4.6</version>
</dependency>

5.3、创建 mybatis-config.xml 配置文件

  • src/main/resources/mybatis-config.xml 文件大致如下

<configuration>
<!-- 写上我们mybatis的各种各样的配置拉 -->
<settings>
<!-- 告诉mybatis,使用驼峰命名法的规则来 转换数据的列名 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>

<!-- sql语句输出配置 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>

<!-- 别名定义 -->
<typeAliases>
<!-- <typeAlias type="java.lang.Integer" alias="integer"/>
<typeAlias type="entity.Student" alias="Student"/> -->
<package name="扫描指定报名"/>
</typeAliases>

<!-- 数据库环境配置的标签,该标签之中可以配置多个数据库连接环境
default="oracle":表示默认使用oracle的数据库环境
-->
<environments default="oracle">
<!-- oracle 连接环境 -->
<environment id="oracle">
<!-- type属性:
JDBC: 告诉mybatis 使用jdbc提供的事物提交、回滚
managed : 表示将事物的控制交给 j2ee容器
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源配置
type 属性:
pooled: 表示使用连接池的方式 来管理连接对象,每次访问数据库的时候 从连接池里面拿一个连接处理啊,用完之后 放回去
unpooled: 不使用连接池来管理嘛
jndi:在 j2ee 容器来中数据源
-->
<dataSource type="POOLED">
               <!--数据库驱动类-->
<property name="driver" value="oracle.jdbc.OracleDriver"/>
               <!--oracle jdbc连接串-->
<property name="url" value="jdbc:oracle:thin:@ip地址:端口号:SID"/>
<property name="username" value="用户名"/>
<property name="password" value="密码"/>
</dataSource>
</environment>

<!-- mysql 连接环境-->
<!-- <environment id="mysql">

</environment> -->
</environments>

   <!--引入多个映射文件的标签-->
<mappers>
       <!--引入指定的 映射(对象关系映射)文件-->
<mapper resource="映射文件路径"/>
</mappers>
</configuration>

配置文件讲解顺序如下

  • 连接数据库的环境配置<environments>

  • 事物配置<transactionManager>

    • type属性

      • JDBC--告诉mybatis 使用jdbc提供的 事物 控制 (提交、回滚)

      • MANAGED--事物的控制 交给j2ee容器来管理

  • 数据源配置<dataSource>

    • type属性

      • POOLED:使用连接池的方式来管理 连接对象

      • UNPOOLED:不使用连接池的方式来管理

      • JNDI:在j2ee容器中配置我们的数据源(没用过)

备注:不用oracle驱动jar的话不用管这个

maven安装本地jar到本地maven仓库中的命令

mvn install:install-file -Dfile=jar包的绝对路径 -Dpackaging=文件打包方式 -DgroupId=groupid名 -DartifactId=artifactId名 -Dversion=jar版本

示例

mvn install:install-file -Dfile=D:\develop\database\install\Oracle\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.jar -Dpackaging=jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.1.0

 

5.4、编写java类,在main方法中初始化MyBatis

核心代码:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(xxx)

main方法中示例:

public static void main(String[] args) throws IOException {
   //获得 类路径下的 mybatis-config.xml 配置文件输入流
   InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
   //让mybatis根据配置文件 来初始化 session 工厂
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
   //得到和数据库 交流的 会话对象
   SqlSession session = factory.openSession();

   System.out.println("===================和数据库会话的对象:"+session);

   //TODO 对数据库进行操作
   //....
   //....
   
   //关闭会话
   session.close();
   //关闭文件输入流
   in.close();

}

5.5、使用MyBatis操作数据库

5.5.1、简单查询示例

  • 映射器配置。建立映射的mapper文件,配置sql语句,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">
 <!-- mybatis通过命名空间找到对应的mapper配置文件 -->
<mapper namespace="com.hr.mapper.StudentMapper">
<select id="selectAll" resultType="com.hr.entity.Student">
select * from student
</select>
</mapper>
  • mybatis-config.xml中引入mapper文件

...
<mappers>
   <mapper resource="./mapper/StudentMapper.xml"/>
</mappers>
...
  • java代码调用mapper中的sql片段

//mapper的命名空间 点 sql块id
List<Student> list = session.selectList("com.hr.mapper.StudentMapper.selectAll");
  • 讲述映射规则, mybatis-config.xml开启驼峰命名规则映射。讲述数据库字段与类名属性要注意的地方

<!-- mybatis开启驼峰命名规则映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
  • 没有看到控制台打印sql语句怎么办?mybatis-config.xml中开启日志配置。

<!-- sql语句输出配置 -->
<setting name="logImpl" value="STDOUT_LOGGING" />

5.6、抽取MyBatis公共代码,封装MyBatisUtils类

参考代码如下:

public class MybatisUtils {
static SqlSessionFactory factory = null;

static {
//获得 类路径下的 mybatis-config.xml 配置文件输入流
InputStream in = null;
try {
in = Resources.getResourceAsStream("mybatis-config.xml");
//让mybatis根据配置文件 来初始化 session 工厂
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

/**
* 获取session
* @return
*/
public static SqlSession getSession() {
//如果为true,表示 自动比较事物 ,false 不会自动提交
// factory.openSession(true)

//无参的话 就是 false
return factory.openSession();
}

/**
* 关闭session
* @param session
*/
public static void closeSession(SqlSession session) {
if(session != null) {
session.close();
}
}
}

 

5.6、接口映射

5.6.1、接口与mapper文件之间的关系

  • 命名空间 --- 接口的完整类名

  • sqlId --- 接口中定义的方法名

XML示例

<?xml version="1.0" encoding="UTF-8" ?>
<!--mybatis 映射器文件的约束-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:这个映射器的命名空间,取个名字而已,
让外面可以通过这个名字来找到这个文件

mybatis中的接口映射:
如果这个映射器要和dao层的接口映射起来,那么这个namespace要填写
对应的 接口的完整类名
-->
<mapper namespace="com.zd.dao.StudentDao">
...
</mapper>

接口示例

package com.zd.dao;
/**
* 操作student表的dao层接口
*/
public interface StudentDao {
...
}

 

5.6.2、接口的方式示例 增、删、改、查

这个过程将演示和说明的内容如下

参数获取的方式有

  • #{} --- 占位符,我们以前写的sql语句中的 ?。即:动态解析--->sql预编译--->执行sql。能防止sql注入

  • ${} --- 拼接符,拼接字符串生成sql语句。即:动态解析--->sql编辑--->执行sql。不能防止sql注入,很少用

别名定义

  • mybatis-config.xml中<typeAliases>可以为实体类定义别名

  • 此外,mybatis也默认定义了一系列别名,可在TypeAliasRegistry.class中查看

XML中常见的转义符

&   &amp; 
<   &lt;
>   &gt;
"   &quot;
'   &apos;

<![CDATA[
<!--将该区域内的文本当做纯文本,即这里面 使用特殊字符 就不需要转义了-->
]]>

多个对象参数传递

xml配置

<!--查询学生列表
如果你的参数有多个,那么 parameterType 你可以不指定,
不指定默认就是 Map
-->
<select id="queryStuList"
parameterType="java.util.Map"
resultType="Student">
select * from student where
c_id = #{cid} and
stu_name like concat('%',#{stu.stuName},'%')
</select>

调用的java代码

...
//条件
Student stu = new Student();
stu.setStuName("张");
//调用查询
List<Student> list = stuDao.queryStuList(1,stu);
...

5.7、结果集映射

  • <resultMap> 结果集映射标签

    • <constructor> 实体类构造标签

    • <association>标签 --- 单个对象关联

    • <collection> --- 集合关联

      • fetchType:"lazy" 懒加载

示例1:

<!--手动映射
id: 给这个映射取个名字
-->
<resultMap id="StudentMap" type="com.zd.entity.Student">
<!--
column:查询结果的列名
property:将被映射到实体类中的属性名,

对于我们没有配置的属性/字段,没有配置的默认使用的就是自动映射
-->
<result property="stuSex" column="stu_sex" />

<!--一条sql语句里面有多表联查,通过以下这种方式来实现映射-->
<result column="c_id" property="clz.id" />
<result column="c_name" property="clz.name" />
</resultMap>

示例2:多对一 / 一对多 映射配置

<!--
此文件命名空间:com.zd.dao.StudentDao
-->

<!--多对一 关联查询结果集示例-->
<resultMap id="StudentMap"
type="com.zd.entity.Student">
<!--发送关联查询的sql语句-->
<association property="clz"
column="c_id" select="com.zd.dao.ClzDao.queryClzById"/>
</resultMap>

<!--查询学生列表-->
<select id="queryStuList" resultType="Student">
select * from student
</select>
<!--
此文件命名空间:com.zd.dao.ClzDao
-->
<!--一对多,手动映射 Clz班级表-->
<resultMap id="ClzMap" type="com.zd.entity.Clz">
<!--如果你将id作为参数 传递给了 collection中的语句,
就必须要在这里告诉mybatis id是谁
-->
<id property="id" column="id"/>
<!--如果你的实体类里面的那个属性是集合,你就用这个玩意儿-->
<!--mybatis解析到这里,就会发送sql语句,去关联查询-->
<collection property="stuList"
column="id" fetchType="lazy"
select="com.zd.dao.StudentDao.queryStuList" />
</resultMap>

<!--根据id 查询班级表-->
<select id="queryClzById"
parameterType="int"
resultType="com.zd.entity.Clz">
select * from clz where id = #{value}
</select>

 

5.8、MyBatis常用注解

5.8.1、@Alias 别名注解

@Alias("Clzz")
public class Clzz {
...
}

5.8.2、@Select 查询注解、@Param 参数注解

public interface TeacterMapper {

@Select(value = "select * from teacher ")
public List<Teacher> selectList();

@Select(value = "select * from teacher where id = #{identity}")
public Teacher selectById(@Param(value = "identity") Integer id);

}

 

5.8.3、@Insert、@Update、@Delete

下面只示例了 @Insert, @Update、@Delete 同学们依葫芦画瓢即可

public interface TeacterMapper {

@Insert("insert into teacher values(#{tea.id},#{tea.name})")
public void insert(@Param("tea") Teacher tea);

}

5.8.8、@Results 结果映射注解

一般配合如下注解使用

  • @Result

  • @Many 多个关联对象注解(通常注解在集合上)

  • @One 单个关联注解

public interface TeacterMapper {

@Results(id = "TeaRes",value = {
@Result(column = "tea_id",property = "id"),
@Result(column = "tea_name",property = "name"),

@Result(property = "clsList",
column = "tea_id",
many = @Many(fetchType = FetchType.LAZY,select = "selectClsListByTeaId")
),
@Result(property = "sch",
column = "s_id",
one = @One(fetchType = FetchType.LAZY,
select = "com.hr.mapper.SchoolMapper.selectByid"))
})
@Select(value = "select id tea_id,name tea_name,s_id from teacher ")
public List<Teacher> queryListUseResults();
}

5.9、MyBatis缓存配置

5.9.1、本地缓存(又称一级缓存)

一个会话中的数据进行缓存。默认为打开状态。

可以向同学们示例,在一个Session中反复调用同一个查询多次,结果只有第一次调用时发出了sql语句,后面的都是获取的缓存数据。

代码演示:

 

5.9.2、二级缓存(也是全局缓存)

在mapper文件中加入 <cache/>,就会打开二级缓存, 所有的select 语句都会被缓存,所有的 insert、update、delete会刷新缓存

代码演示:

 

 

5.9.3、如何引用其他命名空间(mapper)的缓存配置?

<cache-ref namespace="你的命名空间"/>

5.9.4、如何具体控制到 select、inert、update、delete 标签上的缓存

以上4个标签都具备useCache属性:

  • useCache:将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true,其他为false

select 标签还有一个能控制缓存的属性:

  • flushCache:将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存刷新,默认值 false。

5.10、MyBatis动态sql

  • if --- 条件判断

  • choose ...when...otherwise --- 相当于java中的 if...else if ...else...

  • trim --- 去掉多余的 两端多余的字符

  • where --- 用于where子句时

  • set --- 用于update语句时

  • foreach --- 循环遍历集合

  • bind ---创建一个变量,绑定到 标签局部环境之中。该变量值支持 OGNL 表达式.(可以理解为在方法里面定义了一个变量)

    • OGNL表达式:支持 +-*/运算,支持简单的对象方法调用...

示例1: if、where、set、foreach、choose ...when...otherwise

<!--动态sql演示-->
<select id="queryList"
parameterType="java.util.HashMap"
resultType="Student">
select * from student stu
<!--以后不准用 where 1=1,
拼接的条件 包裹在where标签之中,
mybatis会判断,where标签之内是否有生效的条件
如果有生效的条件,就会自动给你加上where 关键词,还会给你去掉
首个and
-->
<where>
<!--动态的条件
类似if示例
如果 stuName 不为null 并且 stuName不为 空字符串
-->
<if test="stu.stuName !=null and stu.stuName.trim() != ''">
and stu.stu_name like
concat('%',#{stu.stuName},'%')
</if>
<!--判断集合/数组是否不为空-->
<if test="nameList != null and nameList.size() > 0">
and stu.stu_name in
<!--循环标签,可以遍历数组/集合
collection:被遍历的集合 / 数组
open:在首次进入循环就立马 插入open中的字符串
close:循环结束后会插入 close中的字符串
separator:你可以把看做分隔符
item:通过item指定的名字来访问集合/数组中的每一项数据

for(String name:nameList){}
-->
<foreach collection="nameList"
open="(" close=")" separator=","
item="name">
#{name}
</foreach>
</if>
<!--日期判断的示例-->
<if test="stu.beginDate !=null">
<![CDATA[
and stu_birthday >= #{stu.beginDate}
]]>
</if>
<if test="stu.endDate != null">
<![CDATA[
and stu_birthday <= #{stu.endDate}
]]>
</if>
<!--
类似 if ... esls if ... else 示例
-->
<choose>
<when test="stu.getStuAge() &lt; 30">
and stu.stu_sex = '女'
</when>
<!--<when test=""></when>-->
<otherwise>
and stu.stu_sex = '男'
</otherwise>
</choose>

<!--别人传递了分页参数给我我就加上分页
类似 java中的 if判断

test:条件(里面是 OGNL表达式,可以百度了解一下OGNL表达式的用法)
-->
<if test="offset != null and size != null">
limit #{offset},#{size}
</if>
</where>
</select>

<!-- 动态sql修改示例-->
<update id="update" parameterType="Student" >
update student
<!--set标签会帮你去掉最后的 , 号-->
<set>
<if test="stu.stuName != null">
stu_name = #{stu.stuName},
</if>
<if test="stu.stuSex != null">
stu_sex = #{stu.stuSex},
</if>
</set>
where id = #{stu.id}
</update>

示例2:trim

  • 加入我现在有这样一条sql语句

<select ...>
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
  • 如果这些条件没有一个能匹配上会发生什么?最终这条 SQL 会变成这样:

SELECT * FROM BLOG WHERE
  • 如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样:

SELECT * FROM BLOG
WHERE
AND title like 'someTitle'
  • 我们可以用where标签来解决这个问题,where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

<select ...>
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
  • trim标签也可以完成相同的功能,写法如下

<select ...>
SELECT * FROM BLOG
<!--
trim会在 下面所有条件拼接完毕后,判断拼接完毕后的 字符串是否以 and开头,如果是的话就会去掉这个and,
然后在判定该字符串是否为有效字符串,若是则再在该字符串前面加上 where
-->
<trim prefix="where" prefixOverrides="and">
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</trim>
</select>

示例3: bind

<select id="queryList"
parameterType="java.util.HashMap"
resultType="Student">
<!--定义一个变量 a
该变量绑定 stu 对象中的 stuName 属性,后面的 sql语句访问变量 a 就相当于访问 stu.stuName
-->
<bind name="a" value="stu.stuName"/>

select * from student stu where stu.stu_name = #{a}
</select>

 

 

5.11、MyBatis 通用Mapper

5.11.1、tk MyBatis

TKMybatis 是基于 Mybatis 框架开发的一个工具,内部实现了对单表的基本数据操作,只需要简单继承 TKMybatis 提供的接口,就能够实现无需编写任何 sql 即能完成单表操作。

5.11.1.2、使用
  • pom.xml中加入依赖

<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.5</version>
</dependency>
  • 集成mybatis核心代码

//创建一个MapperHelper
MapperHelper mapperHelper = new MapperHelper();
//让插件装载mybatis配置
mapperHelper.processConfiguration(session.getConfiguration());
  • 常用注解

    • @Table(name = "表名") //此注解一般打在实体类上,用于表明此实体类映射的数据库表名是 xxx

    • @Id //此注解一般打在实体类的字段上,用于表明此字段 映射的是ID列

    • @Column(name="数据库列名") //此注解一般打在实体类的字段上,用于表明此字段 映射的是列名是xxx

    • @ColumnType(jdbcType = JdbcType.DATE) //此注解一般打在实体类的字段上,用于表明此字段对应的数据库类型

    • @KeySql(sql = "select student_seq.nextval from dual",order = ORDER.BEFORE) //此注解在遇到需要通过select语句获取id时使用

  • 组装条件部分代码示例

//指定构造student的条件
Example condition = new Example(Student.class);
//创建组装条件的对象(criteria[kraɪ'tɪəriə] 标准/原则), 之后开始组装
condition.createCriteria().andEqualTo("height", "170").andLike("name", "%张三%");
//根据id列排序
condition.orderBy("id");

 

5.11.1.3、完整示例
  • 实体类 Student 定义如下

import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;

/**
* 映射 student表的实体类
*/
//告诉mybatis 通用mapper插件,我这个实体类对应的对应的是 t_student
@Table(name = "t_student")
public class Student implements Serializable {
//主键
//告诉tk mybats 通用mapper插件这个字段是主键
@Id
private Integer id;
//学生的名字

private String stuName;
//年龄
private Integer stuAge;
//分数
private Double stuScore;
//出生日期
private Date stuBirthday;
//性别
private String stuSex;
//这个学生所属的班级
private Clz clz;

public Student() {
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getStuName() {
return stuName;
}

public void setStuName(String stuName) {
this.stuName = stuName;
}

public Integer getStuAge() {
System.out.println("调用了 getStuAge方法....");
return stuAge;
}

public void setStuAge(Integer stuAge) {
this.stuAge = stuAge;
}

public Double getStuScore() {
return stuScore;
}

public void setStuScore(Double stuScore) {
this.stuScore = stuScore;
}

public Date getStuBirthday() {
return stuBirthday;
}

public void setStuBirthday(Date stuBirthday) {
this.stuBirthday = stuBirthday;
}

public String getStuSex() {
return stuSex;
}

public void setStuSex(String stuSex) {
this.stuSex = stuSex;
}

public Clz getClz() {
return clz;
}

public void setClz(Clz clz) {
this.clz = clz;
}

@Override
public String toString() {
return "Student{" +
"id=" + id +
", stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
", stuScore=" + stuScore +
", stuBirthday=" + stuBirthday +
", stuSex='" + stuSex + '\'' +
", clz=" + clz +
'}';
}

public Student(Integer id, String stuName, Integer stuAge, Double stuScore, Date stuBirthday, String stuSex) {
this.id = id;
this.stuName = stuName;
this.stuAge = stuAge;
this.stuScore = stuScore;
this.stuBirthday = stuBirthday;
this.stuSex = stuSex;
}
}
  • 操作t_student表的mapper接口定义如下

import com.zd.entity.Student;
import tk.mybatis.mapper.common.Mapper;

import java.util.List;

/**
* 操作student表的dao层接口
*/
public interface StudentMapper extends Mapper<Student> {
/**
* 自定义较为复杂的查询
* @return
*/
List<Student> queryList();
}
  • 测试


import com.zd.entity.Student;
import com.zd.mapper.StudentMapper;
import com.zd.utils.DateUtils;
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 tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.RowBoundsMapper;
import tk.mybatis.mapper.entity.Config;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.mapperhelper.MapperHelper;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class MybatisTest {
public static void main(String[] args) throws IOException {
//创建session对象的工厂
SqlSessionFactory factory = getSqlSessionFactory();
//搞第一个session对象出来
SqlSession session = factory.openSession();
//初始化(集成) 通用mapper的配置
initCommonMapperConfig(session);
//测试通用mapper的方法
testCommonMappe(session);


/*
*用完这个和数据库交流的回话之后呢,一定要 关闭/释放它.
* 将其修改为空闲的状态。
* 和 Connection.close概念是不一样的。
*/
session.close();
}



/**
* 初始化通用mapper的配置
*
* @param session
*/
public static void initCommonMapperConfig(SqlSession session) {
//创建一个MapperHelper
MapperHelper mapperHelper = new MapperHelper();
/*
可省略的配置---begin
*/
//特殊配置
Config config = new Config();
//主键自增回写方法,默认值MYSQL,详细说明请看文档
config.setIDENTITY("MYSQL");
//支持getter和setter方法上的注解
config.setEnableMethodAnnotation(true);
//设置 insert 和 update 中,是否判断字符串类型!=''
config.setNotEmpty(true);
//校验Example中的类型和最终调用时Mapper的泛型是否一致
config.setCheckExampleEntityClass(true);
//启用简单类型
config.setUseSimpleType(true);
//枚举按简单类型处理
config.setEnumAsSimpleType(true);
//自动处理关键字 - mysql
config.setWrapKeyword("`{0}`");
//设置配置
mapperHelper.setConfig(config);
/*
可省略的配置---end
*/
//注册通用接口,和其他集成方式中的 mappers 参数作用相同
//4.0 之后的版本,如果类似 Mapper.class 这样的基础接口带有 @RegisterMapper 注解,就不必在这里注册
mapperHelper.registerMapper(Mapper.class);
//配置 mapperHelper 后,执行下面的操作
mapperHelper.processConfiguration(session.getConfiguration());
}


/**
* 获取 SqlSessionFactory
*
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
InputStream input = null;
SqlSessionFactory factory = null;
try {
input =
MybatisTest.class
//获取类加载器
.getClassLoader()
//获取对应类信息目录下的文件输入流
.getResourceAsStream("mybatis-conf.xml");
/**
* mybatis用的是 工厂设计模式
*/
//session工厂构建器
SqlSessionFactoryBuilder builder =
new SqlSessionFactoryBuilder();
//利用这个工厂的构建器 去创建一个session工厂
factory = builder.build(input);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
//关闭文件的输入流
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return factory;
}

/**
* 获取操作数据的 session对象
*
* @return
*/
public static SqlSession getSqlSession() {
//利用这个工厂获取一个空闲的session
SqlSessionFactory factory = getSqlSessionFactory();
//获取了一个 打开了事物的 session
SqlSession session = factory.openSession();
return session;
}

/**
* 测试通用mapper的方法
* @param session
*/
public static void testCommonMappe(SqlSession session) {
//操作student表的接口
StudentMapper mapper = session.getMapper(StudentMapper.class);
// List<Student> list = mapper.selectAll();
//以前的那种写法是否支持测试
// List<Student> list = mapper.queryList();
// System.out.println(list);
//测试 通用mapper添加
Student stu = new Student(
8, "大丁丁", null,
null, null, null);
// int i = mapper.insert(stu);
// System.out.println("插入后返回的是什么呢?---"+i);

// mapper.delete(new Student());
//修改全部的字段,排除主键
// mapper.updateByPrimaryKey(stu);
//只修改不为null的字段
// mapper.updateByPrimaryKeySelective(stu);


/*
*example 条件示例
*/
Example example = new Example(Student.class);
//利用这个example创建一个标准的条件对象
example.createCriteria()
// = 匹配
.andEqualTo("id", 3)
// and 连接
// .andEqualTo("stuSex","女")
.orEqualTo("stuSex","女")
;

//将条件交给它
mapper.selectByExample(example);

//分页查询
//条件参数
Student s1 = new Student();
s1.setStuSex("女");
//分页参数
int current = 2;//当前页
int size = 3; //每页显示数量

RowBounds bounds = new RowBounds((current - 1)* size,size);
List<Student> stus = mapper.selectByRowBounds(s1, bounds);
//当你看到日志中获取的结果集没有分页时不要怀疑,没有问题的。
//mybatis自带的分页是基于内存的一种分页方式,你只要看到最后获取的结果集是正确的就可以了
System.out.println("分页之后的数据-----------size:"+stus.size());
System.out.println(stus);
//提交事物
// session.commit();
}
}

 

 

 

5.11.2、MyBatis Plus

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

注:mybatis plus 必须配合spring 容器来使用。

 

 

 

 

 

 

 

 

Copyright © 2024 夜雨初凉
Powered by .NET 9.0 on Kubernetes