目录
1、MyBatis的简介
1.1、原始jdbc操作(查询数据)
1.2、原始jdbc操作的分析
1.3、什么是MyBatis
2、MyBatis的快速入门
2.1、MyBatis开发步骤
3、MyBatis的映射文件概述
4、MyBatis的增删改查
4.1、插入操作要注意的问题
4.2、修改操作要注意的问题
4.3、删除操作要注意的问题
5、MyBatis核心配置文件概述
5.1、MyBatis常用配置解析
5.1.1、environments标签
5.1.2、mappers标签
5.1.3、Properties标签
5.1.4、typeAliases标签
6、MyBatis的相应API
6.1、SqlSession工厂构建器SqlSessionFactoryBuilder
6.2、SqlSession工厂对象SqlSessionFactory
6.3、SqlSession会话对象
7、MyBatis的Dao层实现
7.1、传统开发方式
7.1.1、编写UserDao接口
8、MyBatis注解开发
8.1、MyBatis的常用注解
8.2、MyBatis的增删改查
8.3、MyBatis的注解实现复杂映射开发
8.4、一对一查询
8.5、一对多查询
8.5.1、一对多查询的模型
8.6、多对多查询
8.6.1、多对多查询的模型
原始jdbc开发存在的问题如下:
应对上述问题给出的解决方案:
MyBatis官网地址:http://www.mybatis.org/mybatis-3/
MyBatis开发步骤:
pom.xml:
...
mysql
mysql-connector-java
5.1.32
org.mybatis
mybatis
3.4.6
...
package com.domain;
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
UserMapper.xml:
sqlMapConfig.xml:
package com.test;
import com.domain.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.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
@Test
public void test1() throws IOException {
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作 参数:namespace+id
List userList = sqlSession.selectList("userMapper.findAll");
//打印数据
System.out.println(userList);
//释放资源
sqlSession.close();
}
}
userMapper.xml:
insert into user values(#{id},#{username},#{password},#{birthday})
update user set username=#{username},password=#{password} where id=#{id}
delete from user where id=#{id}
package com.test;
import com.domain.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.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
@Test
//查询操作
public void test1() throws IOException {
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作 参数:namespace+id
List userList = sqlSession.selectList("userMapper.findAll");
//打印数据
System.out.println(userList);
//释放资源
sqlSession.close();
}
@Test
//插入操作
public void test2() throws IOException {
//模拟user对象
User user = new User();
user.setId(1);
user.setUsername("张三");
user.setPassword("123456");
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作
sqlSession.insert("userMapper.save",user);
//mybatis执行更新操作,需要提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
@Test
//修改操作
public void test3() throws IOException {
//模拟user对象
User user = new User();
user.setId(1);
user.setUsername("张三");
user.setPassword("123456");
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作
sqlSession.update("userMapper.update",user);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
@Test
//删除操作
public void test4() throws IOException {
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作
sqlSession.delete("userMapper.delete",7);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
configuration 配置
properties 属性
settings 设置
typeAliases 类型别名
typeHandlers 类型处理器
objectFactory 对象工厂
plugins 插件
environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
databaseIdProvider 数据库厂商标识
mappers 映射器
数据库环境的配置,支持多环境配置。
其中,事务管理器(transactionManager)类型有两种:
其中,数据源(dateSource)类型有三种:
sqlMapConfig.xml:
...
...
该标签的作用是加载映射的,加载方式有如下几种:
实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件。
类型别名是为Java类型设置一个短的名字,原来的类型名称配置如下:
配置typeAliases,为com.domain.User定义别名为user
mybatis框架已经为我们设置好了一些常用的类型的别名。
别名 | 数据类型 |
---|---|
string | String |
long | Long |
int | Integer |
double | Double |
boolean | Boolean |
... | ... |
常用API:SqlSessionFactory build(InputStream inputStream)
通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象。
String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resource.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
其中,Resource工具类,这个类在org.apache.ibatis.io包中。Resource类帮助你从类路径下、文件系统或一个web URL中加载资源文件。
SqlSessionFactory有多个方法创建SqlSession实例。常用的有如下两个:
方法 | 解释 |
---|---|
openSession() | 会默认开启一个事务,但事务不会自动提交,也就是意味着需要手动提交该事务,更新操作数据才会持久化到数据库中。 |
openSession(boolean autoCommit) | 参数为是否自动提交,如果设置为true,那么不需要手动提交事务。 |
SqlSession实例在MyBatis中是非常强大的一个类。在这里你会看到所有执行语句、提交或回滚事务和获取映射器实例的方法。
执行语句的方法主要有:
T selectOne(String statement, Object parameter);
List selectList(String statement, Object parameter);
int insert(String statement, Object parameter);
int update(String statement, Object parameter);
int delete(String statement, Object parameter);
操作事务的方法主要有:
void commit();
void rollback();
public interface UserDao {
List findAll() throws IOException;
}
这几年来注解开发越来越流行,MyBatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
-实现新增
@Insert
-实现更新
@Update
-实现删除
@Delete
-实现查询
@Select
-实现结果集封装
@Result
-可以与@Result一起使用,封装多个结果集
@Results
-实现一对一结果集封装
@One
-实现一对多结果集封装
@Many
package com.clp.domain;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
package com.clp.mapper;
import com.clp.domain.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface UserMapper {
/**
*
*
*
*
*
*
*
* @param user
*/
@Insert("insert into user values(#{id}, #{username}, #{password}, #{birthday})")
public void save(User user);
@Update("update user set username=#{username}, password=#{password} where id=#{id}")
public void update(User user);
@Delete("delete from user where id=#{id}")
public void delete(int id);
@Select("select * from user where id=#{id}")
public User findById(int id);
@Select("select * from user")
public List findAll();
}
实现复杂关系映射之前我们可以在映射文件中通过配置
注解 | 说明 |
---|---|
@Results | 代替的是标签 |
@Result | 代替了 column:数据库的列名; property:需要装配的属性名; one:需要使用的@One注解(@Result(one=@One)()); many:需要使用的@Many注解(@Result(many=@Many())) |
@One | 代替了 @One注解属性介绍: select:指定用来多表查询的sqlmapper; 使用格式:@Result(column="",property="",one=@One(select="")) |
@Many | 代替了 使用格式:@Result(property="",column="",many=@Many(select="")) |
package com.clp.domain;
import lombok.Data;
import java.util.Date;
/**
* 订单
*/
@Data
public class Order {
private int id;
private Date ordertime;
private double total;
private User user; //当前订单属于哪个用户
}
package com.clp.mapper;
import com.clp.domain.Order;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface OrderMapper {
/**
* 方式 1
* @return
*/
@Select("select *,o.id oid from orders o, user u where o.uid = u.id")
@Results({
@Result(column = "oid", property = "id"), //将oid字段封装到Order中的id属性值中
@Result(column = "ordertime", property = "ordertime"),
@Result(column = "total", property = "total"),
@Result(column = "uid", property = "user.id"),
@Result(column = "username", property = "user.username"),
@Result(column = "password", property = "user.password"),
@Result(column = "birthday", property = "user.birthday")
})
public List findAll();
// /**
// * 方式 2
// * @return
// */
// @Select("select * from orders")
// @Results({
// @Result(column = "oid", property = "id"), //将oid字段封装到Order中的id属性值中
// @Result(column = "ordertime", property = "ordertime"),
// @Result(column = "total", property = "total"),
// @Result(
// property = "user", //要封装的属性名称
// column = "uid", //根据哪个字段去查询user表的数据
// javaType = User.class, //要封装的实体类型
// //select属性,代表查询哪个接口的方法获得数据
// one = @One(select = "com.clp.mapper.UserMapper.findById")
// )
// })
// public List findAll();
}
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户。
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单。
public interface UserMapper {
/**
*
*
*
*
*
*
*
* @param user
*/
@Select("select * from user")
@Results({
@Result(id=true, column = "id", property = "id"), // id = true 代表该属性为主键
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(
property = "orderList",
column = "id",
javaType = List.class,
many = @Many(select = "com.clp.mapper.OrderMapper.findByUid")
)}
)
public List findUserAndOrderAll();
}
用户表和角色表的关系为:一个用户有多个角色,一个角色被多个用户使用。多对多查询的需求:查询用户同时查询出该用户的所有角色。
public interface RoleMapper {
@Select("select * from user_role ur, role r where ur.roleId=r.id and ur.userId=#{uid}")
public List findByUid(int uid);
}
public interface UserMapper {
/**
*
*
*
*
*
*
*
* @param user
*/
@Select("select * from user")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(
property = "roleList",
column = "id",
javaType = List.class,
many = @Many(select = "com.clp.mapper.RoleMapper.findByUid")
)
})
public List findUserAndRoleAll();
}