1. 框架介绍
2. mybatis介绍
3. mybatis快速入门
4. 映射文件概述
5. mybatis原生的增删改查
6. 抽取工具类【spring可以代替】
7. 核心配置文件
8. 核心api概述
9. mybatis实现dao层
传统dao(接口+实现类)
接口dao(接口)
10. 基于接口增删改查
为什么学习框架?
简化代码,提高效率
ORM(object Relational Mapping)对象关系映射
常用ORM框架有:hibernate(全自动ORM映射)、mybatis(半自动ORM映射)、jpa
历史
简介
MyBatis官网地址:http://www.mybatis.org/mybatis-3/
需求
查询数据库user表的所有记录,封装到User对象中。
/* SQLyog Enterprise - MySQL GUI v6.03 Host - 5.0.22-community-nt : Database - mybatisdb ********************************************************************* Server version : 5.0.22-community-nt */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; CREATE DATABASE IF NOT EXISTS `mybatis_db`; USE `mybatis_db`; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; DROP TABLE IF EXISTS `orders`; CREATE TABLE `orders` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `uid` INT(11) DEFAULT NULL, `ordertime` DATETIME DEFAULT NULL, `money` DOUBLE DEFAULT NULL, PRIMARY KEY (`id`), KEY `uid` (`uid`), CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`) ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; /*Data for the table `orders` */ INSERT INTO `orders`(`id`,`uid`,`ordertime`,`money`) VALUES (1,41,'2019-05-20 02:58:02',999.5),(2,45,'2019-02-14 07:58:00',1399),(3,41,'2019-06-01 21:00:02',1666); /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(32) NOT NULL COMMENT '用户名称', `birthday` DATETIME DEFAULT NULL COMMENT '生日', `sex` VARCHAR(10) DEFAULT NULL COMMENT '性别', `address` VARCHAR(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; /*Data for the table `user` */ INSERT INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES (41,'老王','2019-05-27 17:47:08','男','北京'),(42,'王小二','2019-03-02 15:09:37','女','北京金燕龙'),(43,'老李','2019-03-04 11:34:34','女','北京修正'),(45,'传智播客','2019-03-04 12:04:06','男','北京金燕龙'),(46,'王小二','2018-09-07 17:37:26','男','北京TBD'),(48,'小马宝莉','2019-03-08 11:44:00','女','北京修正'); DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` INT(11) NOT NULL COMMENT '编号', `role_name` VARCHAR(30) DEFAULT NULL COMMENT '角色名称', `role_desc` VARCHAR(60) DEFAULT NULL COMMENT '角色描述', PRIMARY KEY (`ID`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; /*Data for the table `role` */ INSERT INTO `role`(`ID`,`role_name`,`role_desc`) VALUES (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校'); /*Table structure for table `user_role` */ DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `uid` INT(11) NOT NULL COMMENT '用户编号', `rid` INT(11) NOT NULL COMMENT '角色编号', PRIMARY KEY (`uid`,`rid`), KEY `FK_Reference_10` (`rid`), CONSTRAINT `FK_Reference_10` FOREIGN KEY (`rid`) REFERENCES `role` (`id`), CONSTRAINT `FK_Reference_9` FOREIGN KEY (`uid`) REFERENCES `user` (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; /*Data for the table `user_role` */ INSERT INTO `user_role`(`uid`,`rid`) VALUES (41,1),(45,1),(41,2); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 省略 getter、setter、toString
}
<mapper namespace="UserMapper">
<select id="findAll" resultType="com.mybatis.pojo.User">
select * from user
select>
mapper>
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver">property>
<property name="url" value="jdbc:mysql://192.168.43.212:3306/mybatis_db">property>
<property name="username" value="root">property>
<property name="password" value="root">property>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/mybatis/mapper/UserMapper.xml">mapper>
mappers>
configuration>
// 查询所有
@Test
public void testFindAll() throws Exception {
// 1.加载核心配置文件(SqlMapConfig.xml)
// 2.构建SqlSessionFactory工厂对象
// 3.通过工厂创建SqlSession会话对象(Connection)
// 4.执行sql语句
// 5.释放资源
}
public class UserMapperTest {
// 查询所有
@Test
public void testFindAll() throws Exception {
// 1.加载核心配置文件(SqlMapConfig.xml)
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.构建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// 3.通过工厂创建SqlSession会话对象(Connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.执行sql语句 (命名空间+id)
List<User> list = sqlSession.selectList("UserMapper.findAll");
for (User user : list) {
System.out.println(user);
}
// 5.释放资源
sqlSession.close();
}
}
<insert id="save" parameterType="com.mybatis.pojo.User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
insert>
// 新增
@Test
public void testSave() throws IOException {
//1.加载配置文件
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.构建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.通过工厂创建SqlSession会话对象(Connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.执行sql语句(
User user = new User();
user.setUsername("jack");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("北京");
int i = sqlSession.insert("UserMapper.save", user);
if (i>0) {
System.out.println("添加成功");
}
// 注意:mybatis需要手动提交事务(DML),若不手动提交,则会回滚事务
sqlSession.commit();
//5.释放资源
sqlSession.close();
}
- 插入语句insert标签
- 在映射文件中使用parameterType属性指定插入数据类型
- sql语句#{实体属性名} 表示?占位符
- 我们插入操作API是 sqlSession.insert("命名空间.id", 实体对象);
- DML类型语句mybatis需要手动提交事务 sqlSession.commit();
<update id="update" parameterType="com.mybatis.pojo.User">
update user set username = #{username},birthday = #{birthday},sex = #{sex},
address = #{address} where id = #{id}
update>
// 修改
@Test
public void testUpdate()throws Exception{
// 1.加载核心配置文件(SqlMapConfig.xml)
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.构建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// 3.通过工厂创建SqlSession会话对象(Connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.执行sql语句
User user = new User();
user.setId(50);
user.setUsername("lucy");
user.setBirthday(new Date());
user.setSex("女");
user.setAddress("上海");
sqlSession.update("UserMapper.update", user);
// DML语句,手动提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
- 修改操作使用update标签
- 修改操作的API使用的 sqlSession.update("命名空间.id", 实体对象);
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id}
delete>
// 删除
@Test
public void testDelete() throws Exception {
// 1.加载核心配置文件(SqlMapConfig.xml)
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.构建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// 3.通过工厂创建SqlSession会话对象(Connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.执行sql语句
sqlSession.delete("UserMapper.delete", 50);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
- 删除语句使用delete标签
- 如果parameterType是引用数据类型 #{实体属性名}
- 如果parameterType是简单数据类型 #{键名知意}
- 删除操作API sqlSession.delete("命名空间.id", Object);
* 查询所有
代码:
List list = sqlSession.selectList("UserMapper.findAll");
映射文件:
* 新增
代码:
sqlSession.insert("UserMapper.save", user);
映射文件:
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
* 修改
代码:
sqlSession.update("UserMapper.update", user);
映射文件:
update user set username = #{username},birthday = #{birthday},sex = #{sex},
address = #{address} where id = #{id}
* 删除
代码:
sqlSession.delete("UserMapper.delete", 50);
映射文件:
delete from user where id = #{id}
将mybatis测试代码的通用部分进行抽取,简化书写提高效率
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
// 在静态代码块中(1.加载核心配置文件 2.构建工厂对象)
static {
try {
// 1.加载核心配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.构建工厂对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
// 提供获取sqlSession的静态方法
public static SqlSession openSession() {
return sqlSessionFactory.openSession();
}
// 提供提交事务和释放资源方法
public static void close(SqlSession sqlSession){
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
}
需求
根据指定id,查询User对象
编写映射文件UserMapper.xml
<select id="findById" parameterType="Integer" resultType="com.mybatis.pojo.User">
select * from user where id=#{id}
select>
编写测试代码
//根据id查询
@Test
public void testFindById(){
//1.获取根据工具类sqlSession
SqlSession sqlSession = MyBatisUtils.openSession();
//2.执行sql
User user = sqlSession.selectOne("UserMapper.findById",41);
System.out.println(user);
//3.关闭sqlsession
MyBatisUtils.close(sqlSession);
}
1. 其中,事务管理器(transactionManager)类型有两种:
* JDBC:
这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
* MANAGED:
这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。
例如:mybatis与spring整合后,事务交给spring容器管理。
2. 其中,数据源(dataSource)常用类型有二种:
* UNPOOLED:
这个数据源的实现只是每次被请求时打开和关闭连接。
* POOLED:
这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
加载外置的properties配置文件
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.43.212:3306/mybatis_db
jdbc.username=root
jdbc.password=root
mybatis框架内置了一些java类型的别名
1. 加载指定的src目录下的映射文件,
2. 加载指定接口的全限定名,例如:【注解开发时使用....】
3. 加载并扫描指定包下所有的接口,例如:【基于接口扫描方式加载】
properties标签:该标签可以加载外部的properties文件
<properties resource="jdbc.properties">properties>
typeAliases标签:设置类型别名
<typeAlias type="com.mybatis.pojo.User" alias="user">typeAlias>
environments标签:数据源环境配置
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
dataSource>
environment>
environments>
mappers标签:加载映射配置
<mapper resource="com/mybatis/mapper/UserMapper.xml">mapper>
// 加载mybatis的核心配置文件,获取io流
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// DML类型语句,需要手动提交事务
SqlSession openSession();
// 设置是否开启自动提交事务的会话对象,如果设置true,自动提交【了解】
SqlSession openSession(boolean autoCommit);
执行语句的方法主要有
<T> T selectOne(String statement, Object parameter);
<E> List<E> 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 roolback();
public interface UserMapper {
// 查询所有
public List<User> findAll();
}
public class UserMapperImpl implements UserMapper {
@Override
public List<User> findAll() {
try {
// 1.加载核心配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.构建工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
// 3.创建会话
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.执行sql
List<User> list = sqlSession.selectList("UserMapper.findAll");
// 5.释放资源
sqlSession.close();
return list;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
<mapper namespace="UserMapper">
<select id="findAll" resultType="User">
select * from user
select>
mapper>
public class UserMapperTest {
// 模拟service
@Test
public void test01() throws Exception {
// 调用dao层代码
UserMapper userMapper = new UserMapperImpl();
List<User> list = userMapper.findAll();
System.out.println(list);
}
}
1. 编写UserMapper接口
2. 编写UserMapperImpl实现类
3. 编写UserMapper.xml映射
UserMapper接口
public interface UserMapper {
//查询所有
public List<User> findAll() throws IOException;
//新增
public int save(User user);
//修改
public int update(User user);
//删除
public int delete(Integer id);
//根据id查找
public User findById(Integer id);
}
UserMapper
public class UserMapperImpl implements UserMapper {
@Override
public List<User> findAll() {
try {
//1.加载核心配置文件
InputStream in = null;
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建会话
SqlSession sqlSession = sessionFactory.openSession();
//4.执行sql
List<User> list = sqlSession.selectList("UserMapper.findAll");
//5.释放资源
sqlSession.close();
return list;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public int save(User user) {
try {
//1.加载核心配置文件
InputStream in = null;
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建会话
SqlSession sqlSession = sessionFactory.openSession();
//4.执行sql
int i = sqlSession.insert("UserMapper.save", user);
//5.提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
return i;
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int update(User user) {
try {
//1.加载核心配置文件
InputStream in = null;
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建会话
SqlSession sqlSession = sessionFactory.openSession();
//4.执行sql
int i = sqlSession.insert("UserMapper.update", user);
//5.提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
return i;
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int delete(Integer id) {
try {
//1.加载核心配置文件
InputStream in = null;
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建会话
SqlSession sqlSession = sessionFactory.openSession();
//4.执行sql
int i = sqlSession.delete("UserMapper.delete", id);
//5.提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
return i;
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
@Override
public User findById(Integer id) {
try {
//1.加载核心配置文件
InputStream in = null;
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建会话
SqlSession sqlSession = sessionFactory.openSession();
//4.执行sql
User user = sqlSession.selectOne("UserMapper.findById", id);
//5.提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
return user;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
UserMapper.xml
<mapper namespace="UserMapper">
<select id="findAll" resultType="User">
select * from user
select>
<insert id="save" parameterType="User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
insert>
<update id="update" parameterType="User">
update user set username = #{username},birthday = #{birthday},sex = #{sex},
address = #{address} where id = #{id}
update>
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id}
delete>
<select id="findById" parameterType="Integer" resultType="User">
select * from user where id=#{id}
select>
mapper>
采用 Mybatis 的基于接口代理方式实现 持久层 的开发,基于接口代理方式的开发只需要:编写接口和映射文件,Mybatis 框架会为我们动态生成实现类的对象。
接口开发规范
1. Mapper映射文件的namespace与Mapper接口全限定名一致
2. Mapper接口的方法名与id的属性名一致
3. 方法的参数类型与parameterType属性类型一致
4. 方法的返回值类型与resultType属性类型一致
5. 映射文件需要与接口在同一个包下,文件名和接口名相同:扫描包,加载所有的映射文件
在这里插入图片描述
public interface UserMapper {
// 查询所有
public List<User> findAll();
}
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findAll" resultType="User">
select * from user
select>
mapper>
public class UserMapperTest {
// 模拟service测试
@Test
public void test01() throws Exception {
// 需要通过mybatis帮你根据接口规范创建实现类
SqlSession sqlSession = MyBatisUtils.openSession();
// 创建代理对象(实现类)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行sql
List<User> list = userMapper.findAll();
System.out.println(list);
// 关闭会话
MyBatisUtils.close(sqlSession);
}
}
使用了JDK动态代理技术,帮我们创建了接口的实现类,底层还是执行SqlSession.insert() | update()
public interface UserMapper {
//查询所有
public List<User> findAll() throws IOException;
//新增
public int save(User user);
//修改
public int update(User user);
//删除
public int delete(Integer id);
//根据id查找
public User findById(Integer id);
}
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findAll" resultType="User">
select * from user
select>
<insert id="save" parameterType="User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
insert>
<update id="update" parameterType="User">
update user set username = #{username},birthday = #{birthday},sex = #{sex},
address = #{address} where id = #{id}
update>
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id}
delete>
<select id="findById" parameterType="Integer" resultType="User">
select * from user where id=#{id}
select>
mapper>
public class UserMapperTest {
//查询所有
@Test
public void testFindAll() throws IOException {
//需要通过mybatis,根据接口规范创建实现类
SqlSession sqlSession = MyBatisUtils.openSession();
//创建代理对象(实现类)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//执行sql
List<User> list = userMapper.findAll();
System.out.println(list);
//关闭会话
}
//新增
@Test
public void testSave() throws IOException {
//需要通过mybatis,根据接口规范创建实现类
SqlSession sqlSession = MyBatisUtils.openSession();
// 创建代理对象(实现类)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("杨幂");
user.setSex("女");
user.setAddress("北京");
user.setBirthday(new Date());
userMapper.save(user);
//关闭会话
MyBatisUtils.close(sqlSession);
}
// 修改
@Test
public void testUpdate() throws Exception {
//需要通过mybatis,根据接口规范创建实现类
SqlSession sqlSession = MyBatisUtils.openSession();
// 创建代理对象(实现类)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("赵丽颖");
user.setSex("女");
user.setAddress("东北");
user.setBirthday(new Date());
user.setId(54);
userMapper.update(user);
//关闭会话
MyBatisUtils.close(sqlSession);
}
// 删除
@Test
public void testDelete() throws Exception {
//需要通过mybatis,根据接口规范创建实现类
SqlSession sqlSession = MyBatisUtils.openSession();
// 创建代理对象(实现类)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//执行语句
userMapper.delete(54);
//关闭会话
MyBatisUtils.close(sqlSession);
}
//根据id查询
@Test
public void testFindById(){
//需要通过mybatis,根据接口规范创建实现类
SqlSession sqlSession = MyBatisUtils.openSession();
// 创建代理对象(实现类)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//执行语句
User user = userMapper.findById(45);
System.out.println(user);
//关闭会话
MyBatisUtils.close(sqlSession);
}
}