maven 仓库获取
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.13version>
dependency>
Github 获取源码
中文文档
编写第一个 Mybatis 程序首先需要有一个具体步骤:
搭建环境–> 导入 Mybatis–>编写代码–>测试
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userId` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`userName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名称',
`userAge` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户年龄',
PRIMARY KEY (`userId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '张三', '12');
INSERT INTO `user` VALUES (2, '李四', '15');
INSERT INTO `user` VALUES (3, '王五', '18');
SET FOREIGN_KEY_CHECKS = 1;
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.13version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.33version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>testscope>
dependency>
dependencies>
mybatis-config.xml
的 xml 文件
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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
mappers>
configuration>
property
标签中的 value 值,就是我们在 JDBC 中编写配置文件对应的
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/mybatis?TRUE&useUnicode=TRUE&characterEncoding=UTF-8&serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
mappers>
configuration>
每个 Mybatis 的应用都是一个以 SqlSessionFactory 的实例为核心的
SqlSessionFactory 可以通过 SqlSessionFactoryBuilder 来获取
**而 SqlSessionFactoryBuilder 可以从 XML 配置文件来构建出 SqlSessionFactory **
从 SqlSessionFactory 可以获取 SqlSession 实例
通过 SqlSession 可以直接执行已经映射的 SQL 语句
在 utils 包下创建一个工具类 MybatisUtils
编写 MybatisUtils 类,获取 SqlSessionFactory 实例
package com.qiaoer.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
//获取资源
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
String resource
的值是刚刚编写的 resource 文件夹下的 xml 文件路径
通过已经获取的 SqlSessionFactory 实例,来获取 SqlSession 实例
编写 getSqlSession() 方法,来获取 SqlSession 实例
package com.qiaoer.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 MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
//获取资源
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//获取 SqlSession 实例
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
package com.qiaoer.entity;
public class User {
private int userId;
private String userName;
private String userAge;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAge() {
return userAge;
}
public void setUserAge(String userAge) {
this.userAge = userAge;
}
public User() {
}
public User(int userId, String userName, String userAge) {
this.userId = userId;
this.userName = userName;
this.userAge = userAge;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userAge='" + userAge + '\'' +
'}';
}
}
package com.qiaoer.dao;
import com.qiaoer.entity.User;
import java.util.List;
public interface UserDao {
//获取所有用户
List<User> getUsers();
}
<?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="com.qiaoer.dao.UserDao">
<!-- SQL 语句查询-->
<select id="selectBlog" resultType="com.qiaoer.entity.User">
select * from user
</select>
</mapper>
其中
中的 namespace
的值对应的是要实现的接口类
中 id
的值为对应的方法名
resultType
属性表示返回一个结果
resultType
的值为返回值类型的返回类型对应的实体类
编写完 UserMapper.xml 后,需要在 Mybatis 的核心配置文件 mybatis-config.xml
进行 Mapper 注册
<?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/mybatis?TRUE&useUnicode=TRUE&characterEncoding=UTF-8&serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/qiaoer/dao/UserMapper.xml"/>
</mappers>
</configuration>
则表现 Mapper 注册resource
属性的值就是对应的 Mapper.xml 文件路径
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test01 {
public static void main(String[] args) {
//第一步,获取 SqlSession 对象
SqlSession sqlSession= MybatisUtils.getSqlSession();
//方法一:通过 SqlSession 对象获取实现类
System.out.println("=====方法1=====");
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.getUsers();
for (User user:users) {
System.out.println(user);
}
//直接获取结果
List<User> UserLists = sqlSession.selectList("com.qiaoer.dao.UserDao.getUsers");
System.out.println("=====方法2=====");
for (User user:UserLists) {
System.out.println(user);
}
//关闭 SqlSession
sqlSession.close();
}
}
在 Mybatis 中编写dao层的实现类的 Mapper.xml 文件中,对增删改查的标签进行介绍
<select id="对应方法" resultType="方法的返回值类型" parameterType="方法的参数类型">
查询的 SQL 语句
select>
<mapper namespace="com.qiaoer.dao.UserDao">
<!-- SQL 语句查询-->
<select id="selectBlog" resultType="com.qiaoer.entity.User" parameterType="int">
select * from user where userId=#{id}
</select>
</mapper>
<insert id="对应方法" parameterType="方法的参数类型">
增加的 SQL 语句
insert>
<insert id="addUser" parameterType="com.qiaoer.entity.User">
insert into user (userName, userAge) values (#{userName},#{userAge});
</insert>
其中 #{userName},#{userAge}
两个均是 User 对象的属性名
==注意:==当我们执行 SQL 语句的增删改时,都需要开启 SQL 的提交事务,否则并不会实际添加
开启提交事务使用 SqlSession 中的 commit() 方法
代码示例
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test01 {
public static void main(String[] args) {
//第一步,获取 SqlSession 对象
SqlSession sqlSession= MybatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
//执行增加用户
mapper.addUser(new User(-1,"你好","15"));
//查询所有用户
List<User> users = mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
//提交事务
sqlSession.commit();
//关闭 SqlSession
sqlSession.close();
}
}
也可以使用自动提交事务
将我们工具类当中,获取 SqlSession 实例的 openSession() 方法,给个 true 参数即可开启自动提交事务
<insert id="对应方法" parameterType="方法的参数类型">
修改的 SQL 语句
insert>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.UserDao">
<update id="updateUser" parameterType="com.qiaoer.entity.User">
update user set userName=#{userName} where userId=#{userId};
update>
mapper>
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test01 {
public static void main(String[] args) {
//第一步,获取 SqlSession 对象
SqlSession sqlSession= MybatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
//执行修改 id为1的用户
mapper.updateUser(new User(1,"Qiaoer","15"));
//查询所有用户
List<User> users = mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
//提交事务
sqlSession.commit();
//关闭 SqlSession
sqlSession.close();
}
}
<delete id="对应方法" parameterType="方法的参数类型">
删除的 SQL 语句
delete>
package com.qiaoer.dao;
import com.qiaoer.entity.User;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public interface UserDao {
//通过用户年龄,用户姓名,查询用户
List<User> getUserByUserAgeAndUserName(Map<String, Object> map);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.UserDao">
<select id="getUserByUserAgeAndUserName" resultType="com.qiaoer.entity.User" parameterType="map">
select * from user where userAge=#{userAge} and userName=#{userName}
select>
mapper>
#{userAge}
和 #{userName}
都属于 map 的 key 值import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Test01 {
public static void main(String[] args) {
//获取 SqlSession 对象
SqlSession sqlSession=MybatisUtils.getSqlSession();
//获取实现类
UserDao userDao=sqlSession.getMapper(UserDao.class);
//创建参数 map
Map<String, Object> map=new HashMap<String, Object>();
map.put("userAge",15);
map.put("userName","Qiaoer");
//调用查询方法
List<User> userByUserAgeAndUserName = userDao.getUserByUserAgeAndUserName(map);
//输出结果
for (User user : userByUserAgeAndUserName) {
System.out.println(user);
}
//提交事务
sqlSession.commit();
//关闭 SqlSession
sqlSession.close();
}
}
mybatis-config.xml
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="test">
<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/mybatis?TRUE&useUnicode=TRUE&characterEncoding=UTF-8&serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
dataSource>
environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?TRUE&useUnicode=TRUE&characterEncoding=UTF-8&serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/qiaoer/dao/UserMapper.xml"/>
mappers>
configuration>
在上方的
标签内,
标签代表不同的环境
environment
标签的属性 id,则对应的是自己的环境名称
environments
标签的 属性 default,则表示用户要选择哪个环境,与environment
标签的属性 id 的值对应
例如,上方示例中,我的 environments
标签的属性 default 的值为 test ,则代表我选择了 环境
标签为事务管理器
标签为数据源
标签引入
必须放在
标签内部的最顶部
标签的 resource 属性则代表配置文件的路径
标签中,可以使用配置文件中的键来调用
标签内也可以写入配置信息
标签内的子元素和外部配置文件 之间的顺序存在一个优先级顺序
标签中的
标签设置
标签位于
标签的第三位
标签中的
标签设置com.qiaoer.entity
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名com.qiaoer.entity.User
的别名为 user
主要用来解决字段与属性名不相同的问题
resultMap
元素是 MyBatis 中最重要最强大的元素ResultMap
,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,则会导致赋值为空
标签来解决 <resultMap id="" type="">
<result property="" column=""/>
<result property="" column=""/>
resultMap>
<select id="getUsers" resultMap="" >
select * from user
select>
标签中的属性
标签中的属性
标签中的属性
的属性 id 的值
标签
位于
标签的第二位
标签语法 <settings>
<setting name="设置名" value="有效值"/>
settings>
logImpl 是指定 MyBatis 所用日志的具体实现,未指定时将自动查找,即设置名
logImpl 的有效值为
在核心配置文件中设置一个标准日志
标准日志的值为 STDOUT_LOGGING
什么是 Log4j
1、导入 Log4j 的包
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
2、创建配置文件 log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
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=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/qiaoer.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3、配置 Log4j 为日志的实现
4、Log4j 的简单使用
//获取当前类的日志信息
Logger logger = Logger.getLogger(Test01.class);
Test01.class
为当前类的反射对象//获取当前类的日志信息
Logger logger = Logger.getLogger(Test01.class);
logger.info("info:进入了 Test01");
logger.debug("debug:进入了 Test01");
logger.error("error:进入了 Test01");
实现分页的好处:减少数据的处理量
SELECT * from user limit startIndex,pagesize;
使用 MyBatis 实现分页
package com.qiaoer.dao;
import com.qiaoer.entity.User;
import java.util.List;
import java.util.Map;
public interface UserDao {
//获取所有用户
List<User> getUsers();
//分页查询用户
List<User> getUserLimits(Map<String,Object> map);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.UserDao">
<resultMap id="UserMap" type="user">
<result property="userId" column="userId"/>
<result property="userName" column="userName"/>
<result property="Age" column="userAge"/>
resultMap>
<select id="getUsers" resultMap="UserMap" >
select * from user
select>
<select id="getUserLimits" resultMap="UserMap">
SELECT * from user limit #{startIndex},#{pagesize};
select>
mapper>
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Test01 {
public static void main(String[] args) {
//获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//获取实现类
UserDao mapper = sqlSession.getMapper(UserDao.class);
//获设置参数
Map<String,Object> map=new HashMap<String,Object>();
map.put("startIndex",2);
map.put("pagesize",2);
List<User> userLimits = mapper.getUserLimits(map);
//输出结果
for (User user : userLimits) {
System.out.println(user);
}
//提交事务
sqlSession.commit();
//关闭 SqlSession
sqlSession.close();
}
}
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Test01 {
public static void main(String[] args) {
//获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//分层
RowBounds rowBounds=new RowBounds(2,2);
//获取查询所有用户方法
List<User> userRowBounds = sqlSession.selectList("com.qiaoer.dao.UserDao.getUsers", null, rowBounds);
//输出结果
for (User user : userRowBounds) {
System.out.println(user);
}
//提交事务
sqlSession.commit();
//关闭 SqlSession
sqlSession.close();
}
}
使用注解则不需要在写实现类
直接在接口上使用注解开发
//获取所有用户
@Select("select * from user")
List<User> getUsers();
<mappers>
<mapper class="com.qiaoer.dao.UserDao"/>
mappers>
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Test01 {
public static void main(String[] args) {
//获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.getUsers();
//输出结果
for (User user : users) {
System.out.println(user);
}
//提交事务
sqlSession.commit();
//关闭 SqlSession
sqlSession.close();
}
}
**在使用注解进行开发时,如果需要参数,需要在接口的参数前面加上 **
如果有多个参数,则每个参数前都需要添加注解
在 SQL 语句当中,获取参数时,则填写的时以注解命名的参数
//根据 年龄和名字查询用户
@Select("select * from user where userName=#{ParamUserName} and userAge=#{ParamUserAge}")
List<User> getUsersByuserAgeAnduserName(@Param("ParamUserAge") int UserAge, @Param("ParamUserName") String UserName);
package com.qiaoer.dao;
import com.qiaoer.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface UserDao {
//获取所有用户
@Select("select * from user")
List<User> getUsers();
//根据用户 姓名和 年龄查询
//根据 年龄和名字查询用户
@Select("select * from user where userName=#{ParamUserName} and userAge=#{ParamUserAge}")
List<User> getUsersByuserAgeAnduserName(@Param("ParamUserAge") int UserAge, @Param("ParamUserName") String UserName);
//增加用户
@Insert("insert into user (userName, userAge) values (#{userName},#{Age})")
int addUser(User user);
//修改用户
@Update("update user set userName=#{userName} where userId=#{userId}")
int updateUser(User user);
//删除用户
@Delete("delete from user where userId=#{UserId}")
int delUser(@Param("UserId") int userId);
}
import com.qiaoer.dao.UserDao;
import com.qiaoer.entity.User;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Test01 {
public static void main(String[] args) {
//获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users=null;
System.out.println("=================添加用户=================");
//添加用户
mapper.addUser(new User(-1,"abcd","13"));
//输出所有用户
users = mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
System.out.println("=================修改用户=================");
//修改 id 为 3 的用户
mapper.updateUser(new User(3,"修改了","15"));
//输出所有用户
users= mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
System.out.println("=================删除用户=================");
//删除 id 为 3 的用户
mapper.delUser(3);
//输出所有用户
users= mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
//关闭 SqlSession
sqlSession.close();
}
}
@Param("uid“)
中设定的属性名!优点
缺点
使用 右下角这些注解就可以自动生成一些对应的方法
导入 Lombok 的 jar 包,将以下代码导入 maven 仓库即可
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.28version>
dependency>
注解 | 说明 |
---|---|
@Data | 自动生成 getter、setter、toString 等方法 |
@NoArgsConstructor | 自动生成无参构造函数 |
@AllArgsConstructor | 自动生成全参构造函数 |
@Builder | 自动生成 Builder 模式相关代码 |
@EqualsAndHashCode | 自动生成 equals 和 hashCode 方法 |
@Setter | 自动生成 setter 方法 |
@Getter | 自动生成 getter 方法 |
@ToString | 自动生成 toString 方法 |
@Slf4j | 自动生成日志变量 |
@NonNull | 标记字段为非空,生成空值检查 |
@RequiredArgsConstructor | 自动生成带有 final 字段的构造函数 |
@Value | 类似 @Data,不可变对象,自动生成方法 |
@Cleanup | 自动生成资源关闭代码 |
@SneakyThrows | 在方法中抛出异常,无需显示声明 |
package com.qiaoer.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int userId;
private String userName;
private String Age;
}
在进行测试之前,需要先搭建一个测试的环境
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`studentId` int(11) NOT NULL AUTO_INCREMENT COMMENT '学生id',
`studentName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学生姓名',
`tId` int(11) NOT NULL COMMENT '学生关联的老师id',
PRIMARY KEY (`studentId`) USING BTREE,
INDEX `tId`(`tId`) USING BTREE,
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`tId`) REFERENCES `teacher` (`teacherId`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '1号学生', 1);
INSERT INTO `student` VALUES (2, '2号学生', 1);
INSERT INTO `student` VALUES (3, '3号学生', 1);
INSERT INTO `student` VALUES (4, '4号学生', 1);
INSERT INTO `student` VALUES (5, '5号学生', 1);
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`teacherId` int(11) NOT NULL AUTO_INCREMENT COMMENT '教师id',
`teacherName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '教师姓名',
PRIMARY KEY (`teacherId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '刘老师');
与 SQL 的子查询道理类似
主要实现,根据查询出来的学生 tid,寻找对应的教师信息
首先编写接口内的查询方法
package com.qiaoer.dao;
import com.qiaoer.entity.Student;
import java.util.List;
public interface StudentMapper {
//查询所有学生信息
List<Student> getSudent();
}
编写 StudentMapper.xml
先查询所有的学生信息
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.StudentMapper">
<select id="getSudent" resultType="student">
select * from student
select>
mapper>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.StudentMapper">
<select id="getSudent" resultType="student">
select * from student
select>
<select id="getTeacher" resultType="teacher">
Select * from teacher where teacher.teacherId=#{id}
select>
mapper>
resultMap
属性,将结果关联起来
标签内使用
进行处理
标签内使用
进行处理
标签
property
: 指定将关联结果映射到的属性名,这里是学生实体中与老师关联的属性名。column
: 指定用于关联的字段名,这里是学生表中用来和老师表关联的字段名。javaType
: 指定关联的实体类型,这里是老师实体的类型。select
: 指定一个查询,用于根据关联条件获取关联的实体。这个查询会根据指定的关联条件(通常是字段值)去获取关联实体的信息
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.StudentMapper">
<select id="getSudent" resultMap="StuTeacher">
select * from student
select>
<resultMap id="StuTeacher" type="student">
<result property="studentId" column="studentId"/>
<result property="studentName" column="studentName"/>
<association property="teacher" column="tId" javaType="teacher" select="getTeacher"/>
resultMap>
<select id="getTeacher" resultType="teacher">
Select * from teacher where teacher.teacherId=#{id}
select>
mapper>
id="getTeacher"
名字随意命名即可,不要关联某些方法getTeacher
的查询结果赋予了 Student 类的属性 teacher **#{id}
本质就是将
中 column 的 tid
也就是数据库查询出来的结果,当做参数来查询的package com.qiaoer.dao;
import com.qiaoer.entity.Student;
import java.util.List;
public interface StudentMapper {
//查询所有学生信息
List<Student> getSudent();
//查询所有学生信息
List<Student> getSudent2();
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.StudentMapper">
<select id="getSudent2" resultMap="">
select student.studentId as stuId,student.studentName as stuName,teacher.teacherId as teaId,teacher.teacherName as teaName from student INNER JOIN teacher ON student.tId=teacher.teacherId
select>
mapper>
resultMap
属性,将结果关联起来
处理,只不过这次与上次略微不同
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.StudentMapper">
<select id="getSudent2" resultMap="StuTeacher2">
select student.studentId as stuId,student.studentName as stuName,teacher.teacherId as teaId,teacher.teacherName as teaName from student INNER JOIN teacher ON student.tId=teacher.teacherId
select>
<resultMap id="StuTeacher2" type="student">
<result property="studentId" column="studentId"/>
<result property="studentName" column="studentName"/>
<association property="teacher" javaType="teacher">
<result property="teacherId" column="teaId"/>
<result property="teacherName" column="teaName"/>
association>
resultMap>
mapper>
标签只有两个属性
标签内的
标签则是将 teacher 属性对象内的属性关联起来
package com.qiaoer.dao;
import com.qiaoer.entity.Teacher;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface TeacherMapper {
//查询所有教师
List<Teacher> getTeachers();
}
**编写 TeacherMapper.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="com.qiaoer.dao.TeacherMapper">
<select id="getTeachers" resultMap="TeaStudent">
select student.studentId as stuId,student.studentName as stuName,teacher.teacherId as teaId,teacher.teacherName as teaName from student INNER JOIN teacher ON student.tId=teacher.teacherId
</select>
<resultMap id="TeaStudent" type="teacher">
<result property="teacherId" column="teaId"/>
<result property="teacherName" column="teaName"/>
<collection property="studentList" ofType="student">
<result property="studentId" column="stuId"/>
<result property="studentName" column="stuName"/>
</collection>
</resultMap>
</mapper>
标签的属性
标签内
标签的属性
他的本质与多对一大差不差
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.TeacherMapper">
<select id="getTeachers" resultMap="TeaStudent">
select * from teacher
select>
<resultMap id="TeaStudent" type="teacher">
<result property="teacherId" column="teacherId"/>
<result property="teacherName" column="teacherName"/>
<collection property="studentList" javaType="ArrayList" ofType="student" select="getStudent" column="teacherId"/>
resultMap>
<select id="getStudent" resultType="student">
select * from student where tId=#{id}
select>
mapper>
标签内的属性
标签内的的 #{id}
的参数是一致的根据不同的条件生成不同的 SQL 语句
/*
Navicat Premium Data Transfer
Source Server : LanQiaoer
Source Server Type : MySQL
Source Server Version : 50740 (5.7.40)
Source Host : localhost:3306
Source Schema : mybatis
Target Server Type : MySQL
Target Server Version : 50740 (5.7.40)
File Encoding : 65001
Date: 05/08/2023 20:19:07
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for blog
-- ----------------------------
DROP TABLE IF EXISTS `blog`;
CREATE TABLE `blog` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '博客id',
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客标题',
`author` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(11) NOT NULL COMMENT '浏览量',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of blog
-- ----------------------------
INSERT INTO `blog` VALUES (1, 'mybatis如此简单', '兰巧儿', '2023-08-05 20:14:13', 9999);
INSERT INTO `blog` VALUES (2, 'Java如此简单', '兰巧儿', '2023-08-05 20:14:38', 1000);
INSERT INTO `blog` VALUES (3, 'html是一门编程语言', '云朵', '2023-08-05 20:14:50', 9999);
INSERT INTO `blog` VALUES (4, 'spring如此简单', '云朵', '2023-08-05 20:15:03', 9999);
SET FOREIGN_KEY_CHECKS = 1;
创建一个基础工程
package com.qiaoer.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
private int id;
private String title;
private String author;
private String createTime;
private int views;
}
标签位于 Mapper.xml 的 SQL 语句标签内
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.BlogMapper">
<select id="getBlogListIF" resultType="blog">
<if test="">
if>
select>
mapper>
package com.qiaoer.dao;
import com.qiaoer.entity.Blog;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
public interface BlogMapper {
//查询所有
List<Blog> getBlogListIF(Map<String,Object> map);
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiaoer.dao.BlogMapper">
<select id="getBlogListIF" parameterType="map" resultType="blog">
select * from blog where 1=1
<if test="title != null">
and title=#{title}
if>
<if test="author !=null">
and author=#{author}
if>
select>
mapper>
如果传递过来的参数 title 或 author 不为空,那么则会拼接if 标签内的 SQL 语句
if 标签中的 test 属性用于比较的 title 或 author 必须与你传过来的参数名相同
并且传递的参数数量,必须与你写的 if 内做判断的参数数量相同
如果使用 @Param
注解设置了参数,那必须与注解的相同
所以推荐将 Map 当作参数传递
测试
import com.qiaoer.dao.BlogMapper;
import com.qiaoer.entity.Blog;
import com.qiaoer.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test05 {
public static void main(String[] args) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
List<Blog> blogListNoParam = mapper.getBlogListIF(null);
System.out.println("=====没有参数=====");
for (Blog blog : blogListNoParam) {
System.out.println(blog);
}
System.out.println("=====有一个参数 title=====");
Map<String,Object> mapOneTitleParam =new HashMap<String,Object>();
mapOneTitleParam.put("title","html是一门编程语言");
List<Blog> blogListOneTitleParam = mapper.getBlogListIF(mapOneTitleParam);
for (Blog blog : blogListOneTitleParam) {
System.out.println(blog);
}
System.out.println("=====有一个参数 author=====");
Map<String,Object> mapOneAuthorParam =new HashMap<String,Object>();
mapOneAuthorParam.put("author","云朵");
List<Blog> blogListOneAuthorParam = mapper.getBlogListIF(mapOneAuthorParam);
for (Blog blog : blogListOneAuthorParam) {
System.out.println(blog);
}
System.out.println("=====有两个参数 Title author=====");
Map<String,Object> mapTwoParam =new HashMap<String,Object>();
mapTwoParam.put("author","云朵");
mapTwoParam.put("title","html是一门编程语言");
List<Blog> blogListTwoParam = mapper.getBlogListIF(mapTwoParam);
for (Blog blog : blogListTwoParam) {
System.out.println(blog);
}
}
}
基本语法与 JSTL 相似
直接去官网参考学习
https://mybatis.org/mybatis-3/zh/getting-started.html
<select id="selecPatientInfo" resultType="Patient" parameterType="map">
select * from patient
<where>
<choose>
<when test="password != null">
and password=
#{password}
when>
<when test="gender != null">
and gender=
#{gender}
when>
<otherwise>
identityNum=#{identityNum}
otherwise>
choose>
where>
select>
<select id="selecPatientInfo" resultType="Patient" parameterType="map">
select * from patient
<where>
<if test="password != null">
and password=#{password}
if>
<if test="gender != null">
and gender=#{gender}
if>
where>
select>
AND
或 OR
,where
会自动去除(保险最好都写上)// 动态 sql Map 限定传参 set 判断
int updatePatientInfo(Map<String, Object> patientMap);
// Main 执行 sql
SqlSession sqlSession = MybatisUtil.getSqlSession();
PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
Map<String, Object> patientMap = new HashMap<>();
patientMap.put("password", "312314");
patientMap.put("gender", "男");
patientMap.put("identityNum", "3223123");
int patientList = patientMapper.updatePatientInfo(patientMap);
System.out.println(patientList + ":行受影响");
<update id="updatePatientInfo" parameterType="map">
update patient
<set>
<if test="password != null">
password=#{password},
if>
<if test="gender != null">
gender=#{gender},
if>
set>
<where>
identityNum=#{identityNum}
where>
update>
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
trim>
<trim prefix="SET" suffixOverrides=",">
...
trim>
prefixOverrides
忽略通过|
分隔的内容(AND |OR
中的空格是必要的)prefixOverrides
属性中指定的内容,并且插入prefix
属性中指定的内容select * from patient where (patientID=1 and patientID=2 and patientID=3)
-- 这里也可以用 where patientID IN(1,2,3) 只是为了练习拼接 sql
// 动态 sql foreach 便利
List<Patient> selecPatientInfoForeach(Map<String, Object> patientMap);
// Main 执行 sql
SqlSession sqlSession = MybatisUtil.getSqlSession();
PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
Map<String, Object> patientMap = new HashMap<>();
ArrayList<Integer> patientIdList = new ArrayList<>();
patientIdList.add(1);
patientIdList.add(2);
patientIdList.add(5);
patientMap.put("ids", patientIdList);
List<Patient> patientList = patientMapper.selecPatientInfoForeach(patientMap);
for (Patient patient : patientList) {
System.out.println(patient);
}
<select id="selecPatientInfoForeach" resultType="Patient" parameterType="map">
select *
from patient
<where>
<foreach item="patientID" collection="ids" open="and (" separator="or" close=")">
patientID=#{patientID}
foreach>
where>
select>
在写这类复杂的拼接 可以先在数据库中写好 正确的完整 sql 在来替换拆分
在使用 sql 的时候 会有一些重复性的 判断,例如上面的案例,都判断了title
与gender
类似于这样的 sql 就可以抽离成 sql 片段,以复用
<update id="updatePatientInfo" parameterType="map">
update patient
<set>
<include refid="if-password-gender"/>
set>
<where>
identityNum=#{identityNum}
where>
update>
<sql id="if-password-gender">
<if test="password != null">
password=#{password},
if>
<if test="gender != null">
gender=#{gender},
if>
sql>
要在带注解的映射器接口类中使用动态 SQL,可以使用script
元素。
@Update({""})
void updateAuthorValues(Author author);
bind
元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
select>
add(5);
patientMap.put(“ids”, patientIdList);
List patientList = patientMapper.selecPatientInfoForeach(patientMap);
for (Patient patient : patientList) {
System.out.println(patient);
}
```xml
在写这类复杂的拼接 可以先在数据库中写好 正确的完整 sql 在来替换拆分
在使用 sql 的时候 会有一些重复性的 判断,例如上面的案例,都判断了title
与gender
类似于这样的 sql 就可以抽离成 sql 片段,以复用
<update id="updatePatientInfo" parameterType="map">
update patient
<set>
<include refid="if-password-gender"/>
set>
<where>
identityNum=#{identityNum}
where>
update>
<sql id="if-password-gender">
<if test="password != null">
password=#{password},
if>
<if test="gender != null">
gender=#{gender},
if>
sql>
要在带注解的映射器接口类中使用动态 SQL,可以使用script
元素。
@Update({""})
void updateAuthorValues(Author author);
bind
元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
select>