MyBatis 是一款优秀的持久层框架。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO为数据库中的记录。
MyBatis 前身是 IBatis ,本是 Apache 的一个开源项目 ;由apache software foundation 迁移到了google code,并且改名为MyBatis
实体类和 SQl 语句之间建立映射关系
持久化
持久化是程序数据在瞬时状态和持久状态间的转化过程
也就是将数据存入数据库(永久性的保存下来了)
ORM (Object Relational Mapping)对象关系映射
编写程序的时候,以面向对象的方式处理数据
保存数据的时候,以关系型数据库的方式存储数据
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.25version>
dependency>
写基本的mybatis 配置,包含了MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务范围和控制方式的事务管理器(TransactionManager),后面的学习还会往里面继续添加配置。
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://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://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=true" />
<property name="username" value="root" />
<property name="password" value="admin" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/hkp/mapper/UserMapper.xml" />
mappers>
configuration>
package com.hkp.entity;
import java.util.Date;
public class User {
private Integer id;
private String userCode;
private String userName;
private String userPassword;
private Integer gender;
private Date birthday;
private String phone;
private String address;
private Integer userRole;
private Integer createdBy;
private Date creationDate;
private Integer modifyBy;
private Date modifyDate;
@Override
public String toString() {
return "User{" +
"id=" + id +
", userCode='" + userCode + '\'' +
", userName='" + userName + '\'' +
", userPassword='" + userPassword + '\'' +
", gender=" + gender +
", birthday=" + birthday +
", phone='" + phone + '\'' +
", address='" + address + '\'' +
", userRole=" + userRole +
", createdBy=" + createdBy +
", creationDate=" + creationDate +
", modifyBy=" + modifyBy +
", modifyDate=" + modifyDate +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getUserRole() {
return userRole;
}
public void setUserRole(Integer userRole) {
this.userRole = userRole;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* @return
*/
List<User> getUser();
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
select * from smbms_user
select>
mapper>
package com.hkp.mapper;
import com.hkp.entity.User;
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 org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class TestUserMapper {
@Test
public void test() throws Exception {
//读取mybatis 核心配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//创建工厂构建器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
//使用 mybatis 核心配置文件 构建工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//打开 sql 会话(跟数据库打开了一个会话)
SqlSession sqlSession = sqlSessionFactory.openSession();
//使用sql会话执行sql语句
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> user = mapper.getUser();
//关闭会话,释放资源
sqlSession.close();
//查询到的数据
System.out.println("查询到的数据 : ");
for (User user1 : user) {
System.out.println(user1);
}
}
}
MyBatis 的核心对象:
mybatis-config.xml 是 MyBatis 核心配置文件
xxxMapper.xml SQL映射文件
SqlSessionFactoryBuilder
用过即丢,生命周期只存在方法内
可以通过 build 方法创建多个 SqlSessionFactory 实例
SqlSessionFactory
SqlSessionFactory 是每个 MyBatis 应用的核心
作用域整个应用
生命周期与应用的生命周期相同(即软件启动和结束相同)
作用是创建 SqlSession 实例
SqlSession sqlSession = sqlSessionFactory.openSession(Boolean boolean);
里面的参数可以加也可以不加 默认是 true ;
true :表示关闭事务控制
false : 表示开启事务控制
SqlSession
包含SQL 执行的所有方法
对应一次数据库会话,会话结束必须关闭
SqlSessionFactoryBuilder 和 SqlSessionFactory 在应用中只需要启动一次,SqlSession 可以启动多次 ;所以我们将 SqlSessionFactoryBuilder 和 SqlSessionFactory封装一下。
1、创建工具类
package com.hkp.utils;
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 java.io.IOException;
import java.io.InputStream;
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
//静态代码块,运行时只加载一次
static {
// 读取mybatis 核心配置文件
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
// 创建工厂构建器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 使用mybatis 核心配置文件 构建工厂
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
//将方法定义成static静态的,类外部的方法就可以通过类名打点调用该方法了
public static SqlSession getSqlSession() {
// 打开 sql 会话(跟数据库打开了一个会话)
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
2、测试运行
package com.hkp.utils;
import com.hkp.entity.User;
import com.hkp.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class TestUtil {
@Test
public void test() throws Exception {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//使用sql会话执行sql语句 "User.getUser" 配置文件中的命名空间和id
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.getUser();
//关闭会话,释放资源
sqlSession.close();
//查询到的数据
for (User user:users) {
System.out.println(user);
}
}
}
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://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://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=true" />
<property name="username" value="root" />
<property name="password" value="admin" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/hkp/mapper/UserMapper.xml" />
mappers>
configuration>
属性说明 (注意 :顺序不能反,不然会报错)
configuration 配置
properties 可以配置在java属性配置文件中
settings 修改 Mybatis 在运行时的行为方式
typeAliases 为java类型命名一个别名 (简称)
typeHandlers 类型处理器
ObjectFactory 对象工厂
plugins 插件
environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
mappers 映射器
指定外部配置文件,实现动态配置
好处 :
jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8
在 MyBatis 核心配置文件 也就是 mybatis-config.xml 中不能用 & 符号
xml 中使用 & 会报错 :转义错误 & 转义是 &
错误信息如下 :
1、在 resources 文件夹下面创建 db.properties 文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8&useSSL=true
user=root
password=admin
2、将 db.properties 配置文件引入MyBatis 核心配置(mybatis-config.xml)中,核心配置修改完如下 :
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/hkp/mapper/UserMapper.xml" />
mappers>
configuration>
用来修改 MyBatis 运行时的行为方式
主要是 MyBatis 的一些全局配置属性的设置
这里以配置日志文件为例 :
1、引入 log4j 的 jar 依赖
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
2、在 resources 文件夹中创建 log4j.properties 文件 (网上随便找一个即可),放在resource 文件夹下面也行
### 配置根 ###
log4j.rootLogger = debug,console ,fileAppender
### 设置输出sql的级别,其中logger后面的内容全部为jar包中所包含的包名 ###
log4j.logger.org.mybatis=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug
log4j.logger.java.sql.ResultSet=debug
### 配置输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n
### 配置输出到文件 ###
log4j.appender.fileAppender = org.apache.log4j.FileAppender
log4j.appender.fileAppender.File = ./logs/log.log
log4j.appender.fileAppender.Append = true
log4j.appender.fileAppender.Threshold = DEBUG
log4j.appender.fileAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
3、在 MyBatis 核心配置文件 中配置
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">properties>
<settings>
<setting name="logImpl" value="LOG4J" />
settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/hkp/mapper/UserMapper.xml" />
mappers>
configuration>
类型别名
只关联 xml 配置,简写冗长的 java 类名
两种方法 :单个类配置别名,批量配置别名(扫描包)
<typeAliases>
<typeAlias type="com.hkp.entity.User" alias="user" />
<package name="com.hkp.entity"/>
typeAliases>
配置完别名在写 SQL 的xml 文件里返回值就可以是别名了,而不再是实体的全路径名了
核心配置文件修改完如下:
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">properties>
<settings>
<setting name="logImpl" value="LOG4J" />
settings>
<typeAliases>
<typeAlias type="com.hkp.entity.User" alias="user" />
<package name="com.hkp.entity"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/hkp/mapper/UserMapper.xml" />
mappers>
configuration>
注册绑定我们的 Mapper 文件
方式一 :
<mappers>
<mapper resource="com/hkp/mapper/UserMapper.xml" />
mappers>
方式二 :
注意 :接口和mapper配置文件必须同名,也必须在同一包下
<mappers>
<package name="com.hkp.mapper"/>
mappers>
方式三 :
注意 :接口和mapper配置文件必须同名,也必须在同一包下
<mappers>
<mapper class="com.hkp.mapper.UserMapper"/>
mappers>
SQL映射文件就是写SQL的 xml 文件
SQL映射文件的元素(按照顺序)
mapper - namespace
cache 配置给定命名空间的缓存
cache-ref 从其他命名空间中引用缓存
resultMap 用来描述数据库结果集合对象的关系
sql 可以重用的SQL块,也可以被其他语句引用
insert/select/delete/update 增删改查 无顺序之分
namespace 命名空间
namespace 和增删改查的 id 要确保是唯一的,以区别不同的 mapper 接口和方法
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。比如:
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password sql>
这个 SQL 片段可以在其它语句中使用,例如:
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/>include>,
<include refid="userColumns"><property name="alias" value="t2"/>include>
from some_table t1
cross join some_table t2
select>
查询用户
xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<sql id="getUser">
select * from smbms_user where gender = ${gender}
sql>
<select id="getUser" resultType="com.hkp.entity.User">
<include refid="getUser">
<property name="gender" value="#{gender}"/>
include>
LIMIT #{start},#{pageNum}
select>
mapper>
接口
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
List<User> getUser(@Param("gender") Integer gender,@Param("start") Integer start, @Param("pageNum") Integer pageNum);
}
测试
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int gender = 2;
//条件
Integer pageNow=1; //第几页
Integer pageNum=3; //每页几行数据
//将第几页转换为limit 参数(起始下标)
//起始下标=(页码 - 1)*每页的条数
Integer start = (pageNow-1)*pageNum;
// 获取接口中的方法
List<User> user=userMapper.getUser(gender,start,pageNum);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
增删改查的 属性基本都差不多,只不过增删改没有resultType,这里以查询为例
id
命名空间中的唯一标识符
接口中的方法与映射文件中的SQL语句id 要 一 一对应
parameterType
传入SQL语句的参数类型
resultType
SQL语句返回值类型的完整类名或别名
以 根据用户名模糊查询用户 为例
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUserByName" parameterType="string" resultType="com.hkp.entity.User">
select * from smbms_user where userName like concat('%',#{userName},'%')
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* 参数类型必须和 SQL映射文件中的传入参数类型一致
* @return
*/
List<User> getUserByName(String userName);
}
3、运行测试
@Test
public void tset() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
String userName="张";
List<User> user = userMapper.getUserByName(userName);
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user2 : user) {
System.out.println(user2);
}
}
以 根据用户名和用户地址模糊查询用户 为例
多参数传递需要一个注解 @Param(“userName”) 这样SQL映射文件就可以直接使用该名称传参了,而不需要parameterType属性了
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUserByNameAndAdress" resultType="com.hkp.entity.User">
SELECT
*
FROM
smbms_user
WHERE
userName LIKE CONCAT( '%', #{userName}, '%' )
AND
address LIKE CONCAT('%',#{address},'%')
select>
mapper>
2、修改mapper接口的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* 多参数传递需要一个注解 @Param("userName") 这样SQL映射文件就可以直接使用该名称传参了,而不需要parameterType属性了
* @return
*/
List<User> getUserByNameAndAdress(@Param("userName") String userName, @Param("address") String address);
}
3、测试运行
@Test
public void tset() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
String userName="李";
String address="北京市";
List<User> user = userMapper.getUserByNameAndAdress(userName,address);
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user2 : user) {
System.out.println(user2);
}
}
这里还是以 根据用户名和用户地址模糊查询用户 为例
以实体类的形式传参,不需要注解,也不需要parameterType属性,只需要跟实体类中的属性名保持一致就行
1、修改SQL 映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUserByNameAndAdress" resultType="com.hkp.entity.User">
SELECT
*
FROM
smbms_user
WHERE
userName LIKE CONCAT( '%', #{userName}, '%' )
AND
address LIKE CONCAT('%',#{address},'%')
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* 以实体类的形式传参,不需要注解,也不需要parameterType属性,只需要SQL映射文件中的参数跟实体类中的属性名保持一致就行
* @return
*/
List<User> getUserByNameAndAdress(User user);
}
3、测试运行
@Test
public void tset() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
String userName="李";
String address="北京市";
List<User> user = userMapper.getUserByNameAndAdress(userName,address);
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user2 : user) {
System.out.println(user2);
}
}
以 查询前三条的用户信息 为例
以封装map集合的形式传参,不需要注解,也不需要parameterType属性,只需要跟map中的键名保持一致就行
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUserLimit" resultType="com.hkp.entity.User">
select * from smbms_user limit #{start},#{end}
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
import java.util.Map;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* 以封装map集合的形式传参,不需要注解,也不需要parameterType属性,只需要跟map中的键 名保持一致就行
* @return
*/
List<User> getUserLimit(Map<String, Object> map);
}
3、测试运行
@Test
public void tset() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
Map<String, Object> map=new HashMap<String, Object>();
map.put("start", 0);
map.put("end",3);
List<User> user = userMapper.getUserLimit(map);
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user2 : user) {
System.out.println(user2);
}
}
返回值类型是普通类型的 我们可以使用 ResultType 来写,但是对于复杂的返回值类型怎么返回?使用自定义的 ResultMap
例如 :想返回 用户id、用户名称、用户性别、用户手机、和角色名称
这里可以看出,我们需要使用两张表联查(用户表和角色表)
ResultType :直接返回数据类型 (基本数据类型、复杂数据类型)
ResultMap :对外部 自定义的映射方式引用
数据库字段与实体属性不一致
复杂联合查询,可以自由控制映射
在核心配置文件中添加:
<settings>
<setting name="autoMappingBehavior" value="PARTIAL"/>
settings>
如果在核心配置文件中配置了取消自动映射 ;则在SQL映射文件中就要使用使用自定义的映射ResultMap ;映射只针对查询返回的字段与实体中的属性映射
如果ResultMap 中出现了association 和collection 标签 ,默认的自动映射无效PARTIAL ,必须配置映射才能完成映射 ;想要自动映射可以使用 FULL 级别 来完成自动映射
以查询用户列表 包含(用户id、用户名称、用户性别、用户手机、和角色名称)为例
mybatis默认的映射机制,根据SQL查询到的字段自动去返回类型中寻找相对应的属性名,根据get 和set 方法进行赋值
用户表中没有角色名称的,为了可以映射的上,在User实体中添加一个roleName属性
如果字段名和属性名一致的话,就直接返回就行,如果不一致,则需要使用自定义返回类型ResultMap
1、在用户实体类中添加一个属性,并添加get和set方法和toString,用于放角色名称
private String roleName;
2、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultMap="getUserMap">
SELECT
us.id,
us.userName,
us.gender,
us.phone,
role.roleName
FROM
smbms_user us
LEFT JOIN smbms_role role ON us.userRole = role.id
select>
<resultMap type="com.hkp.entity.User" id="getUserMap">
<id column="id" property="id"/>
<result column="roleName" property="roleName"/>
resultMap>
mapper>
3、修改 mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* @return
*/
List<User> getUser();
}
4、测试运行
@Test
public void tset() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
List<User> user = userMapper.getUser();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user2 : user) {
System.out.println(user2);
}
}
增加、修改和删除 都很类似,他们中都没有resultType 返回值类型,因为他们三个都是影响数据库的行数的,所以返回值默认都是 int 类型
增删改都需要提交
sqlSession.commit();
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<insert id="addUser">
INSERT INTO `smbms`.`smbms_user` ( `userName`, `userPassword`, `address` )
VALUES(#{userName},#{userPassword},#{address});
insert>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 方法名要和id 名称一样
* @return
*/
int addUser(User user);
}
3、测试运行 (增删改都需要提交)
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
User u=new User();
u.setUserName("测试");
u.setUserPassword("test");
u.setAddress("测试");
int count = userMapper.addUser(u);
//增删改 影响数据库的操作需要做提交操作
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
System.out.println("影响数据库行数 :"+count);
}
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<update id="updateUser">
UPDATE `smbms`.`smbms_user`
SET `userName` = #{userName},
`userPassword` = #{userPassword},
`address` = #{address}
WHERE
`id` = #{id};
update>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 方法名要和id 名称一样
* @return
*/
int updateUser(User user);
}
3、测试运行 (增删改都需要提交)
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
User u=new User();
u.setId(16);
u.setUserName("测试udpate");
u.setUserPassword("test");
u.setAddress("测试");
int count = userMapper.updateUser(u);
//增删改 影响数据库的操作需要做提交操作
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
System.out.println("影响数据库行数 :"+count);
}
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<delete id="delUser" parameterType="int">
DELETE FROM smbms_user WHERE id=#{id}
delete>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 方法名要和id 名称一样
* @return
*/
int delUser(int id);
}
3、测试运行 (增删改都需要提交)
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
int count = userMapper.delUser(16);
//增删改 影响数据库的操作需要做提交操作
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
System.out.println("影响数据库行数 :"+count);
}
SQL映射文件中的一个重要的标签
id : resultMap 的唯一标识
type : java实体类
id :一般对应数据库中的主键,设置此项可以提高 MyBatis 的性能
result :映射到 javaBean 的某个“简单类型”属性
association :一对一映射 ,里面放一的一方
collection :一对多映射,里面放多的一方
association :一对一映射 ,里面放一的一方
property :实体对象属性
javaType :完整java 类名或别名
resultMap : 引用外部的resultMap 结果集,使用这个就不需要 javaType 了因为在 resultMap 里面有type属性了
查询用户列表为例 (包含用户ID、用户名称,用户手机号,角色ID、角色名称)
1、在User实体中声明Role实体类型,并生成get 和set 以及toString 方法
private Role role;
2、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultMap="getUserMap">
SELECT
us.id,
us.userName,
us.phone,
role.id roleId,
role.roleName
FROM
smbms_user us
LEFT JOIN smbms_role role ON us.userRole = role.id
select>
<resultMap type="com.hkp.entity.User" id="getUserMap">
<id column="id" property="id" />
<result column="userName" property="userName" />
<result column="phone" property="phone" />
<association property="role" javaType="com.hkp.entity.Role">
<id column="roleId" property="id" />
<result column="roleName" property="roleName" />
association>
resultMap>
mapper>
3、修改mapper 接口中的方法
package com.hkp.mapper;
import java.util.List;
import com.hkp.entity.User;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 方法名要和id 名称一样
* @return
*/
List<User> getUser();
}
4、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
List<User> list=userMapper.getUser();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user : list) {
System.out.println(user);
}
}
collection :一对多映射,里面放多的一方
property :实体对象属性
ofType :完整java 类名或别名
resultMap : 引用外部的resultMap 结果集,使用这个就不需要 javaType了因为在 resultMap 里面有type属性了
查询用户列表为例,一个用户有多个地址
1、在User实体中声明address实体类型,并生成get 和set 以及toString 方法
private List<Address> userAddress;
2、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultMap="UserAddressMap">
SELECT
us.id,
us.userName,
us.phone,
sa.id addressId,
sa.contact,
sa.addressDesc
FROM
smbms_user us
LEFT JOIN smbms_address sa ON us.id = sa.userId
select>
<resultMap type="com.hkp.entity.User" id="UserAddressMap">
<id column="id" property="id" />
<result column="userName" property="userName" />
<result column="phone" property="phone" />
<collection property="userAddress" resultMap="addressMap" />
resultMap>
<resultMap type="com.hkp.entity.Address" id="addressMap">
<id column="addressId" property="id" />
<result column="contact" property="contact" />
<result column="addressDesc" property="addressDesc" />
resultMap>
mapper>
3、修改mapper 接口中的方法
package com.hkp.mapper;
import java.util.List;
import com.hkp.entity.User;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 方法名要和id 名称一样
* @return
*/
List<User> getUser();
}
4、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
List<User> list=userMapper.getUser();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
for (User user : list) {
System.out.println(user);
}
}
每次发送一次SQL请求都需要去调用数据库,有点太耗资源,速度也慢了 ;
在第一次发送SQL请求时,从数据库拿到数据,往缓存里保存一份,这样,下次同样的SQL语句,就不去数据库里拿数据了,直接从缓存里拿数据即可,这样也提高了查询速度
MyBatis 缓存分为 :一级缓存和二级缓存
一级缓存默认是开启的
MyBatis 默认是开启一级缓存的
在同一个SQL会话(sqlsession)中,执行相同的SQL语句,第二次直接从缓存中获取数据
作用域 :同一个SQL会话中
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
/**
* 这里的方法名和返回值必须要和xml文件中的名称一样
* 返回值要和resultType中的值一样,这里resultType会自动将user加入list集合
* 方法名要和id 名称一样
* @return
*/
List<User> getUser();
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
List<User> list=userMapper.getUser();
System.out.println("第一次查询已结束");
List<User> list2=userMapper.getUser();
System.out.println("第二次查询已结束");
// 关闭会话,释放资源
sqlSession.close();
}
结果可以发现,两条SQL语句之间没有再去请求数据库,只请求了一次数据库
MyBatis 二级缓存默认是关闭的
之前说过 :一级缓存 的作用域只是一个 SQL 会话,那么SQL会话一旦关闭了,再去访问同一个SQL还是要去数据库拿数据的 ;这时候就用到了二级缓存
二级缓存作用域 :整个命名空间(namespace)中,也就是整个SQL映射文件中
执行相同的SQL语句,第二次直接从缓存中获取数据
<cache eviction="FIFO" flushInterval="60000" size="512"
readOnly="true" />
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
可用的清除策略有:
LRU
– 最近最少使用:移除最长时间不被使用的对象。FIFO
– 先进先出:按对象进入缓存的顺序来移除它们。SOFT
– 软引用:基于垃圾回收器状态和软引用规则移除对象。WEAK
– 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。默认的清除策略是 LRU。
flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
案例
1、在SQL映射文件中添加配置,开启二级缓存
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<cache eviction="FIFO" flushInterval="60000" size="512"
readOnly="true" />
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user
select>
mapper>
2、mapper 接口方法和一级缓存的方法一样,没有发生改变
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
List<User> list=userMapper.getUser();
System.out.println("第一次查询已结束");
List<User> list2=userMapper.getUser();
System.out.println("第二次查询已结束");
// 关闭会话,释放资源
sqlSession.close();
//重新获取sqlsession会话,以及缓存已经失效
SqlSession sqlSession2 = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
//第三次查询用户列表,sqlsession会话已经关闭,一级缓存已经失效
List<User> list3=userMapper2.getUser();
System.out.println("第三次查询已结束");
}
可以看到前两次查询用户列表是在同一个SQL会话里进行的,此时一级缓存是生效的;而第三次查询用户列表的时候,SQL会话已经关闭了,我们需要重新打开一个SQL会话,因为二级缓存已经被我们开启了,所以第三次查询虽然重新打开了SQL会话,但SQL语句没有发生变化,所以还是走的缓存
二级缓存的作用域是整个SQL映射文件,所以在那个SQL映射文件下面的所有方法都会走缓存,那么有的方法不想走缓存怎么办 ?
在方法上添加属性 useCache=“false”
<select id="getUser" resultType="com.hkp.entity.User" useCache="false">
SELECT * FROM smbms_user
select>
这样 二级缓存 对这个方法就不生效了,但一级缓存生效,也就是在同一个SQL会话中执行两次这个SQL,还是会有缓存的(一级缓存)
基于 OGNL 表达式
完成多条件查询等逻辑实现
主要元素有 :
if、trim、where、set、choose ( when 、 otherwise )、foreach
if 通常与where 一起使用
根据条件判断 来增加查询条件
根据 用户名和角色ID 来查询用户列表
1、添加SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user
WHERE 1=1
<if test="userName!=null and userName!=''">
AND userName LIKE CONCAT('%',#{userName},'%')
if>
<if test="userRole!=null">
AND userRole = #{userRole}
if>
select>
mapper>
2、添加mapper 接口中的方法
package com.hkp.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.hkp.entity.User;
public interface UserMapper {
List<User> getUser(@Param("userName") String userName,@Param("userRole") Integer userRole);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
Integer userRole=3;
String userName="张";
List<User> list=userMapper.getUser(userName,userRole);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user : list) {
System.out.println(user);
}
}
动态拼接多个条件,如果没有条件,where 会自动去掉;如果多个条件,where 会自动去掉第一个条件前面的 AND 或 OR
动态处理 AND 和 OR
根据 用户名和角色ID 来查询用户列表
1、添加SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user
<where>
<if test="userName!=null and userName!=''">
AND userName LIKE CONCAT('%',#{userName},'%')
if>
<if test="userRole!=null">
AND userRole = #{userRole}
if>
where>
select>
mapper>
2、添加mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
List<User> getUser(@Param("userName") String userName,@Param("userRole") Integer userRole);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
Integer userRole=null;
String userName=null;
List<User> list=userMapper.getUser(userName,userRole);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user : list) {
System.out.println(user);
}
}
在修改数据的时候,如果值为null ,数据库的信息将会被修改为null;set 可以去处理,如果为null 则不修改,保持数据库中的数据不动
主要用于修改数据的SQL语句中
可以动态处理多余的逗号
set 的使用方法和 where 类似
1、添加SQL 映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<update id="updateUser">
UPDATE `smbms`.`smbms_user`
<set>
<if test="userName!=null and userName!=''">
`userName` = #{userName},
if>
<if test="gender!=null">
`gender` = #{gender},
if>
<if test="address!=null and address!=''">
`address` = #{address},
if>
set>
WHERE
`id` = #{id};
update>
mapper>
2、添加mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
public interface UserMapper {
int updateUser(User user);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
User u=new User();
u.setId(15);
u.setUserName("测试");
u.setGender(1);
int count=userMapper.updateUser(u);
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
//打印结果
System.out.println("影响的行数 :"+count);
}
主要用于更加复杂的SQL语句
可以替代 where 和 set
更灵活的去掉多余的关键字
属性 :
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<update id="updateUser">
UPDATE `smbms`.`smbms_user`
<trim prefix="set" suffix="WHERE `id` = #{id}" suffixOverrides=",">
<if test="userName!=null and userName!=''">
`userName` = #{userName},
if>
<if test="gender!=null">
`gender` = #{gender},
if>
<if test="address!=null and address!=''">
`address` = #{address},
if>
trim>
update>
mapper>
2、mapper 接口方法与set中的一样,不需要改动
3、测试运行,代码和 set 中的一样,不需要改动
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user
<trim prefix="where" prefixOverrides="and">
<if test="userName!=null and userName!=''">
AND userName LIKE CONCAT('%',#{userName},'%')
if>
<if test="userRole!=null">
AND userRole = #{userRole}
if>
trim>
select>
mapper>
2、mapper 接口方法与 where 中的一样,不需要改动
3、测试运行,代码和 where 中的一样,不需要改动
迭代一个集合,通常用于 in 条件
属性 :
item 声明变量去接收元素
collection : 必须指定 用来接参数
open 以什么开头
separator 元素的分隔符
close 以什么结尾
为了方便理解,采用java中的foreach来对比 :
for (User user : list) {
System.out.println(user);
}
其中 :
User 相当于 collection
user 相当于 item
list 相当于 collection 中的值 ( list、array、map-key )
foreach 遍历普通数组和动态数组都不常用,将数组封装到map 集合中比较常用
因为 :我们以后传参不可能只穿一个类型的参数(数组中的值是单一类型的),而map集合可以封装很多参数类型来进行传参
将数组封装到 map 集合中,我们在SQL映射文件 通过集合对应的键名称 来取
foreach 迭代 一共有三个案例
普通数组和动态数组 :主要是迭代 in 中的单一类型的参数
map 集合 :在迭代 in 中的单一类型的参数基础上,加上其他的参数
1、添加SQL映射文件内容
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user WHERE id IN
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
foreach>
select>
mapper>
2、添加mapper 接口方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
List<User> getUser(int[] idArr);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建一个普通的数组
int[] idArr = {1,2,5};
// 获取接口中的方法
List<User> user=userMapper.getUser(idArr);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
foreach>
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
List<User> getUser(List<Integer> arrayList);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建一个动态的list的数组
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
// 获取接口中的方法
List<User> user=userMapper.getUser(arrayList);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
1、修改SQL映射文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT * FROM smbms_user WHERE id IN
<foreach collection="idList" item="id" open="(" separator="," close=")">
#{id}
foreach>
AND gender = #{gender}
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
import java.util.Map;
public interface UserMapper {
List<User> getUser(Map<String, Object> map);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建一个动态的list的数组
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
//将数组封装到集合中
Map<String, Object> map=new HashMap<String, Object>();
map.put("idList", arrayList);
//将其他参数封装到map集合里面
map.put("gender", 2);
// 获取接口中的方法
List<User> user=userMapper.getUser(map);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
相当于 java 中的switch 语句,当when 有条件满足时,就跳出choose ;如果when 条件都不满足,就执行 otherwise
通过 用户名称、用户性别、用户角色id 查询用户列表 ;
choose 的作用就是选择一个条件去查询
1、修改SQL映射文件内容
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT
*
FROM
smbms_user
<where>
<choose>
<when test="userName!=null and userName!=''">
AND userName LIKE CONCAT( '%',#{userName}, '%' )
when>
<when test="gender!=null">
AND gender = #{gender}
when>
<otherwise>
AND userRole = #{userRole}
otherwise>
choose>
where>
select>
mapper>
2、修改mapper 接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
List<User> getUser(User user);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
User u=new User();
u.setUserName("赵");
u.setGender(1);
u.setUserRole(3);
List<User> user=userMapper.getUser(u);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
1、修改SQL映射文件内容
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="com.hkp.entity.User">
SELECT
*
FROM
smbms_user
LIMIT #{start},#{pageNum}
select>
mapper>
2、修改mapper 接口的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
List<User> getUser(@Param("start") Integer start, @Param("pageNum") Integer pageNum);
}
3、测试运行
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//条件
Integer pageNow=1; //第几页
Integer pageNum=3; //每页几行数据
//将第几页转换为limit 参数(起始下标)
//起始下标=(页码 - 1)*每页的条数
Integer start = (pageNow-1)*pageNum;
// 获取接口中的方法
List<User> user=userMapper.getUser(start,pageNum);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
SQL映射文件的内容
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="getUser" resultType="user">
select * from smbms_user
select>
mapper>
接口中的方法
package com.hkp.mapper;
import com.hkp.entity.User;
import java.util.List;
public interface UserMapper {
List<User> getUser();
}
测试
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//第一个参数为 第几页,第二个参数为页面有几条数据
RowBounds rowBounds = new RowBounds(1, 3);
// 获取 mapper 接口
List<User> userList = sqlSession.selectList("com.hkp.mapper.UserMapper.getUser",null, rowBounds);
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : userList) {
System.out.println(user2);
}
}
映射的语句可以不用 XML 来配置,而可以使用 Java 注解来配置。比如,上面的 XML 示例可以被替换成如下的配置:
package org.mybatis.example;
public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
}
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
核心配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">properties>
<settings>
<setting name="logImpl" value="LOG4J" />
settings>
<typeAliases>
<package name="com.hkp.entity"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
dataSource>
environment>
environments>
<mappers>
<mapper class="com.hkp.mapper.UserMapper"/>
mappers>
configuration>
接口
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from smbms_user")
List<User> getUser();
}
测试
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> user = mapper.getUser();
// 关闭会话,释放资源
sqlSession.close();
//打印结果
for (User user2 : user) {
System.out.println(user2);
}
}
接口
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Insert;
import java.util.List;
public interface UserMapper {
@Insert("INSERT INTO `smbms`.`smbms_user` ( `userName`, `userPassword`, `address` ) VALUES(#{userName},#{userPassword},#{address});")
int addUser(User user);
}
测试
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
User u=new User();
u.setUserName("测试");
u.setUserPassword("test");
u.setAddress("测试");
int count = userMapper.addUser(u);
//增删改 影响数据库的操作需要做提交操作
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
System.out.println("影响数据库行数 :"+count);
}
接口
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Delete;
import java.util.List;
public interface UserMapper {
@Delete("DELETE FROM smbms_user WHERE id=#{id}")
int deleteUser(@Param("id") int id);
}
测试
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
int count = userMapper.deleteUser(24);
//增删改 影响数据库的操作需要做提交操作
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
System.out.println("影响数据库行数 :"+count);
}
接口
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface UserMapper {
@Update("UPDATE `smbms`.`smbms_user` \n" +
"\t\tSET `userName` = #{userName},\n" +
"\t\t`userPassword` = #{userPassword},\n" +
"\t\t`address` = #{address}\n" +
"\t\tWHERE\n" +
"\t\t\t`id` = #{id};")
int updateUser(User user);
}
测试
@Test
public void test() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取 mapper 接口
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 获取接口中的方法
User u=new User();
u.setId(16);
u.setUserName("测试udpate");
u.setUserPassword("test");
u.setAddress("测试");
int count = userMapper.updateUser(u);
//增删改 影响数据库的操作需要做提交操作
sqlSession.commit();
// 关闭会话,释放资源
sqlSession.close();
// 查询到的数据
System.out.println("影响数据库行数 :"+count);
}
#{} 安全,可以防止 SQL 注入
${} 不安全