文章目录
- 快速入
- Mapper代理开发
- 具体步骤
- 使用mapper代理中的包扫描
- 查询
- 字段名称不一致问题
- 方法一:对SQL语句起别名
- 方法二: 采用resultMap映射
- 条件查询
- 单条件查询
- SQL中特殊字符的处理
- 多条件查询
- 方式一:散装参数
- 方式二:对象参数
- 方式三:map集合参数
- 动态多条件查询
- 单条件动态查询
- 添加
- 更新
- 修改全部字段
- 修改动态字段
- 删除
- 根据指定值删除
- 动态批量删除
参考
快速入
一些pom.xml
依赖
<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!-- slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!-- logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.8</version>
</dependency>
</dependencies>
mybatis-config.xml
配置文件
注意,这里由于xml语法,&是非法的,将其转换成&
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- environments:配置数据库了环境信息,可以配置多个environment,通过defavlt属性切换不同的environment -->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&useOldAliasMetadataBehavior=true&useServerPrepStmts=true"/>
<property name="username" value="root"/>
<property name="password" value="5508769123"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBCC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jdbcc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&useOldAliasMetadataBehavior=true&useServerPrepStmts=true"/>
<property name="username" value="roottt"/>
<property name="password" value="114514"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载sql映射文件 -->
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
注意:这里的加载sql映射文件:有下面两种方法:1.挨个挨个写;2.包扫描
-
挨个挨个写
就是上面的写法,不过当有多个XXXMapper时需要将所有的都按照这个方法写出来
-
包扫描见下面的mapper代理开发部分
编写SQL映射文件
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:名称空间
id:sql语句唯一标识符(不能重复)
resultType:返回结果的类型,将来需要返回什么包装结果类型就写什么
-->
<mapper namespace="test">
<select id="selectAll" resultType="pojo.Student">
select * from student;
</select>
</mapper>
使用相对路径
一些测试类
Student.java
package pojo;
public class Student {
private Integer id;
private String name;
private String sex;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
MyBasitDemo.java
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 pojo.Student;
public class MyBasitDemo {
public static void main(String[] args) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.执行sql
List<Student> users = sqlSession.selectList("test.selectAll");
System.out.println(users);
// 4.释放资源
sqlSession.close();
}
}
注意
List<Student> users = sqlSession.selectList("test.selectAll");
中的test.selectAll
为StudentMapper.xml
中的指定的部分namespace.select id
Mapper代理开发
具体步骤
对于第一步,先了解maven打包之后的框架。
可以发现,在源文件中StudentMapper.xml
是放在resources
文件夹中,但是打包成target之后StudentMapper.xml
就没有resource
目录了,因此若要想StudentMapper.java
打包之后与StudentMapper.xml
同一个同一文件夹下,可以将源文件中StudentMaper.xml
放在与StudentMapper.java
同一个结构之下(不是复制放在一起而是新创路径),这样打包之后StudentMapper.xml
将会被自动塞进与StudentMapper.java
同一文件夹。如下:
- 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置同一目录之下
因此,配置文件mybatis-config.xml
也要随之改变
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&useOldAliasMetadataBehavior=true&useServerPrepStmts=true"/>
<property name="username" value="root"/>
<property name="password" value="5508769123"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载sql映射文件 -->
<mapper resource="mapper\StudentMapper.xml"/>
</mappers>
</configuration>
StudentMapper.java
package mapper;
import java.util.List;
import pojo.Student;
public interface StudentMapper {
List<Student> selectAll();
}
-
设置SQL映射文件的namespace属性为Mapper接口全限定名称,如下面的mapper.StudentMapper
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:名称空间 id:sql语句唯一标识符(不能重复) resultType:返回结果的类型,将来需要返回什么包装结果类型就写什么 --> <!-- 使用mapper代理 --> <mapper namespace="mapper.StudentMapper"> <select id="selectAll" resultType="pojo.Student"> select * from student; </select> </mapper>
-
在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回类型一致
StudentMapper.java
package mapper; import java.util.List; import pojo.Student; public interface StudentMapper { List<Student> selectAll(); }
使用mapper代理中的包扫描
如果Mapper接口名称和SQL映射文件名称相同,并且放在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
上述代理中,有一个StudentMapper
文件就要在mybatis-config.xml
添加一行映射
<mapper resource="mapper\StudentMapper.xml"/>
这样当映射多了的时候添加起来很麻烦,就干脆直接添加映射文件的文件夹,到时候直接扫描该文件夹下的映射文件
mybatis-config.xml
修改如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- environments:配置数据库了环境信息,可以配置多个environment,通过defavlt属性匹配不同的id值来切换不同的environment -->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&useOldAliasMetadataBehavior=true&useServerPrepStmts=true"/>
<property name="username" value="root"/>
<property name="password" value="5508769123"/>
</dataSource>
</environment>
<mappers>
<!-- Mapper 代理方法:包扫描 -->
<!-- 注意,格式不是路径格式那般,例如文件目录:com/mapper对应的应该写为:com.mapper
因为这里没有上级目录,所以特此说明 -->
<package name="mapper"/>
</mappers>
</configuration>
-
测试编码:
MyBasitDemo.java
import java.io.IOException; import java.io.InputStream; import java.util.List; 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 mapper.StudentMapper; import pojo.Student; // mapper代理开发 public class MyBasitDemo { public static void main(String[] args) throws IOException { // 1.加载mybatis的核心配置文件,获取SqlSessionFactory String resource = "config\\anyshare\\mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.获取SqlSession对象,用它来执行sql SqlSession sqlSession = sqlSessionFactory.openSession(); // 3.获取StudentMapper接口的代理对象 StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); //4.执行 List<Student> students = studentMapper.selectAll(); System.out.println(students); // 5.释放资源 sqlSession.close(); } }
查询
字段名称不一致问题
由于查询时要求类中的成员字段(Java采用驼峰命名)要与数据库中的标段相同(采用下划线),因此若不大同则会出现查询结果某成员为null
的情况
数据库:
Java:
可以发现,nameCh,nameEn均与数据库中字段不一致
查询方法采用上面Mapper代理中的MyBasitDemo.java
类方法
将会得到下面的结果:
方法一:对SQL语句起别名
对StudentMapper.xml
文件中的SQL语句中不对应的列名采用起与StudentMapper.java
中一致的别名。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:名称空间
id:sql语句唯一标识符(不能重复)
resultType:返回结果的类型,将来需要返回什么包装结果类型就写什么
-->
<!-- 使用mapper代理 -->
<mapper namespace="mapper.StudentMapper">
<sql id = "student_column">
id,name_ch as nameCh,sex,age,name_en as nameEn
</sql>
<select id="selectAll" resultType="pojo.Student">
select
<include refid = "student_column" />
from student;
</select>
</mapper>
再次执行查询语句:
方法二: 采用resultMap映射
由sql
相关知识可知,若要取别名则需要列出所有的列名(尽管不需要),这样是十分繁琐的。因此可以采用更为灵活的方法来映射
对StudentMapper.xml
进行修改
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<resultMap id = "studentResultMap" type = "pojo.Student">
<!-- 需要定义别名的放在这里面
id:完成主键字段映射
column:表的列名
property:实体类的属性名
result:完成一般字段的映射
column:表的列名
property:实体类的属性名
-->
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<select id = "selectAll" resultMap = "studentResultMap">
select * from student;
</select>
</mapper>
条件查询
单条件查询
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<!-- 不一致且需要起别名的字段放这里 -->
<resultMap id = "studentResultMap" type = "pojo.Student">
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<!--
参数占位符:
1. #{}:会将其替换为 ? ,为了防止SQL注入
2.${}:拼sql,会存在SQL注入问题
3.使用时机:
参数传递的时候:#{}
表名或者列名不固定的情况:${} 但会存在SQL注入问题
参数类型:parameterType:可以省略
-->
<select id = "selectById" parameterType = "int" resultMap = "studentResultMap">
<!-- #{一般与接口中方法参数名称一样} -->
select * from student where id = #{id};
</select>
</mapper>
在StudentMapper.java
中添加相应的接口方法Student selectById(int id);
package mapper;
import java.util.List;
import pojo.Student;
public interface StudentMapper {
List<Student> selectAll();
Student selectById(int id);
}
编写测试代码 MyBasitDemo.java
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo {
public static void main(String[] args) throws IOException {
// selectAll();
selectById(2);
}
public static void selectAll() throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectAll();
System.out.println(students);
// 4.释放资源
sqlSession.close();
}
public static void selectById(int id) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
Student student = studentMapper.selectById(id);
System.out.println(student);
// 5.释放资源
sqlSession.close();
}
}
SQL中特殊字符的处理
在xml与语句中<
为标记符号,因此例如语句 select * from student where id < #{id}; 是非法的。
处理方法:1.将非法符号转译;2.使用CDATA空间
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用mapper代理 -->
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<!-- 不一致且需要起别名的字段放这里 -->
<resultMap id = "studentResultMap" type = "pojo.Student">
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<select id = "selectAll" resultMap = "studentResultMap">
select * from student;
</select>
<!--
参数占位符:
1. #{}:会将其替换为 ? ,为了防止SQL注入
2.${}:拼sql,会存在SQL注入问题
3.使用时机:
参数传递的时候:#{}
表名或者列名不固定的情况:${} 但会存在SQL注入问题
参数类型:parameterType:可以省略
-->
<select id = "selectById" parameterType = "int" resultMap = "studentResultMap">
<!-- #{一般与接口中方法参数名称一样} -->
<!-- select * from student where id = #{id}; -->
<!-- xml表示符号,<为xml的表示符号,不可写在sql中(小于号) -->
<!-- 解决方法: -->
<!-- 1.转义字符 -->
<!-- select * from student where id < 2; -->
<!-- 2. 使用CDATA空间 将其识别为普通文本而非xml-->
select * from student where id
<![CDATA[
<
]]>
2;
</select>
</mapper>
多条件查询
多条件查询
参数接受
1.散装参数:如果方法中有多个参数,需要使用@Param(“SQL参数占位符名称”)
2.对象参数:对象的属性名称要和参数占位符名称一致
3.map集合参数:键的名称要和参数占位符名称一致
三种方式,StudentMapper.xml
均不用修改
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<!-- 不一致且需要起别名的字段放这里 -->
<resultMap id = "studentResultMap" type = "pojo.Student">
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<!-- 多条件查询 -->
<!-- 一般#{}里面的除了要与传入参数名称相同之外还要与类的属性名称一致 -->
<select id = "selectByConditions" resultMap = "studentResultMap">
select * from student where age < #{age}
and name_en like #{nameEn};
</select>
</mapper>
方式一:散装参数
StudentMapper.java
:
package mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import pojo.Student;
public interface StudentMapper {
// 1.散装参数
// 当存在多个参数时,需要使用Param来区分传给xml的参数
List<Student> selectByConditions(@Param("age") int age, @Param("nameEn") String nameEn);
}
MyBasitDemo.java
:
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
selectByConditions(25, "a");
}
// 1.散装参数
public static void selectByConditions(int age,String nameEn) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
// 参数处理
nameEn = "%" + nameEn + "%";
List<Student> students = studentMapper.selectByConditions(age, nameEn);
System.out.println(students);
// 5.释放资源
sqlSession.close();
}
}
方式二:对象参数
StudentMapper.java
:
package mapper;
import java.util.List;
import pojo.Student;
public interface StudentMapper {
// 2.对象参数
List<Student> selectByConditions(Student student);nameEn);
}
MyBasitDemo.java
:
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
selectByConditions(25, "a");
}
// 2.对象参数
public static void selectByConditions(int age, String nameEn) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
// 参数处理
nameEn = "%" + nameEn + "%";
// 封装对象
Student student = new Student();
student.setAge(age);
student.setNameEn(nameEn);
List<Student> students = studentMapper.selectByConditions(student);
System.out.println(students);
// 5.释放资源
sqlSession.close();
}
}
方式三:map集合参数
StudentMapper.java
:
package mapper;
import java.util.List;
import java.util.Map;
import pojo.Student;
public interface StudentMapper {
// 3.map集合参数
List<Student> selectByConditions(Map map);
}
MyBasitDemo.java
:
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
selectByConditions(25, "a");
}
// 3.map集合参数
public static void selectByConditions(int age,String nameEn) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
// 参数处理
nameEn = "%" + nameEn + "%";
// 封装对象
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("age", age);
hashMap.put("nameEn", nameEn);
List<Student> students = studentMapper.selectByConditions(hashMap);
System.out.println(students);
// 5.释放资源
sqlSession.close();
}
}
动态多条件查询
在上面使用的条件查询语句存在问题,当三种方式中MyBasitDemo.java
中的selectByConditions
方法参数age、nameEn没有值即为null
时SQL语句将查询不出结果(正常情况应该是返回该表的所有数据)。
使用逻辑判断:
StudentMapper.xml
:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<!-- 不一致且需要起别名的字段放这里 -->
<resultMap id = "studentResultMap" type = "pojo.Student">
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<!--
动态多条件查询
if:条件判断
test:逻辑表达式
-->
<select id = "selectByConditions" resultMap = "studentResultMap">
select * from student where
<if test = "age != null">
age < #{age}
</if>
<if test = "nameEn != null and nameEn !=''">
<!-- nameEn不为空且不为空字符串 -->
and name_en like #{nameEn};
</if>
</select>
</mapper>
-
当age !=null且nameEn==null时,SQL语句为:
select * from student where age < age;
但是这样也同样存在问题:不符合SQL规范
-
当agenull且nameEnnull时,SQL语句为:
select * from student where
-
当age==null且nameEn!=null时,SQL语句为:
select * from student where and name_en like nameEn;
解决方式:
一、用恒等式使其达到语法要求 1 = 1
,让所有条件格式都一样
<select id = "selectByConditionsDynamic" resultMap = "studentResultMap">
select * from student where 1 = 1
<if test = "age != null">
and age < #{age}
</if>
<if test = "nameEn != null and nameEn !=''">
<!-- nameEn不为空且不为空字符串 -->
and name_en like #{nameEn};
</if>
</select>
二、用 代替where
<select id = "selectByConditionsDynamic" resultMap = "studentResultMap">
select * from student
<where>
<if test = "age != null">
and age < #{age}
</if>
<if test = "nameEn != null and nameEn !=''">
<!-- nameEn不为空且不为空字符串 -->
and name_en like #{nameEn};
</if>
</where>
</select>
单条件动态查询
从多个条件中选择一个
与上面动态多条件查询的不同是:if条件可以满足多个并执行相应SQL语句,而单条件只能执行一个
- choose(when,otherwise):选择,类似于Java中switch语句
StudentMapper.java
package mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import pojo.Student;
public interface StudentMapper {
// 单条件动态查询
List<Student> selectByConditionDynamic(Student student);
}
MyBasitDemo.java
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
selectByConditionDynamic("小","a");
}
public static void selectByConditionDynamic(String nameCh,String nameEn) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
// 参数处理
nameEn = "%" + nameEn + "%";
nameCh = "%" + nameCh + "%";
// 封装对象
Student student = new Student();
student.setNameCh(null);
student.setNameEn(null);
List<Student> students = studentMapper.selectByConditionDynamic(student);
System.out.println(students);
// 5.释放资源
sqlSession.close();
}
}
StudentMapper.xml
可以写成两种
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<!-- 不一致且需要起别名的字段放这里 -->
<resultMap id = "studentResultMap" type = "pojo.Student">
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<select id = "selectAll" resultMap = "studentResultMap">
select * from student;
</select>
<select id = "selectByConditionDynamic" resultMap = "studentResultMap">
select * from student
<where>
<!-- 相当于switch -->
<choose>
<!-- 相当于case -->
<when test = "nameCh != null">
name_ch like #{nameCh};
</when>
<!-- 相当于case -->
<when test = "nameEn != null">
name_en like #{nameEn};
</when>
</choose>
</where>
</select>
</mapper>
或者
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 使用resultMap方法解决:列名与数据库为标段不一致问题 -->
<mapper namespace="mapper.StudentMapper">
<!-- 不一致且需要起别名的字段放这里 -->
<resultMap id = "studentResultMap" type = "pojo.Student">
<result column = "name_ch" property = "nameCh"/>
<result column = "name_en" property = "nameEn"/>
</resultMap>
<select id = "selectByConditionDynamic" resultMap = "studentResultMap">
select * from student
<where>
<!-- 相当于switch -->
<choose>
<!-- 相当于case -->
<when test = "nameCh != null">
name_ch like #{nameCh};
</when>
<!-- 相当于case -->
<when test = "nameEn != null">
name_en like #{nameEn};
</when>
</choose>
</where>
</select>
</mapper>
添加
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!--
keyProperty=的值为主键对应实体类属性的名称
useGeneratedKeys= "true",获取返回主键
-->
<insert id = "add" useGeneratedKeys= "true" keyProperty = "id">
insert into student(name_ch,sex,age,name_en)
values(#{nameCh},#{sex},#{age},#{nameEn});
</insert>
</mapper>
StudentMapper.java
package mapper;
import pojo.Student;
public interface StudentMapper {
// 添加
void add(Student student);
}
MyBasitDemo2.java
import java.io.IOException;
import java.io.InputStream;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
add("小李","男",16,"xiaoli");
}
public static void add(String nameCh,String sex,int age,String nameEn) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 封装对象
Student student = new Student();
student.setNameCh(nameCh);
student.setSex(sex);
student.setAge(age);
student.setNameEn(nameEn);
// 4.执行
studentMapper.add(student);
// 提交事务
sqlSession.commit();
//获取主键
System.out.println(student.getId());
// 5.释放资源
sqlSession.close();
}
}
更新
修改全部字段
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!-- 更新语句 -->
<update id = "update">
update student set
name_ch = #{nameCh},
name_en = #{nameEn},
sex = #{sex},
age = #{age}
where id = #{id};
</update>
</mapper>
StudentMapper.java
package mapper;
import pojo.Student;
public interface StudentMapper {
// 修改更新
int update(Student student);
}
MyBasitDemo.java
import java.io.IOException;
import java.io.InputStream;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo {
public static void main(String[] args) throws IOException {
update(10,"大红","男",25,"dahong");
}
public static void update(int id,String nameCh,String sex,int age,String nameEn) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 封装对象
Student student = new Student();
student.setId(id);
student.setNameCh(nameCh);
student.setSex(sex);
student.setAge(age);
student.setNameEn(nameEn);
// 4.执行
// 获取影响行数看是否成功更新
int count = studentMapper.update(student);
System.out.println(count);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
}
修改动态字段
当上面的修改全部字段
中的传入参数存在null时,SQL语句将会报错,因此我们需要做到:当传入的某个参数为null
时,需要在SQL语句中将其忽视。这就要在xml中使用set
标签来代替set。
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!-- 动态条件更新 -->
<update id = "update">
update student
<set>
<if test = "nameCh != null and nameCh != ''">
name_ch = #{nameCh},
</if>
<if test = "nameEn != null and nameEn != ''">
name_en = #{nameEn},
</if>
<if test = "sex != null and sex != ''">
sex = #{sex},
</if>
<if test = "age != null">
age = #{age}
</if>
</set>
where id = #{id}
</update>
</mapper>
StudentMapper.java
接口声明 与MyBasitDemo.java
方法实现无需改变
删除
根据指定值删除
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!-- 删除 -->
<delete id = "deleteById">
delete from student where id = #{id};
</delete>
</mapper>
StudentMapper.java
package mapper;
import org.apache.ibatis.annotations.Param;
import pojo.Student;
public interface StudentMapper {
// 根据id删除
int deleteById(int id);
}
MyBasitDemo.java
import java.io.IOException;
import java.io.InputStream;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
deleteById(1);
}
public static void deleteById(int id) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
// 获取影响行数看是否成功删除
int count = studentMapper.deleteById(id);
System.out.println(count);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
}
动态批量删除
相当于一次性执行多次上面的根据指定值删除
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<!-- 动态批量删除 -->
<!--
mybatis 会将数组参数封装为一个Map集合,
* 默认key值为:array => 数组,即写为:
<foreach collection = "array" item = "id" separator=",">
* 可以使用@Param注解改变map集合的默认key的名称,即现在下面用的
-->
<delete id = "deleteByIds">
delete from student where id in (
<foreach collection = "ids" item = "id" separator=",">
#{id}
</foreach>
);
</delete>
</mapper>
StudentMapper.java
package mapper;
import org.apache.ibatis.annotations.Param;
import pojo.Student;
public interface StudentMapper {
// 批量删除
int deleteByIds(@Param("ids") int[] ids);
}
MyBasitDemo.java
import java.io.IOException;
import java.io.InputStream;
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 mapper.StudentMapper;
import pojo.Student;
// mapper代理开发
public class MyBasitDemo2 {
public static void main(String[] args) throws IOException {
deleteByIds(new int[]{1,2});
}
public static void deleteByIds(int[] ids) throws IOException {
// 1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "config\\anyshare\\mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// 4.执行
// 获取影响行数看是否成功删除
int count = studentMapper.deleteByIds(ids);
System.out.println(count);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
}