Java核心框架
一、MyBatis
1.1MyBatis概念
MyBatis 是一款优秀的持久层ORM框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
Mybatis 基于持久层的ORM框架
对原生JDBC的封装
半自动化框架
学习成本低,使用简单,适合做一些业务多变的互联网项目
1.2环境搭建
1)下载资源jar包
官网: https://mybatis.org/mybatis-3/zh/index.html
2)项目下新建lib路径,需要的jar包放入lib路径下,选中右键add as lib…
3)编写代码程序
1.核心配置文件 : 做mybatis使用的核心基本配置
数据库的连接信息
是否使用连接池技术
SQL映射文件的扫描
2.SQL映射文件 : 定义SQL语句
3.测试执行使用mybatis框架连接数据库,执行SQL语句,得到结果
1.3Mybatis配置文件详解
1.3.1 核心配置文件
- properties标签:加载外部的properties文件(软编码)
- 加载外部文件格式
<!-- 加载外部的properties文件 -->
<properties resource="db.properties" />
- property:获取properties文件中数据时候,要通过
${}
的方式获取
<!--type="POOLED" 使用连接池结束-->
<dataSource type="POOLED">`
<!--定义数据库的连接参数-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
- typeAliases标签:定义类型别名
- alias属性:为指定的类设置别名
<!--为类型定义别名-->
<typeAliases>
<!--alias 设置别名-->
<!--<typeAlias type="com.yjxxt.pojo.Dept" alias="Dept"/>-->
<!--没有定义alias属性,默认别名为类型,不缺分大小写-->
<!--<typeAlias type="com.yjxxt.pojo.Dept"/>-->
</typeAliases>
- package name:设置一个包下所有的类型的别名,默认别名为类名(推荐使用)
<!--为类型定义别名-->
<typeAliases>
<!--设置一个包下所有的类型定义别名,别名默认类名,不区分大小写-->
<package name="com.yjxxt.pojo"/>
</typeAliases>
- transactionManager:事务管理机制
<!--transactionManager事务管理机制 : type="JDBC"选择使用JDBC项目的事务管理机制--><transactionManager type="JDBC"/>
- dataSource标签:数据源配置|是否使用来连接池技术
<!--type="POOLED" 使用连接池结束-->
<dataSource type="POOLED">
<!--定义数据库的连接参数-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
- mappers标签:扫描SQL映射文件和接口绑定方案文件
- mapper resource:对单个SQL映射文件扫描
<mappers>
<!--一个SQL映射文件的加载 : resource指定SQL映射文件在项目中的路径-->
<mapper resource="com/yjxxt/mappers/EmpMapper.xml"/>
</mappers>
- mapper class :扫描一个指定接口
- package name: 扫描一个包下的所有接口(推荐使用)
<mappers>
<!--扫描一个指定的接口-->
<!--<mapper class = "com.yjxxt.mappers.DeptMapper"/>-->
<!--扫描一个包下的所有接口-->
<package name="com.yjxxt.mappers"/>
</mappers>
1.3.2 SQL映射文件(mapper)
- mapper标签
- namespace属性:用于指定命名空间,定义SQL映射文件的唯一,不可重复
- 命名规范:包名.文件名 (不加后缀)
- select :相当于一个处理块
- id : 一个命名空间中sql语句的唯一标识,在一个命名空间中id属性不能重复,见名知意
- resultType : 结果类型。java中某个类型的名字,List集合,需要定义集合的泛型类型
- parameterType : 入参类型。
<mapper namespace="com.yjxxt.mappers.DeptMapper">
<select id="queryAll" resultType="dept">
select * from dept
</select>
</mapper>
1.4 三个查询方法
- selectList(“命名空间.id”)
- 用户查询多条数据情况,返回一个List集合, 没有查到数据返回空集合,不是返回null
- selectOne(“命名空间.id”)
- 用于查询单条数据,返回一个数据, 如果没有查到返回null
- selectMap(“命名空间.id”,key的字段名)
- 用于查询多条记录情况, 返回Map集合, 需要指定那个属性作为key, 通过key来查询value,sql查询结果作为value,指定的字段值(主键)作为key, 如果查不到, 返回一个空map集合,不是null
//selectOne("命名空间.id",Object) 查询一个数据,返回对应类型的一个结果,如果没有查询到返回null,第二个参数为sql语句的入参
Emp emp = session.selectOne("com.yjxxt.mappers.EmpMapper.queryEmpByNo",7369);
//根据命名空间.id找到SQL语句
System.out.println(emp);
//selectList("命名空间.id") 查询多个数据,返回一个List集合,如果没有查询到返回空的List
//selectList("命名空间.id",Object) 第二个参数为sql语句的入参*/
List<Emp> list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByDeptno", 20);
System.out.println(list);
list.forEach(System.out::println);
//selectMap("命名空间.id","作为key的字段名") 查询多个数据,返回一个Map集合,如果没有查询到返回空的Map
//selectMap("命名空间.id",Object,"作为key的字段名") 第二个参数为sql语句的入参,第三个参数返回Map集合中每条数据作为key的字段名,empno 是字段名,作为Map键值对的key,20 是部门编号是SQL语句的入参
Map<Integer, Emp> map = session.selectMap("com.yjxxt.mappers.EmpMapper.queryEmpByDeptno", 20, "empno");
1.5parameterType入参类型
如果执行的是条件查询,DML,需要在调用方法的时候传递参数,此时, 可以在sql标签中通过
parameterType属性指定参数的类型(别名|权限定名). 而在sql语句,通过#{}的方式获取参数
- 一个参数的查询
- 根据id查询用户信息,当参数只有一个,
#{}
可以任意填写匹配参数
<!-- 根据用户id查询用户信息 -->
<select id="queryById" resultType="string" parameterType="int">
select uname from t_user where id=#{id} <!-- 可以任意填写 -->
</select>
- 多个参数查询
- 多个参数传递时, 由于sqlSession中提供的查询方法,只允许传递一个sql参数, 因此可以对多个参数进行
封装,可以对象,集合,数组…
<!-- 入参类型: Javabean -->
<select id="queryUserByNamePwd" parameterType="user" resultType="User">
<!-- 如果参数为对象,可以通过#{对象的属性名}匹配不同的属性值 -->
select <include refid="user_all_field"/> from t_user where uname =#
{uname} and upwd = #{upwd}
</select>
- 入参类型
- 基本数据类型|包装类 String Date JavaBean数组 List Map
1.5.1基本数据类型|包装类
<!--基本数据类型|包装类 : 根据员工姓名模糊查询员工编号-->
<select id="queryIdByNameLike" parameterType="String" resultType="int">
select empno from emp where ename like '%'||#{ename}||'%'
</select>
1.5.2 String
<!-- 入参类型 : String 根据用户名查询用户信息-->
<select id="queryUserByName" parameterType="String" resultType="User">
select from dept where dname = #{0}
</select>
//测试入参类型: String
List<User>
list=session.selectList("com.yjxxt.mapper.UserMapper.queryUserByName","SMITH");
list.forEach(System.out::println)
1.5.3 Date
<!--Date: 根据员工入职日期查询-->
<select id="queryEmpByDate" parameterType="date" resultType="Emp">
select * from emp where hiredate = #{hiredate}
</select>
//测试入参类型:Date 1981/12/3
Date date = new SimpleDateFormat("yyyy/MM/dd").parse("1981/12/3");
list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByDate",date);
1.5.4 JavaBean
当sql需要的参数存在多个,并且为一个对象的不同属性,可以先把对个参数封装成JavaBean对象,然后作为一个入参传递sql中,占位符的名字需要匹配入参对象的属性名
<!--JAVABEAN: 根据员工姓名与部门编号同时查询-->
<select id="queryEmpByNameDeptno" parameterType="emp" resultType="Emp">
select * from emp where ename=#{ename} and deptno = #{deptno}
</select>
//测试入参类型:JavaBean
Emp emp = new Emp();
emp.setEname("SMITH");
emp.setDeptno(20);
Emp emp1 = session.selectOne("com.yjxxt.mappers.EmpMapper.queryEmpByNameDeptno",emp);
1.5.5Map
sql需要的多个参数,不属于一个对象的不不同属性值,可以封装为Map集合中的不同键值对
sql中占位符的名字需要匹配键值对的key
<!--Map: 根据员工薪资或者员工所在部门编号查询-->
<select id="queryEmpBySalDeptno" parameterType="map" resultType="Emp">
select * from emp where sal>#{sal} or deptno=#{deptno}
</select>
//测试入参类型:Map
Map map = Map.of("sal",1500,"deptno","10");
list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpBySalDeptno",map);
list.forEach(System.out::println);
1.5.6 数组|List
sql需要的多个参数是同种类型,一个字段的多个值,适合使用数组|list
sql语句中需要使用foreach标签进行遍历
<!--数组: 根据多个员工编号查询-->
<select id="queryEmpByidSome" resultType="Emp">
select * from emp where empno in (
<foreach collection="array" item="item" separator=",">
#{item}
</foreach>
)
</select>
注意:数组和List集合是不用写入参类型的,直接在select语句里面用foreach遍历即可
//测试入参类型:数组|List
list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByidSome",new int[]{7369,7499});
注意:入参类型和结果类型都不区分大小写
1.6 resultType 结果类型
查询到的结果集中的每一个数据的类型
- 结果类型
- 基本数据类型|包装类 String Date JAVABEAN List Map List< Map >
- 如果结果类型为List,resultType设置的为集合的泛型类型
1.6.1 Map
查询到一条数据,返回一个Map,一条数据的不同字段值作为Map集合中的不同键值对
<!--Map : 根据员工编号查询员工信息 -->
/*
* Map : 根据员工编号查询信息
* 返回值: key 属性名
* value 属性值
*/
<select id="queryMapById" parameterType="int" resultType="Map">
select * from emp where empno = #{empno}
</select>
//测试结果类型:Map
Map<String,Object> map = session.selectOne("com.yjxxt.mappers.EmpMapper2.queryMapById",7369);
1.6.2 List< Map >
<!--List<Map> : 根据薪资查询员工信息-->
/*
* List<Map> : 根据薪资查询员工信息,返回多个值
* 返回值: key 属性名
* value 属性值
*/
<select id="queryMapBySal" parameterType="map" resultType="Map">
select empno,ename,sal,comm,deptno from emp where sal between #{low} and #{high}
</select>
//测试结果类型:List<Map>
List<Map<String,Object>> list = session.selectList("com.yjxxt.mappers.EmpMapper2.queryMapBySal",Map.of("low",1000,"high",1500));
list.forEach(System.out::println);
1.7 事物
事务是数据库操作的最小单位,有着ACID的特性,应该保证一个事务下的多条SQL语句要么都成功,要么都失败.
Mybatis中配置了事务管理器,type属性设置JDBC,表示Mybatis采用和原生JDBC相同的事务管理机制
在Myabatis执行操作的开始,将自动提交功能关闭了,需要我们在执行DML操作时候,手动提交设置/设置自动提交
- 手动提交:
//在测试类中设置手动事物体提交
session.commit(); //事务提交
- 设置自动提交事务
//SqlSession的封装方法getSession()中设置
public static SqlSession getSession(){
SqlSession session = null;
if(factory!=null) {
//session = factory.openSession(); //默认手动 提交事务
session = factory.openSession(true); //设置自动 提交事务
}
return session;
}
1.7 接口绑定方案(重点)
Myabtis中,提供了一套接口绑定方案,程序员可以提供一个接口,然后提供一个与接口所对应的mapper.xml文件
Myabaits会自动讲接口与xml文件进行绑定,实际上就是Mybatis互根据接口和对应的xml文件创建一个接口的实现类,换言之,就是可以得到接口类型的一个对象,方便方法的调用
1.7.1实现流程
定义接口—>定义SQL映射文件—>(核心配置文件中扫描接口)—>测试类中调用接口中的抽象方法实现功能
1.定义接口
public interface DeptMapper {
//查询所有的部门信息
List<Dept> queryAll();
}
2.定义映射文件
定义规则:
1.接口名与SQL映射文件名字保持一致,同时放在同一个包下
2.SQL映射文件命名空间要求定义为: 与之绑定的接口的包名.文件名
3.sql标签的id属性值要求与所对应的抽象方法的方法名保持一致
4.SQL的参数与返回值要求与对应的抽象方法的参数与返回值保持一致
<mapper namespace="com.yjxxt.mappers.DeptMapper">
<select id="queryAll" resultType="dept">
select * from dept
</select>
</mapper>
3.核心配置文件中扫描接口
<mappers>
<!--扫描一个指定的接口-->
<!--<mapper class = "com.yjxxt.mappers.DeptMapper"/>-->
<!--扫描一个包下的所有接口-->
<package name="com.yjxxt.mappers"/>
</mappers>
4.测试类中使用
在使用时,通过SqlSession的getMapper() 方法,返回接口代理对象(通过接口.class获得接口的实例对象),从而调用对象来实现抽象方法
// 测试接口绑定方案
public class Class001_Test {
public static void main(String[] args) throws IOException {
//获取回话
SqlSession session = SessionUtils.getSession();
//获取接口的实现类对象
DeptMapper mapper = session.getMapper(DeptMapper.class);
//通过实现类对象调用重写后的方法
List<Dept> list = mapper.queryAll();
list.forEach(System.out::println);
//关闭回话
session.close();
}
}
1.7.2 通过接口绑定解决多参数传递问题
1.方法一
接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语句中使用.
public interface DeptMapper {
//修改update 根据部门编号修改部门名称
int updateDept(int deptno,String dname);
}
映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{参数名称}或#{param+数字}的
方式.
<!--多参数 : sql语句中占位符的名字默认为[arg1, arg0, param1, param2]-->
<select id="queryDeptByNameDeptno" resultType="dept">
select * from dept where dname = #{param1} and loc = #{param2}
</select>
2.方法二
接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语句中使用.
public interface DeptMapper {
//修改update 根据部门编号修改部门名称
int updateDept(@Param("deptno") int deptno,@Param("dname") String dname);
}
映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{参数名称}或#{param+数字}的
方式.
<!--update-->
<update id="updateDept">
update dept set dname=#{dname} where deptno = #{deptno}
</update>
1.7.3 批量增删改操作
定义接口
//定义接口(.java)
public interface DeptMapper2 {
//批量删除
//根据部门编号删除多个部门数据
int deleteDeptSome(List<Integer> list);
//批量新增
int insertDeptSome(List<Dept> list);
//批量更新
int updateDeptSome(List<Dept> list);
}
定义SQL语句
//定义批量增删改操作(.xml)
<mapper namespace="com.yjxxt.mappers.DeptMapper2">
<!--批量删除-->
<delete id="deleteDeptSome">
delete from dept where deptno in
<foreach collection="list" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</delete>
<!--批量新增-->
<insert id="insertDeptSome">
insert into dept select * from
(
<foreach collection="list" item="item" separator="union">
select #{item.deptno} deptno, #{item.dname} dname, #{item.loc} loc from dual
</foreach>
)
</insert>
<!--批量更新-->
<update id="updateDeptSome">
<foreach collection="list" item="item" open="begin" close=";end;" separator=";">
update dept set dname=#{item.dname} where deptno = #{item.deptno}
</foreach>
</update>
</mapper>
测试类
//测试批量操作
public class Class002_Test {
public static void main(String[] args) throws IOException {
//获取回话
SqlSession session = SessionUtils.getSession();
//获取接口的实现类对象
DeptMapper2 mapper = session.getMapper(DeptMapper2.class);
//批量删除
mapper.deleteDeptSome(List.of(90,91,64));
List<Dept> list = List.of(
new Dept(11,"嘻哈部","成都"),
new Dept(12,"嘿哈部","东北")
);
mapper.insertDeptSome(list);
mapper.updateDeptSome(list);
//关闭回话
session.close();
}
}
1.7.4 多表查询
resultMap
1.8 动态SQL(重点)
- 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同
条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个
列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
- 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显
著地提升了这一特性的易用性。
1.8.1 if标签
if标签是用在SQL语句中来判断是否满足给定的条件,如果满足则查询满足条件的语句,若条件为空,则查询所有结果
- where 标签
- 在有条件的时候,会自动在当前select语句中拼接where关键字
如果没有条件,不会拼接where关键字
会自动帮助把第一个满足条件的if标签的and关键字去掉
定义接口
//定义动态SQL接口
public interface UserMapper {
/**
* 查询用户数据
* @param username 根据用户名查询
* @param password 根据用户密码查询
* @return 返回查询到的用户数据
* 如果没有条件,查询所有数据
* 如果存在任意一个条件,根据这个条件进行查询
* 如果两个条件都存在,同时根据这两个条件进行查询
*
* 条件是否存在: 字符串类型的用户名|密码 !=null 同时 !=''
*/
List<User> queryUser(@Param("username") String username,@Param("password") String password);
}
定义SQL语句
test : 用于设置判断条件,类似java中的()中的内容
<mapper namespace="com.xxxx.mappers.UserMapper">
<!-- 动态SQL -->
<select id="queryUser" resultType="user">
select * from t_user <!-- where 1=1 -->
<!--
where :标签代替恒等式 where 1=1
在有条件的时候,会自动在当前select语句中拼接where关键字
如果没有条件,不会拼接where关键字
会自动帮助把第一个满足条件的if标签的and关键字去掉
-->
<where>
<!--
if 标签用于条件判断
test : 用于设置判断条件,类似java中的()中的内容
-->
<if test="username!=null and username!=''">
and username = #{username}
</if>
<if test="password!=null and password!=''">
and password = #{password}
</if>
</where>
</select>
</mapper>
测试类
public class UserTest {
public static void main(String[] args) {
//获取会话
SqlSession session = SessionUtils.getSession();
//获取某一个接口的实现类实例,参数为目标接口的Class对象
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.queryUser("", "");
list.forEach(System.out::println);
session.close();
}
}
1.8.2 choose…when…otherwise标签
定义接口
//定义动态SQL接口
public interface UserMapper {
/**
* 查询用户信息
* @param username
* @param password
* @return
* 如果存在用户名则只根据用户名查询,如果没有用户名,存在用户密码,根据用户密码查询,如果都不存在查询所有
*/
List<User> queryUserByNameOrPwd(@Param("username") String username,@Param("password") String password);
}
定义SQL语句
<mapper namespace="com.xxxx.mappers.UserMapper">
<!-- choose...when...otherwise -->
<select id="queryUserByNameOrPwd" resultType="user">
select <include refid="my"/> from t_user
<where>
<choose> <!-- 相当于java中的switch -->
<when test="username!=null and username!=''"> <!-- 相当于java中的case,条件写在test属性中 -->
and username = #{username}
</when>
<when test="password!=null and password!=''"> <!-- 相当于java中的case,条件写在test属性中 -->
and password = #{password}
</when>
<otherwise> <!-- 相当于java中的default -->
and 1=1
</otherwise>
</choose>
</where>
</select>
</mapper>
测试类
public class UserTest {
public static void main(String[] args) {
//获取会话
SqlSession session = SessionUtils.getSession();
//获取某一个接口的实现类实例,参数为目标接口的Class对象
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.queryUserByNameOrPwd("", "123456");
list.forEach(System.out::println);
session.close();
}
}
1.8.3 Set标签
set用于维护update的set子句,与where标签类似
如果满足条件,自动添加set关键字
会去除最后一个子句的多余的 ,
如果没有满足条件,不添加set关键字
定义接口
//定义动态SQL接口
public interface UserMapper {
/**
* 根据用户id修改用户信息
* @param user
* @return
* 如果存在用户名修改用户名,如果存在用户密码修改用户密码,如果都存在就都修改
*/
int updateUserById(User user);
}
定义SQL语句
<mapper namespace="com.xxxx.mappers.UserMapper">
<!-- set -->
<update id="updateUserById" parameterType="User">
update t_user
<!--set : 用户维护update的set子句,与where标签类似
如果满足条件,自动添加set关键字
会去除最后一个子句的多余的,
如果没有满足条件,不添加set关键字 -->
<set>
id = #{id},
<if test="username!=null and username!=''">
username = #{username}, ,必须添加,set标签不会自动添加
</if>
<if test="password!=null and password!=''">
password = #{password},
</if>
</set>
where id = #{id}
</update>
</mapper>
测试类
public class UserTest {
public static void main(String[] args) {
//获取会话
SqlSession session = SessionUtils.getSession();
//获取某一个接口的实现类实例,参数为目标接口的Class对象
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(2000);
user.setUsername("66");
user.setPassword("666");
int rows = mapper.updateUserById(user);
if(rows>0) {
System.out.println("成功!!!");
}else {
System.out.println("失败!!!");
}
session.close();
}
}
1.8.4 trim 标签
trim: 用于在前后添加或者删除一些内容
定义接口
//定义动态SQL接口
public interface UserMapper {
/**
* 根据用户id修改用户信息
* @param user
* @return
* 如果存在用户名修改用户名,如果存在用户密码修改用户密码,如果都存在就都修改
*/
int updateUserById(User user);
}
定义SQL语句
<mapper namespace="com.xxxx.mappers.UserMapper">
<update id="updateUserById" parameterType="User">
update t_user
<!--
trim: 用于在前后添加或者删除一些内容
prefix: 在前面添加内容
prefixOverrides: 在前面删除内容
suffix: 在后面添加内容
suffixOverrides: 在后面删除内容
-->
<trim prefix="set" prefixOverrides="id = #{id}," suffix="" suffixOverrides=",">
id = #{id},
<if test="username!=null and username!=''">
username = #{username}, <!-- ,必须添加,set标签不会自动添加 -->
</if>
<if test="password!=null and password!=''">
password = #{password},
</if>
</trim>
where id = #{id}
</update>
</mapper>
测试类
trim: 用于在前后添加或者删除一些内容
prefix: 在前面添加内容
prefixOverrides: 在前面删除内容
suffix: 在后面添加内容
suffixOverrides: 在后面删除内容
public class UserTest {
public static void main(String[] args) {
//获取会话
SqlSession session = SessionUtils.getSession();
//获取某一个接口的实现类实例,参数为目标接口的Class对象
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(2000);
user.setUsername("66");
//user.setPassword("666");
int rows = mapper.updateUserById(user);
if(rows>0) {
System.out.println("成功!!!");
}else {
System.out.println("失败!!!");
}
session.close();
}
}
1.8.5 bind 标签
定义接口
//定义动态SQL接口
public interface UserMapper {
/**
* 根据用户名做模糊查询
* @param name
* @return
*/
List<User> queryUserByNameLike(@Param("username") String name);
}
定义SQL语句
<mapper namespace="com.xxxx.mappers.UserMapper">
<!-- bind -->
<select id="queryUserByNameLike" parameterType="string" resultType="User">
<!-- select * from t_user where username like '%'||#{username}||'%' -->
select <include refid="my"/> from t_user
<where>
<if test="username!=null and username!=''">
<!-- 对参数username使用前进行再加工,先拼接前后% -->
<bind name="username" value="'%'+username+'%'"/>
username like #{username}
</if>
</where>
</select>
</mapper>
测试类
public class UserTest {
public static void main(String[] args) {
//获取会话
SqlSession session = SessionUtils.getSession();
//获取某一个接口的实现类实例,参数为目标接口的Class对象
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list2 = mapper.queryUserByNameLike("z");
list2.forEach(System.out::println);
session.close();
}
}