MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理注册驱动、创建Connection、创建Statement、手动设置参数、结果集检索及映射等繁杂的过程代码。
历史进程
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对iBatis进行一些改进。
多学一招
同层产品:commons-dbutils、spring-jdbc、Hibernate
MyBaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases
WEB-INF/lib
目录下(目录不存在,需手动创建)# 创建数据库
CREATE DATABASE ssm_db1;
# 使用数据库
USE ssm_db1;
# 1.1 创建用户表
CREATE TABLE `user` (
`uid` VARCHAR(32) NOT NULL,
`username` VARCHAR(20) DEFAULT NULL, #用户名
`password` VARCHAR(32) DEFAULT NULL, #密码
`name` VARCHAR(20) DEFAULT NULL, #昵称
`email` VARCHAR(30) DEFAULT NULL, #电子邮箱
`telephone` VARCHAR(20) DEFAULT NULL, #电话
`birthday` DATE DEFAULT NULL, #生日
`sex` VARCHAR(10) DEFAULT NULL, #性别
`state` INT(11) DEFAULT 0, #状态:0=未激活,1=已激活
`code` VARCHAR(64) DEFAULT NULL, #激活码
PRIMARY KEY (`uid`)
) ;
# 1.2 初始化用户默认数据
INSERT INTO `user` VALUES ('u001','jack','1234','杰克','[email protected]','13612345678','2015-11-04','男',0,NULL);
INSERT INTO `user` VALUES ('u002','rose','1234','肉丝','[email protected]','13612345679','2015-11-05','女',0,NULL);
INSERT INTO `user` VALUES ('373eb242933b4f5ca3bd43503c34668b','ccc','ccc','aaa','[email protected]','15723689921','2015-11-04','男',0,'9782f3e837ff422b9aee8b6381ccf927bdd9d2ced10d48f4ba4b9f187edf7738'),('3ca76a75e4f64db2bacd0974acc7c897','bb','bb','张三','[email protected]','15723689921','1990-02-01','男',0,'1258e96181a9457987928954825189000bae305094a042d6bd9d2d35674684e6'),('62145f6e66ea4f5cbe7b6f6b954917d3','cc','cc','张三','[email protected]','15723689921','2015-11-03','男',0,'19f100aa81184c03951c4b840a725b6a98097aa1106a4a38ba1c29f1a496c231'),('c95b15a864334adab3d5bb6604c6e1fc','bbb','bbb','老王','[email protected]','15712344823','2000-02-01','男',0,'71a3a933353347a4bcacff699e6baa9c950a02f6b84e4f6fb8404ca06febfd6f'),('f55b7d3a352a4f0782c910b2c70f1ea4','aaa','aaa','小王','[email protected]','15712344823','2000-02-01','男',1,NULL);
package com.czxy.ssm.domain;
import java.util.Date;
/**
*
Create Table
CREATE TABLE `user` (
`uid` varchar(32) NOT NULL,
`username` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`sex` varchar(10) DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`code` varchar(64) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
*/
public class User {
private String uid;
private String username;
private String password;
private String name;
private String email;
private Date birthday;
private String sex;
private Integer state;
private String code;
@Override
public String toString() {
return "User{" +
"uid='" + uid + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", state=" + state +
", code='" + code + '\'' +
'}';
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public User(String uid, String username, String password, String name, String email, Date birthday, String sex, Integer state, String code) {
this.uid = uid;
this.username = username;
this.password = password;
this.name = name;
this.email = email;
this.birthday = birthday;
this.sex = sex;
this.state = state;
this.code = code;
}
public User() {
}
}
之前的开发中我们编写的都是UserDao,在MyBatis将dao称为Mapper。
所以此后所有dao接口统一命名成Mapper。
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
/**
* 查询所有
* @return
*/
@Select("select * from user")
public List<User> selectAll();
}
配置文件名称:SqlMapConfig.xml
配置文件位置:src
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="db1">
<environment id="db1">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/ssm_db1" />
<property name="username" value="root" />
<property name="password" value="1234" />
dataSource>
environment>
environments>
<mappers>
<package name="com.czxy.ssm.mapper"/>
mappers>
configuration>
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
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;
import java.util.List;
public class Test01_SelectAll {
public static void main(String[] args) throws IOException {
//1 加载配置文件
// 1.1 获得资源流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2 获得会话(连接)
SqlSession session = factory.openSession();
//3获得功能接口
UserMapper userMapper = session.getMapper(UserMapper.class);
//4 调用功能
List<User> userList = userMapper.selectAll();
//5 打印查询结果
for (User user : userList) {
System.out.println(user);
}
}
}
功能接口中的方法
如果参数简单类型,sql语句需要使用value [不推荐]
@Select("select * from user where name like #{value}")
public List<User> selectByName(String name);
如果使用@Param,可以进行相应的命名 【推荐】
@Select("select * from user where name like #{name}")
public List<User> selectByName(@Param("name") String name);
测试类
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
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;
import java.util.List;
public class Test02_Like {
public static void main(String[] args) throws IOException {
//1 加载配置文件
// 1.1 获得资源流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2 获得会话(连接)
SqlSession session = factory.openSession();
//3获得功能接口
UserMapper userMapper = session.getMapper(UserMapper.class);
//4 调用功能
List<User> userList = userMapper.selectByName("%王%");
//5 打印查询结果
for (User user : userList) {
System.out.println(user);
}
}
}
/**
* 插入数据
* @param user
*/
@Insert("insert into user(uid, username, password, name, email, birthday, sex, state) values(#{uid},#{username},#{password},#{name},#{email},#{birthday},#{sex},#{state})")
public Integer insert(User user);
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
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;
import java.util.Date;
import java.util.List;
public class Test03_Insert {
public static void main(String[] args) throws IOException {
//1 加载配置文件
// 1.1 获得资源流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2 获得会话(连接)
SqlSession session = factory.openSession();
//3获得功能接口
UserMapper userMapper = session.getMapper(UserMapper.class);
//4 调用功能
User user = new User();
user.setUid("1");
user.setUsername("jack");
user.setPassword("1234");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
Integer result = userMapper.insert(user);
System.out.println(result);
//5 提交资源
session.commit();
//6 释放资源
session.close();
}
}
/**
* 插入数据
* @param user
*/
@Insert("update user set username=#{username}, password=#{password}, name=#{name}, email=#{email},birthday=#{birthday},sex=#{sex}, state=#{state} where uid=#{uid}")
public Integer update(User user);
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
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;
import java.util.Date;
/**
* @author 禹哥
* @email [email protected]
*/
public class Test04_Update {
public static void main(String[] args) throws IOException {
//1 加载配置文件
// 1.1 获得资源流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2 获得会话(连接)
SqlSession session = factory.openSession();
//3获得功能接口
UserMapper userMapper = session.getMapper(UserMapper.class);
//4 调用功能
User user = new User();
user.setUid("1");
user.setUsername("jack1");
user.setPassword("12341");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
Integer result = userMapper.update(user);
System.out.println(result);
//5 提交资源
session.commit();
//6 释放资源
session.close();
}
}
/**
* 通过id删除
* @param uid
*/
@Delete("delete from user where uid = #{uid}")
public Integer deleteByPrimaryKey(@Param("uid") Integer uid);
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
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;
import java.util.Date;
public class Test05_Delete {
public static void main(String[] args) throws IOException {
//1 加载配置文件
// 1.1 获得资源流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2 获得会话(连接)
SqlSession session = factory.openSession();
//3获得功能接口
UserMapper userMapper = session.getMapper(UserMapper.class);
//4 调用功能
Integer result = userMapper.deleteByPrimaryKey(1);
System.out.println(result);
//5 提交资源
session.commit();
//6 释放资源
session.close();
}
}
1)添加jar包 (已添加)
2)添加配置文件
# 2. 输出格式
## log4j.appender.stdout=输出位置(固定值,由log4j提供)
## log4j.appender.stdout.Target=方式
## log4j.appender.stdout.layout=布局(固定值)
## log4j.appender.stdout.layout.ConversionPattern=格式
# 2.1 将日志输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c:%L - %m%n
# 2.2 将日志输出到文件
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:/file.log
log4j.appender.file.Append=false
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c:%L - %m%n
#1.log4j.rootLogger=日志级别, 输出方式1, 输出方式2, ...
## 日志级别:debug、info、warn、error
log4j.rootLogger=debug, stdout, file
# 3 自定义日志级别
## log4j.logger.包=日志级别
#log4j.logger.com.ibatis = debug
#log4j.logger.com.ibatis.common.jdbc.SimpleDataSource = debug
#log4j.logger.com.ibatis.common.jdbc.ScriptRunner = debug
#log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = 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.logger.org.apache.ibatis.transaction = info
log4j.logger.org.apache.ibatis.io = info
log4j.logger.org.apache.ibatis.datasource = info
log4j.logger.org.apache.ibatis.logging = info
package com.czxy.ssm.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.InputStream;
public class MyBatisUtils {
// 会话工厂
private static SqlSessionFactory factory;
static{
try {
// 1.1 加载核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
factory = new SqlSessionFactoryBuilder().build(is);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
/**
* 获得新会话
* @return
*/
private static SqlSession openSession(){
SqlSession sqlSession = local.get();
if(sqlSession == null){
sqlSession = factory.openSession();
local.set(sqlSession);
}
return sqlSession;
}
/**
* 获得mapper
* @param clazz
* @return
*/
public static <T> T getMapper(Class<T> clazz){
return openSession().getMapper(clazz);
}
/**
* 释放资源
*/
public static void close() {
SqlSession sqlSession = openSession();
if(sqlSession != null){
sqlSession.close();
}
}
/**
* 提交并释放资源
*/
public static void commitAndclose() {
SqlSession sqlSession = openSession();
if(sqlSession != null){
sqlSession.commit();
close();
}
}
/**
* 回滚并释放资源
*/
public static void rollbackAndclose() {
SqlSession sqlSession = openSession();
if(sqlSession != null){
sqlSession.rollback();
close();
}
}
}
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import java.util.Date;
public class Test06_Utils {
public static void main(String[] args) {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = new User();
user.setUid("1");
user.setUsername("jack");
user.setPassword("1234");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
Integer result = userMapper.insert(user);
System.out.println(result);
MyBatisUtils.commitAndclose();
}
}
在实际开发中,开发者会事先准备好配置文件模板,然后把模板Copy到项目中,再去修改重要的配置参数即可。这样开发者就无需把配置文件的结构背下来。但是开发者还是需要能够读懂配置文件的。下面我们来学习MyBatis核心配置文件。
配置子标签时,多个标签之间有先后顺序,使用时一定要注意。
如下就是常用4个标签的使用顺序:
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>properties>
<typeAliases>typeAliases>
<environments>environments>
<mappers>mappers>
configuration>
常见子标签介绍
标签名称 | 描述 |
---|---|
properties | 属性配置,也可引入外部properties文件 |
settings | 系统参数配置,所有参数都有默认值,通常不用配置 |
typeAliases | 类型别名,简化开发,仅减少类完全限定名的冗余。用于xml开发。 |
plugins | 插件,用于添加扩展功能。 |
environments | 环境配置,提供给factory配置信息 |
mappers | 映射器,确定SQL语句的位置 |
将易于修改的配置内容抽取到properties中,方便统一管理。mybatis提供两种方式来维护properties:property标签和properties配置文件。
1)配置:将需要的内容配置在
<properties>
<property name="jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/ssm_db1"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="1234"/>
properties>
2)使用:在配置文件的其他位置,通过 ${标识}
方式获得内容
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
整体示意图
在实际开发中,我们常见数据库的配置信息存放到properties文件,mybatis也提供了对配置文件的支持。
1)添加 db.properties配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db1
jdbc.username=root
jdbc.password=1234
2)加载properties文件,修改核心配置文件
<properties resource="db.properties" />
整体示意图
<properties resource="db.properties" >
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/ssm_db2"/>
properties>
mybatis框架系统配置settings,用于改变 MyBatis 的运行时行为。
mybatis提供可多种设置,用于系统的优化。
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则映射, 即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true | false | false |
autoMappingBehavior | 指定 MyBatis 是否以及如何自动映射指定的列到字段或属性。 NONE 表示取消自动映射; PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集 | NONE, PARTIAL, FULL | PARTIAL |
useGeneratedKeys | 允许 JDBC 支持自动生成主键,需要驱动兼容。 | true | false | false |
useColumnLabel | 使用列标签代替列名。 | true | false | true |
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。 | true | false | false |
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
MyBatis通过环境environments来配置数据库的连接和事务管理。
确定使用哪个配置
<environments default="配置2">
<environment id="配置1">
environment>
<environment id="配置2">
environment>
environments>
配置内容
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
扩展(查看源码,可以确定 type 配置内容)
事务的配置项
连接池的配置项
MANAGED 不管事务,只关闭连接
加载指定包package所有的接口。
<mappers>
<package name="com.czxy.ssm.mapper"/>
mappers>
在开发中,一个对象的查询条件,比对象中封装的属性更多。例如:user有birthday,我们需要查询2010-2020年的数据,时间段beginTime、endTime在User对象中就没有提供属性,实际开发中,一般提供一个自定义对象,例如:UserVo。
1)编写vo
package com.czxy.ssm.vo;
public class UserVo {
private String beginTime; // 开始时间
private String endTime; // 结束时间
public UserVo() {
}
public UserVo(String beginTime, String endTime) {
this.beginTime = beginTime;
this.endTime = endTime;
}
public String getBeginTime() {
return beginTime;
}
public void setBeginTime(String beginTime) {
this.beginTime = beginTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
}
2)修改Mapper,添加 condition 方法
/**
* 条件查询
* @param userVo
* @return
*/
@Select("select * from user where birthday >= #{beginTime} and birthday <= #{endTime}")
public List<User> condition(UserVo userVo);
3)测试类
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import com.czxy.ssm.vo.UserVo;
import java.util.Date;
import java.util.List;
public class Test07_Condition {
public static void main(String[] args) {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
List<User> list = userMapper.condition(new UserVo("2010-01-01", "2021-01-01"));
// 打印
list.forEach(user -> {
System.out.println(user);
});
MyBatisUtils.commitAndclose();
}
}
实际开发中,如果数据库字段和Java对象字段不能对应,就需要我们编写对应关系。
注解 | 描述 |
---|---|
@Results | 对象和表的映射关系。 |
@Result | 一个对象属性和一个表的字段的映射关系。 |
@ResultMap | 映射关系,使用@Results声明的映射关系。 |
/**
@Results(value = 一组Result )
*/
@Results(value = {
@Result(property = "属性名", column = "字段名", id = true),
@Result(property = "属性名2", column = "字段名2"),
@Result(property = "属性名3", column = "字段名3")
})
/**
* 查询所有
* @return
*/
@Select("select * from user")
@Results({
@Result(property = "uid", column = "uid", id = true),
@Result(property = "username", column = "username"),
@Result(property = "password", column = "password")
})
public List<User> selectAll();
语法
@Select(...)
@Results(id = "标识", value = {
...})
public 返回值 方法名();
@Select(...)
@ResultMap("标识")
public 返回值 方法名2();
使用
/**
* 查询所有
* @return
*/
@Select("select * from user")
@Results(id = "userResult", value = {
@Result(property = "uid", column = "uid", id = true),
@Result(property = "username", column = "username"),
@Result(property = "password", column = "password")
})
public List<User> selectAll();
/**
* 通过id查询详情
* @param uid
* @return
*/
@Select("select * from user where uid = #{uid}")
@ResultMap("userResult")
public User selectById(@Param("uid") String uid);
注解名称 | 描述 |
---|---|
@Insert | 添加sql |
@Update | 更新sql |
@Delete | 删除sql |
@Select | 查询sql |
@Param | 形参命名 |
@Results | 对象和表的映射关系。 |
@Result | 一个对象属性和一个表的字段的映射关系。 |
CREATE TABLE `orders` (
`oid` VARCHAR(32) PRIMARY KEY NOT NULL,
`ordertime` DATETIME DEFAULT NULL, #下单时间
`total_price` DOUBLE DEFAULT NULL, #总价
`state` INT(11) DEFAULT NULL, #订单状态:1=未付款;2=已付款,未发货;3=已发货,没收货;4=收货,订单结束
`address` VARCHAR(30) DEFAULT NULL, #收获地址
`name` VARCHAR(20) DEFAULT NULL, #收获人
`telephone` VARCHAR(20) DEFAULT NULL, #收货人电话
`uid` VARCHAR(32) DEFAULT NULL,
CONSTRAINT `order_fk_0001` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
) ;
INSERT INTO `orders` VALUES ('x001','2010-10-10',10,1,'江苏','张三','12345','u001');
INSERT INTO `orders` VALUES ('x002','2010-11-11',20,2,'河北','李四','67890','u001');
INSERT INTO `orders` VALUES ('x003','2011-10-10',30,3,'山西','王五','66666','u002')
package com.czxy.ssm.domain;
import java.util.Date;
/**
*
Create Table
CREATE TABLE `orders` (
`oid` varchar(32) NOT NULL,
`ordertime` datetime DEFAULT NULL,
`total` double DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`address` varchar(30) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`telephone` varchar(20) DEFAULT NULL,
`uid` varchar(32) DEFAULT NULL,
PRIMARY KEY (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
*/
public class Order {
private String oid; // 订单编号
private Date ordertime; // 下单时间
private Double total; // 订单总金额
private Integer state; // 订单状态 0 未支付 1 已支付 2已发货 3已收货
private String address; // 收货人地址
private String name; // 收货人姓名
private String telephone; // 收货人电话
private String uid;
@Override
public String toString() {
return "Order{" +
"oid='" + oid + '\'' +
", ordertime=" + ordertime +
", total=" + total +
", state=" + state +
", address='" + address + '\'' +
", name='" + name + '\'' +
", telephone='" + telephone + '\'' +
", uid='" + uid + '\'' +
'}';
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
public Date getOrdertime() {
return ordertime;
}
public void setOrdertime(Date ordertime) {
this.ordertime = ordertime;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public Order(String oid, Date ordertime, Double total, Integer state, String address, String name, String telephone, String uid) {
this.oid = oid;
this.ordertime = ordertime;
this.total = total;
this.state = state;
this.address = address;
this.name = name;
this.telephone = telephone;
this.uid = uid;
}
public Order() {
}
}
以对象的方法,描述两个JavaBean之间的关系
JavaBean:User
public class User {
private String uid;
private String username;
private String password;
private String name;
private String email;
private Date birthday;
private String sex;
private Integer state;
private String code;
// 一对多:一个用户 拥有【多个用户】
private List<Order> orderList = new ArrayList<>();
// ...
}
JavaBean:Order
public class Order {
private String oid; // 订单编号
private Date ordertime; // 下单时间
private Double total; // 订单总金额
private Integer state; // 订单状态 0 未支付 1 已支付 2已发货 3已收货
private String address; // 收货人地址
private String name; // 收货人姓名
private String telephone; // 收货人电话
private String uid;
// 多对一, 多个订单 属于 【一个用户】
private User user;
// ...
}
在Mybatis注解开发中,需要通过@Result进行关联关系的描述。
@Result(
property = "1表JavaBean属性名",
column = "1表字段名",
many = @Many(select = "多表Mapper的方法签名")
)
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Order;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface OrderMapper {
/**
* 通过id查询详情
* @param uid
* @return
*/
@Select("select * from orders where uid = #{uid}")
public Order findOrdersByUserId(@Param("uid") String uid) ;
}
public interface UserMapper {
/**
* 查询所有
* @return
*/
@Select("select * from user")
@Results(id = "userResult", value = {
@Result(property = "uid", column = "uid", id = true),
@Result(property = "username", column = "username"),
@Result(property = "password", column = "password"),
@Result(property="orderList" , many=@Many(select="com.czxy.ssm.mapper.OrderMapper.findOrdersByUserId") , column="uid")
})
public List<User> selectAll();
}
在Mybatis注解开发中,需要通过@Result进行关联关系的描述。
@Result(
property = "多表JavaBean属性名",
column = "多表字段名",
one = @One(select ="1表Mapper的方法签名")
)
需求:查询订单时,查询关联的用户信息
分析:
1)通过user_id查询用户详情
2)通过id查询订单详情
/**
* 通过id查询详情
* @param uid
* @return
*/
@Select("select * from user where uid = #{uid}")
@ResultMap("userResult")
public User selectById(@Param("uid") String uid);
/**
*
* @param id
* @return
*/
@Select("select * from orders where oid = #{oid}")
@Results({
@Result(property="oid" , column="oid"),
@Result(property="ordertime" , column="ordertime"),
@Result(property="total" , column="total"),
@Result(property="state" , column="state"),
@Result(property="address" , column="address"),
@Result(property="name" , column="name"),
@Result(property="telephone" , column="telephone"),
@Result(property="uid" , column="uid"),
@Result(property="user" , one=@One(select="com.czxy.ssm.mapper.UserMapper.selectById") , column="uid"),
})
public Order selectById(@Param("oid") String id);
#老师表
CREATE TABLE teacher(
tid INT PRIMARY KEY,
NAME VARCHAR(50)
);
#学生表
CREATE TABLE student(
sid INT PRIMARY KEY,
NAME VARCHAR(50)
);
#中间表
CREATE TABLE teacher_student(
teacher_id INT ,
student_id INT,
CONSTRAINT ts_t_fk FOREIGN KEY (teacher_id) REFERENCES teacher(tid),
CONSTRAINT ts_s_fk FOREIGN KEY (student_id) REFERENCES student(sid)
);
INSERT INTO teacher VALUES (1,'肖老师');
INSERT INTO teacher VALUES (2,'马老师');
INSERT INTO student VALUES (1,'张三');
INSERT INTO student VALUES (2,'李四');
INSERT INTO student VALUES (3,'王五');
INSERT INTO teacher_student VALUES (1,1);
INSERT INTO teacher_student VALUES (1,2);
INSERT INTO teacher_student VALUES (1,3);
INSERT INTO teacher_student VALUES (2,1);
INSERT INTO teacher_student VALUES (2,2);
JavaBean:Student
package com.czxy.ssm.domain;
import java.util.ArrayList;
import java.util.List;
/**
* #学生表
* CREATE TABLE student(
* sid INT PRIMARY KEY,
* NAME VARCHAR(50)
* );
public class Student {
private Integer sid;
private String name;
private List teacherList = new ArrayList<>();
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getTeacherList() {
return teacherList;
}
public void setTeacherList(List teacherList) {
this.teacherList = teacherList;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", name='" + name + '\'' +
", teacherList=" + teacherList +
'}';
}
}
JavaBean:Teacher
package com.czxy.ssm.domain;
import java.util.ArrayList;
import java.util.List;
/**
* #老师表
* CREATE TABLE teacher(
* tid INT PRIMARY KEY,
* NAME VARCHAR(50)
* );
*/
public class Teacher {
private Integer tid;
private String name;
private List<Student> studentList = new ArrayList<>();
public Integer getTid() {
return tid;
}
public void setTid(Integer tid) {
this.tid = tid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
@Override
public String toString() {
return "Teacher{" +
"tid=" + tid +
", name='" + name + '\'' +
", studentList=" + studentList +
'}';
}
}
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Student;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface StudentMapper {
/**
* 通过tid查询对应的学生
* @param tid
* @return
* @throws Exception
*/
@Select("select * from student s where s.sid in (select student_id from teacher_student where teacher_id = #{tid} )")
public Student findStudentByTeacherId(@Param("tid") Integer tid) throws Exception;
}
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Teacher;
import org.apache.ibatis.annotations.*;
public interface TeacherMapper {
@Select("select * from teacher t where t.tid = #{tid}")
@Results({
@Result(property="tid" , column="tid"),
@Result(property="name" , column="name"),
@Result(property="studentList" , many=@Many(select="com.czxy.ssm.mapper.StudentMapper.findStudentByTeacherId") , column="tid"),
})
public Teacher selectById(@Param("tid") Integer tid);
}
package com.czxy.ssm.test;
import com.czxy.ssm.domain.Order;
import com.czxy.ssm.domain.Teacher;
import com.czxy.ssm.mapper.OrderMapper;
import com.czxy.ssm.mapper.TeacherMapper;
import com.czxy.ssm.utils.MyBatisUtils;
public class Test09_SelectTeacher {
public static void main(String[] args) {
TeacherMapper teacherMapper = MyBatisUtils.getMapper(TeacherMapper.class);
Teacher teacher = teacherMapper.selectById(1);
// 打印
System.out.println(teacher);
MyBatisUtils.commitAndclose();
}
}
查询所有的老师,并查询老师对应的学生。
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Teacher;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface TeacherMapper {
/**
* 通过id查询详情
* @param tid
* @return
*/
@Select("select * from teacher t where t.tid = #{tid}")
@Results(id = "teacherResult" , value = {
@Result(property="tid" , column="tid"),
@Result(property="name" , column="name"),
@Result(property="studentList" , many=@Many(select="com.czxy.ssm.mapper.StudentMapper.findStudentByTeacherId") , column="tid"),
})
public Teacher selectById(@Param("tid") Integer tid);
/**
* 查询所有
* @return
*/
@Select("select * from teacher")
@ResultMap("teacherResult")
public List<Teacher> selectList();
}
测试类
package com.czxy.ssm.test;
import com.czxy.ssm.domain.Teacher;
import com.czxy.ssm.mapper.TeacherMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import java.util.List;
public class Test10_SelectAllTeacher {
public static void main(String[] args) {
TeacherMapper teacherMapper = MyBatisUtils.getMapper(TeacherMapper.class);
List<Teacher> teacherList = teacherMapper.selectList();
// 打印
teacherList.forEach(teacher -> {
System.out.println(teacher);
});
MyBatisUtils.commitAndclose();
}
}
MyBatis没有提供分页支持,需要自己编写limit语句。
开发中我们采用PageHelper插件。
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
<property name="rowBoundsWithCount" value="true"/>
plugin>
plugins>
1) 设置分页数据
PageHelper.startPage(int pageNum, int pageSize)
参数1:pageNum 第几页
参数2:pageSize 页面显示个数
2) 封装分页结果 PageInfo
new PageInfo(查询结果) //创建分页对象
pageInfo.getTotal(), //自动查询总条数
pageInfo.getPages(), //总分页数
package com.czxy.ssm.test;
import com.czxy.ssm.domain.Teacher;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.TeacherMapper;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.List;
public class Test11_Page {
public static void main(String[] args) {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
// 设置分页 **
PageHelper.startPage(1,2);
// 查询
List<User> users = userMapper.selectAll();
// 获得封装对象 **
PageInfo<User> pageInfo = new PageInfo<>(users);
// 打印分页信息
long total = pageInfo.getTotal();
List<User> list = pageInfo.getList();
System.out.println("总条数:" + total);
System.out.println("分页数据:");
list.forEach(user -> {
System.out.println(user);
});
MyBatisUtils.commitAndclose();
}
}
通用Mapper对MyBatis进行简化的第三方工具包。
通用Mapper提供了一个名为Mapper
的接口,用于自动完成单表的增删改查操作。
public interface UserMapper extends Mapper<User> {
}
package com.czxy.ssm.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 tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
import tk.mybatis.mapper.entity.Config;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import java.io.InputStream;
public class MyBatisUtils {
// 会话工厂
private static SqlSessionFactory factory;
static{
try {
// 1.1 加载核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 1.2 获得工厂
factory = new SqlSessionFactoryBuilder().build(is);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
/**
* 获得新会话
* @return
*/
private static SqlSession openSession(){
SqlSession sqlSession = local.get();
if(sqlSession == null){
sqlSession = factory.openSession();
//创建一个MapperHelper
MapperHelper mapperHelper = new MapperHelper();
//特殊配置
Config config = new Config();
// 设置UUID生成策略
// 配置UUID生成策略需要使用OGNL表达式
// 默认值32位长度:@java.util.UUID@randomUUID().toString().replace("-", "")
//config.setUUID("");
// 主键自增回写方法,默认值MYSQL,详细说明请看文档
// config.setIDENTITY("HSQLDB");
// 支持方法上的注解
// 3.3.1版本增加
config.setEnableMethodAnnotation(true);
config.setNotEmpty(true);
// 序列的获取规则,使用{num}格式化参数,默认值为{0}.nextval,针对Oracle
// 可选参数一共3个,对应0,1,2,分别为SequenceName,ColumnName, PropertyName
//config.setSeqFormat("NEXT VALUE FOR {0}");
// 设置全局的catalog,默认为空,如果设置了值,操作表时的sql会是catalog.tablename
//config.setCatalog("");
// 设置全局的schema,默认为空,如果设置了值,操作表时的sql会是schema.tablename
// 如果同时设置了catalog,优先使用catalog.tablename
//config.setSchema("");
// 主键自增回写方法执行顺序,默认AFTER,可选值为(BEFORE|AFTER)
//config.setOrder("AFTER");
//设置配置
mapperHelper.setConfig(config);
// 注册通用tk.mybatis.mapper.common.Mapper接口 - 可以自动注册继承的接口
mapperHelper.registerMapper(Mapper.class);
mapperHelper.registerMapper(MySqlMapper.class);
// mapperHelper.registerMapper(SqlServerMapper.class);
// mapperHelper.registerMapper(IdsMapper.class);
//配置完成后,执行下面的操作
mapperHelper.processConfiguration(sqlSession.getConfiguration());
local.set(sqlSession);
}
return sqlSession;
}
/**
* 获得mapper
* @param clazz
* @return
*/
public static <T> T getMapper(Class<T> clazz){
return openSession().getMapper(clazz);
}
/**
* 释放资源
*/
public static void close() {
SqlSession sqlSession = openSession();
if(sqlSession != null){
sqlSession.close();
}
}
/**
* 提交并释放资源
*/
public static void commitAndclose() {
SqlSession sqlSession = openSession();
if(sqlSession != null){
sqlSession.commit();
close();
}
}
/**
* 回滚并释放资源
*/
public static void rollbackAndclose() {
SqlSession sqlSession = openSession();
if(sqlSession != null){
sqlSession.rollback();
close();
}
}
}
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper2 extends Mapper<User> {
}
查询方法
方法名 | 描述 |
---|---|
T selectOne(T t) | 根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号 |
List select(T t) | 根据实体中的属性值进行查询,查询条件使用等号 |
List selectAll() | 查询全部结果 |
int selectCount(T t) | 根据实体中的属性查询总数,查询条件,使用等号 |
T selectByPrimaryKey(Object key) | 根据主键字段进行查询 |
boolean existsWhithPrimaryKey(Object key) | 根据主键字段查询记录是否存在 |
List selectByExample(Object example) | 根据Example条件进行查询 |
T selectOneByExample(Object example) | 根据Example条件进行查询,只能有一个返回值 |
int selectCountByExample(Object example) | 根据Example条件进行查询记录数 |
插入方法
方法名 | 描述 |
---|---|
int insert(T t) | 保存一个实体,null的属性也会保存,不会使用数据库默认值 |
int intsertSelective(T t) | 保存一个实体,null的属性不会保存,使用数据库默认值 |
更新方法
方法名 | 描述 |
---|---|
int updateByPrimaryKey(T t) | 根据主键更新实体全部字段,null值会被更新 |
int updateByPrimaryKeySelective(T t) | 根据主键更新实体中不为null值的字段 |
删除方法
方法名 | 描述 |
---|---|
int delete(T t) | 根据实体属性作为条件进行删除,查询条件使用等号 |
int deletePrimaryKey(Object key) | 根据主键字段进行删除 |
int deleteByExample(Object example) | 根据Example条件删除数据 |
1)确定主键,否则所有字段都是主键
2)测试
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.mapper.UserMapper2;
import com.czxy.ssm.utils.MyBatisUtils;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class Test13_Mapper {
@Test
public void testSelectByPrimaryKey() {
UserMapper2 userMapper2 = MyBatisUtils.getMapper(UserMapper2.class);
User user = userMapper2.selectByPrimaryKey("1");
System.out.println(user);
MyBatisUtils.commitAndclose();
}
}
@Test
public void testSelectAll() {
UserMapper2 userMapper2 = MyBatisUtils.getMapper(UserMapper2.class);
List<User> list = userMapper2.selectAll();
// 打印
list.forEach(System.out::println);
MyBatisUtils.commitAndclose();
}
@Test
public void testInsert() {
UserMapper2 userMapper2 = MyBatisUtils.getMapper(UserMapper2.class);
User user = new User();
user.setUid("2");
user.setUsername("jack");
user.setPassword("1234");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
int result = userMapper2.insert(user);
// 打印
System.out.println(result);
MyBatisUtils.commitAndclose();
}
@Test
public void testUpdate() {
UserMapper2 userMapper2 = MyBatisUtils.getMapper(UserMapper2.class);
User user = new User();
user.setUid("2");
user.setUsername("jack");
user.setPassword("1234");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
int result = userMapper2.updateByPrimaryKey(user);
// 打印
System.out.println(result);
MyBatisUtils.commitAndclose();
}
@Test
public void testDelete() {
UserMapper2 userMapper2 = MyBatisUtils.getMapper(UserMapper2.class);
int result = userMapper2.deleteByPrimaryKey("2");
// 打印
System.out.println(result);
MyBatisUtils.commitAndclose();
}
// 获得多条件对象
Example example = new Example(对象.class);
Example.Criteria criteria = example.createCriteria();
// 常见条件方法
andLike() //模糊查询
andEqualTo() //等值查询
andLessThanOrEqualTo() //<=查询
andGreaterThanOrEqualTo() //>=查询
andBetween() //区间查询
@Test
public void testCondition() {
UserMapper2 userMapper2 = MyBatisUtils.getMapper(UserMapper2.class);
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andLike("name", "%王%");
criteria.andEqualTo("sex", "男");
List<User> list = userMapper2.selectByExample(example);
for (User user : list) {
System.out.println(user);
}
MyBatisUtils.commitAndclose();
}
1)选择Web 应用
2)创建项目mybatis-demo02
步骤1:编写Dao接口,用于确定方法名称
步骤2:编写Mapper.xml文件,用于编写SQL语句
步骤3:编写SqlMapConfig.xml 核心配置文件,并添加mapper xml文件
步骤4:测试
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.User;
public interface UserMapper {
/**
* 通过id查询详情
* @param uid
* @return
*/
public User selectById(String uid);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.UserMapper">
<select id="selectById" parameterType="string" resultType="com.czxy.ssm.domain.User">
select * from user where uid = #{id}
select>
mapper>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import org.junit.Test;
public class TestUserMapper {
@Test
public void testSelectById() {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = userMapper.selectById("1");
System.out.println(user);
MyBatisUtils.commitAndclose();
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Mapper类">
<select id="方法名">SQL语句select>
<insert id="方法名">SQL语句insert>
<update id="方法名">SQL语句update>
<delete id="方法名">SQL语句delete>
mapper>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper类">
<select id="方法名" parameterType="参数类型">SQL语句select>
mapper>
简单类型:
<select id="findUserById" parameterType="int" resultType="com.czxy.domain.User">
select * from user where uid = #{id}
select>
POJO类型:
<insert id="insertUser" parameterType="com.czxy.domain.User">
insert into user(uid, username, password, name, email, birthday, sex, state) values(#{uid},#{username},#{password},#{name},#{email},#{birthday},#{sex},#{state})
insert>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper类">
<select id="方法名" resultType="结果类型">SQL语句select>
mapper>
简单类型
<select id="findUserCount" resultType="int">
select count(*) from user
select>
POJO类型
<select id="findUserById" parameterType="int" resultType="com.czxy.domain.User">
select * from user where uid = #{id}
select>
resultType可以指定pojo将查询结果封装到该pojo中,但需要pojo的属性名和sql查询的列名保持一致。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系。
语法:
<resultMap type="JavaBean类型" id="resultMap名称">
<id column="表列名" property="JavaBean属性名"/>
<result column="表列名" property="JavaBean属性名"/>
resultMap>
<select resultMap="resultMap名称">
select>
实例:
<resultMap type="com.czxy.ssm.domain.User" id="userResultMap">
<id column="uid" property="uid"/>
<result column="username" property="username"/>
resultMap>
<select id="selectById" parameterType="string" resultMap="userResultMap">
select * from user where uid = #{id}
select>
别名 | 映射类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
声明别名,在 SqlMapConfig.xml 配置文件中声明
方式1:一次定义一个类
<typeAliases>
<typeAlias type="类型" alias="别名"/>
typeAliases>
方式2:一次定义一个包下的所有类
<typeAliases>
<package name="包名"/>
typeAliases>
使用别名,在mapper中直接使用
<select id="selectById" parameterType="string" resultType="user">
select * from user where uid = #{id}
select>
在SqlMapConfig.xml文件中,通过
和
加载映射文件
方式1:加载指定文件
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
方式2:加载指定包下的所有映射文件
<mappers>
<package name="com.czxy.ssm.mapper"/>
mappers>
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.vo.UserVo;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
/**
* 通过id查询详情
* @param uid
* @return
*/
public User selectById(String uid);
/**
* 查询所有
* @return
*/
public List<User> selectAll();
/**
* 模糊查询
* @param name
* @return
*/
public List<User> selectByName(@Param("name") String name);
/**
* 插入数据
* @param user
*/
public Integer insert(User user);
/**
* 插入数据
* @param user
*/
public Integer updateByPrimaryKey(User user);
/**
* 通过id删除
* @param uid
*/
public Integer deleteByPrimaryKey(@Param("uid") String uid);
/**
* 条件查询
* @param userVo
* @return
*/
public List<User> condition(UserVo userVo);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.UserMapper">
<resultMap type="com.czxy.ssm.domain.User" id="userResultMap">
<id column="uid" property="uid"/>
<result column="username" property="username"/>
resultMap>
<select id="selectById" parameterType="string" resultMap="userResultMap">
select * from user where uid = #{id}
select>
<select id="selectAll" parameterType="string" resultMap="userResultMap">
select * from user
select>
<select id="selectByName" parameterType="string" resultMap="userResultMap">
select * from user where name like #{name}
select>
<insert id="insert" parameterType="user">
insert into user(uid, username, password, name, email, birthday, sex, state) values(#{uid},#{username},#{password},#{name},#{email},#{birthday},#{sex},#{state})
insert>
<update id="updateByPrimaryKey" parameterType="user">
update user set username=#{username}, password=#{password}, name=#{name}, email=#{email},birthday=#{birthday},sex=#{sex}, state=#{state} where uid=#{uid}
update>
<delete id="deleteByPrimaryKey" >
delete from user where uid = #{uid}
delete>
mapper>
package com.czxy.ssm.test;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class TestUserMapper {
@Test
public void testSelectById() {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = userMapper.selectById("1");
System.out.println(user);
MyBatisUtils.commitAndclose();
}
@Test
public void testSelectAll() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
List<User> list = UserMapper.selectAll();
// 打印
list.forEach(System.out::println);
MyBatisUtils.commitAndclose();
}
@Test
public void testSelectByName() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
List<User> list = UserMapper.selectByName("%张%");
// 打印
list.forEach(System.out::println);
MyBatisUtils.commitAndclose();
}
@Test
public void testInsert() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = new User();
user.setUid("2");
user.setUsername("jack");
user.setPassword("1234");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
int result = UserMapper.insert(user);
// 打印
System.out.println(result);
MyBatisUtils.commitAndclose();
}
@Test
public void testUpdate() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = new User();
user.setUid("2");
user.setUsername("jack");
user.setPassword("1234");
user.setName("杰克");
user.setEmail("[email protected]");
user.setBirthday(new Date());
user.setSex("男");
user.setSex("0");
int result = UserMapper.updateByPrimaryKey(user);
// 打印
System.out.println(result);
MyBatisUtils.commitAndclose();
}
@Test
public void testDelete() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
int result = UserMapper.deleteByPrimaryKey("2");
// 打印
System.out.println(result);
MyBatisUtils.commitAndclose();
}
}
动态SQL就是Mybatis允许在映射文件中通过标签控制SQL语句最后的拼凑结果。
语法:在mapper映射文件中,
<select>
<if test="条件">
//有效的SQL语句片段
if>
<select>
封装对象:UserVo
public class UserVo {
private String name; // 模糊查询
private String beginTime; // 开始时间
private String endTime; // 结束时间
// ...
}
多条件查询,拼凑恒等条件 where 1=1
<select id="condition" parameterType="userVo" resultType="user" >
select * from user where 1=1
<if test="name != null and name != ''">
and name like '%${name}%'
if>
select>
测试
@Test
public void testCondtion() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
UserVo userVo = new UserVo();
userVo.setName("张");
List<User> list = UserMapper.condition(userVo);
// 打印
list.forEach(System.out::println);
MyBatisUtils.commitAndclose();
}
多条件查询时,我们使用了一个小技巧“where 1=1”,mybatis提供了一个
进行取代。
修改映射文件
<select id="condition" parameterType="userVo" resultType="user" >
select * from user
<where>
<if test="name != null and name != ''">
and name like '%${name}%'
if>
where>
select>
>标签
语法:
<foreach collection="数组" open="uid in (" item="变量" separator="," close=")">
foreach>
封装对象
public class UserVo {
private List<String> ids = new ArrayList<>();
private String name; // 模糊查询
private String beginTime; // 开始时间
private String endTime; // 结束时间
// ...
}
多条件查询
<select id="condition" parameterType="userVo" resultType="user" >
select * from user
<where>
<foreach collection="ids" open="uid in (" item="id" separator="," close=")">
'${id}'
foreach>
where>
select>
测试
@Test
public void testCondtion() {
UserMapper UserMapper = MyBatisUtils.getMapper(UserMapper.class);
UserVo userVo = new UserVo();
userVo.setIds(Arrays.asList("u001","u002"));
List<User> list = UserMapper.condition(userVo);
// 打印
list.forEach(System.out::println);
MyBatisUtils.commitAndclose();
}
<select id="">
<choose>
<when test="">when>
<when test="">when>
<otherwise>otherwise>
choose>
select>
定义公共SQL语句,使用
将需要的SQL片段拼凑到指定的位置。
<sql id="user_all_column">uid, username, password, name, email, birthday, sex, statesql>
<select id="selectAll" parameterType="string" resultMap="userResultMap">
select <include refid="user_all_column" /> from user
select>
UserMapper,已有
public interface UserMapper {
/**
* 通过id查询详情
* @param uid
* @return
*/
public User selectById(String uid);
}
OrderMapper
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Order;
import org.apache.ibatis.annotations.Param;
public interface OrderMapper {
/**
* 查询指定用户的所有的订单
* @param uid
* @return
*/
public Order findOrdersByUserId(@Param("uid") Integer uid) ;
}
OrdersMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.OrderMapper">
<select id="findOrdersByUserId" parameterType="string" resultType="order" >
select * from orders where uid = #{uid}
select>
mapper>
UserMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.UserMapper">
<resultMap type="com.czxy.ssm.domain.User" id="userResultMap">
<id column="uid" property="uid"/>
<result column="username" property="username"/>
<collection property="orderList" column="uid" select="com.czxy.ssm.mapper.OrderMapper.findOrdersByUserId" />
resultMap>
<select id="selectById" parameterType="string" resultMap="userResultMap">
select * from user where uid = #{id}
select>
mapper>
public class TestUserMapper {
@Test
public void testSelectById() {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = userMapper.selectById("u001");
System.out.println(user);
MyBatisUtils.commitAndclose();
}
}
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Order;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface OrderMapper {
/**
*
* @param oid
* @return
*/
public Order selectById(@Param("oid") String oid);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.OrderMapper">
<resultMap id="ordersResultMap" type="order">
<id property="oid" column="oid">id>
<result property="ordertime" column="ordertime" >result>
<result property="total" column="total" >result>
<result property="state" column="state" >result>
<result property="address" column="address" >result>
<result property="name" column="name" >result>
<result property="telephone" column="telephone" >result>
<result property="uid" column="uid" >result>
<association property="user" select="com.czxy.ssm.mapper.UserMapper.selectById" column="uid" />
resultMap>
<select id="selectById" resultMap="ordersResultMap">
select * from orders where oid = #{oid}
select>
mapper>
package com.czxy.ssm.test;
import com.czxy.ssm.domain.Order;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.OrderMapper;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import com.czxy.ssm.vo.UserVo;
import org.junit.Test;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
public class TestOrderMapper {
@Test
public void testSelectById() {
OrderMapper orderMapper = MyBatisUtils.getMapper(OrderMapper.class);
Order order = orderMapper.selectById("x001");
System.out.println(order);
MyBatisUtils.commitAndclose();
}
}
-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.OrderMapper">
<select id="findOrdersByUserId" parameterType="string" resultType="order" >
select * from orders where uid = #{
uid}
</select>
</mapper>
UserMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.UserMapper">
<resultMap type="com.czxy.ssm.domain.User" id="userResultMap">
<id column="uid" property="uid"/>
<result column="username" property="username"/>
<collection property="orderList" column="uid" select="com.czxy.ssm.mapper.OrderMapper.findOrdersByUserId" />
resultMap>
<select id="selectById" parameterType="string" resultMap="userResultMap">
select * from user where uid = #{id}
select>
mapper>
public class TestUserMapper {
@Test
public void testSelectById() {
UserMapper userMapper = MyBatisUtils.getMapper(UserMapper.class);
User user = userMapper.selectById("u001");
System.out.println(user);
MyBatisUtils.commitAndclose();
}
}
package com.czxy.ssm.mapper;
import com.czxy.ssm.domain.Order;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface OrderMapper {
/**
*
* @param oid
* @return
*/
public Order selectById(@Param("oid") String oid);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.ssm.mapper.OrderMapper">
<resultMap id="ordersResultMap" type="order">
<id property="oid" column="oid">id>
<result property="ordertime" column="ordertime" >result>
<result property="total" column="total" >result>
<result property="state" column="state" >result>
<result property="address" column="address" >result>
<result property="name" column="name" >result>
<result property="telephone" column="telephone" >result>
<result property="uid" column="uid" >result>
<association property="user" select="com.czxy.ssm.mapper.UserMapper.selectById" column="uid" />
resultMap>
<select id="selectById" resultMap="ordersResultMap">
select * from orders where oid = #{oid}
select>
mapper>
package com.czxy.ssm.test;
import com.czxy.ssm.domain.Order;
import com.czxy.ssm.domain.User;
import com.czxy.ssm.mapper.OrderMapper;
import com.czxy.ssm.mapper.UserMapper;
import com.czxy.ssm.utils.MyBatisUtils;
import com.czxy.ssm.vo.UserVo;
import org.junit.Test;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
public class TestOrderMapper {
@Test
public void testSelectById() {
OrderMapper orderMapper = MyBatisUtils.getMapper(OrderMapper.class);
Order order = orderMapper.selectById("x001");
System.out.println(order);
MyBatisUtils.commitAndclose();
}
}
xml版
"d1" type="com.czxy.ssm.domain.Order">
"uid" column="uid"></id>
//一对多
"user" column="uid" select="com.czxy.ssm.mapper.UserMapper.user">
//多对一
"user" column="uid" select="com.czxy.ssm.mapper.UserMapper.user"></association>
</collection>
</resultMap>
注解版
//一对多 many
//多对多 one
将数据库表中的uid拿到 com.czxy.ssm.mapper.UserMapper.user进行执行 然后将结果封装到user中