文章目录
- MyBatis框架
- 一、概述
- 二、环境搭建
- 1.数据库准备
- 2.创建Maven工程,依赖配置
- 3.创建实体类和dao层的接口
- 创建实体类
- dao层接口
- 4.创建MyBatis的主配置文件 SqlMapConfig.xml
- 5.创建映射配置文件 IUserDao.xml
- 6.配置日志文件
- ==注意事项==
- 三、入门
- 1.读取配置文件
- 2.创建SqlSessionFactory工厂
- 3.创建SqlSession对象
- 4.创建Dao接口的代理对象
- 5.执行dao中的方法
- 6.释放资源
- ==关键==
- 四、MyBatis的映射文件概述
- 五、设计模式分析
- 一、代码解析
- 二、流程分析
- 三、整体分析
MyBatis框架
一、概述
mybatis是一个优秀的基于ava的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement等繁杂的过程。
mybatis通过xml或注解的方式将要执行的各种 statement配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由 mybatis框架执行sq并将结果映射为java对象并返回。
采用ORM思想解决了实体和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc api底层访问细节,使我们不用与 jdbc api打交道,就可以完成对数据库的持久化操作。
补充:
- 什么是ORM?
- Object Relation Mapping,对象关系映射。对象指的是Java对象,关系指的是数据库中的关系模型,对象关系映射,指的就是在Java对象和数据库的关系模型之间建立一种对应关系,比如用一个Java的Student类,去对应数据库中的一张student表,类中的属性和表中的列一一对应。Student类就对应student表,一个Student对象就对应student表中的一行数据
- 为什么mybatis是半自动的ORM框架?
- 用mybatis进行开发,需要手动编写SQL语句。而全自动的ORM框架,如hibernate,则不需要编写SQL语句。用hibernate开发,只需要定义好ORM映射关系,就可以直接进行CRUD操作了。由于mybatis需要手写SQL语句,所以它有较高的灵活性,可以根据需要,自由地对SQL进行定制,也因为要手写SQL,当要切换数据库时,SQL语句可能就要重写,因为不同的数据库有不同的方言(Dialect),所以mybatis的数据库无关性低。虽然mybatis需要手写SQL,但相比JDBC,它提供了输入映射和输出映射,可以很方便地进行SQL参数设置,以及结果集封装。并且还提供了关联查询和动态SQL等功能,极大地提升了开发的效率。并且它的学习成本也比hibernate低很多。
参考:mybatis看这一篇就够了,简单全面一发入魂
- 什么是CRUD?
- CRUD是指在做计算处理时的
增加(Create)
、读取查询(Retrieve)
、更新(Update)
和删除(Delete)
几个单词的首字母简写。主要被用在描述软件系统中DataBase或者持久层的基本操作功能。
- 数据库CRUD操作
- 一、删除表
drop table 表名称 - 二、修改表
alter table 表名称 add 列名 数据类型(add表示添加一列)
alter table 表名称 drop column 列名称(column表示列 drop表示删除) - 三、删除数据库
drop database 数据库 - 四、CRUD操作(create 添加数据read读取数据 update 修改数据delete删除数据)
- 1、添加数据(create)
a: insert into + nation values('n002 ','回族 ‘) 加单引号是转为字符串,英文的
b: insert into nation values(‘n003’,’ ') 只添加一列后面的是空给所有的添加可以用
c: insert into nation(code,) values(‘n004’) 给某一列添加可以用
d:给多列添加insert into nation(code,name) values(‘n004’,‘维吾尔族’)
e: 专门添加自增长列的 insert into 表名 values(‘p001’,‘p006’) 自增长列不用管,直接写第二列 - 2、删除数据(delete)
delete from +表名称–删除表中所有内容
delete from +表名称 where ids=5 (删除此行)—where后面跟一个条件 - 3、修改数据(uodate)
update +表名称 set +列名称=’ 'set(设置)—修改所有的内容这一列的
update +表名称 set +列名称='p006 ’ where ids=6
update +表名称 set +列名称='p006 ',列名称=‘p002’ where ids=6-----用逗号隔开可以修改多列
整数型(int)的不需要加单引号 0 (false)1(true) - 4、查询数据(10种)
a1:简单查询
select * from 表名称 ——查询表中所有数据 代表所有列
select code,name from 表名称——查询指定列数据
select code as’代号’,name as’姓名’ from 表名称——给列指定别名
a2:条件查询
select * from 表名 where code=’ ’ 查这一行
select * from 表名 where sex=‘true’ and nation=’ ’ 表示并列,–多条件并的关系
select * from 表 名 where sex=‘true’ or nation=’ ’ --多条件或的关系
a3:范围查询
select * from 表名 where 列名>40 and 列名<50
select * from 表名 where 列名 between 40 and 50 --专用于范围查询
a4:离散查询
select * from 表名 where 列名 in (’ ‘,’ ‘,’ ‘)
select * from 表名 where 列名 not in (’ ‘,’ ‘,’ ') 反选,不在里面的
a5:模糊查询
select * from 表名 where 列名 like ‘%宝马%’——查包含宝马的
select * from 表名 where 列名 like ‘宝马%’——查以宝马开头的
select * from 表名 where 列名 like ‘%宝马’——查以宝马结尾的
select * from 表名 where 列名 like ‘宝马’——查等于宝马的
select * from 表名 where 列名 like ‘_ _E’——查第三个是E的
% 代表是任意多个字符
_ 下划线 代表是一个字符
a6:排序查询
select * from 表名 order by 列名——默认升序排序
select * from 表名 order by 列名 desc——降序排列
select * from 表名 order by 列名 desc, 列名 asc——多个条件排序 , 前面是主条件 后面是次要条件
desc 降序 ,asc 升序, order by 排序 根据哪一列排序
a7:分页查询
select top 5 * from 表名——查询前5条数据
select top 5 * from 表名 where code not in (select top 5 code from car)
a8:去重查询(去掉重复的)
select distinct 列名 from
a9:分组查询
select Brand from 表名 group by Brand having count()>2
group by having ——表示根据一列分组 ,count()>2——每一组的数量
a10:聚合函数(统计查询)
select count () from 表名——查询所有数据条数(每一列的)
select count (列名主键) from 表名——查询这列的所有数据条数(执行快)
select sum (列名) from 表名——求和
select avg (列名) from 表名——求平均值
select max (列名) from 表名——求最大值
select min (列名) from 表名——求最小值
参考:什么是CRUD? CRUD的操作
返回頂部
二、环境搭建
1.数据库准备
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` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
// 插入数据
insert into `user`(`id`,`username`,`birthday`,`sex`,`address`)
values (41,'老王','2018-02-27 17:47:08','男','北京'),
(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),
(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),
(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),
(46,'老王','2018-03-07 17:37:26','男','北京'),
(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正');
返回頂部
2.创建Maven工程,依赖配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MyBatis</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 打包方式 -->
<packaging>jar</packaging>
<dependencies>
<!-- MyBatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- 日志依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 单元测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
返回頂部
3.创建实体类和dao层的接口
创建实体类
package com.zyx.core.day1;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
// 数据库表字段
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// toString()
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
// set、get方法集
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
dao层接口
package com.zyx.core.day1.dao;
import com.zyx.core.day1.domain.User;
import java.util.List;
/**
* 用户持久层接口
*/
public interface IUserDao {
/**
* 查询所有
* @return
*/
List<User> findAll();
}
返回頂部
4.创建MyBatis的主配置文件 SqlMapConfig.xml
- 在resource目录下创建SqlMapConfig.xml主配置文件~
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- MyBatis的主配置文件 -->
<configuration>
<!--配置环境-->
<environments default="mysql">
<!-- 配置mysql的环境 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源 —— 连接池 -->
<dataSource type="POOLED">
<!-- 配置数据连接信息 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<mapper resource="com/zyx/core/day1/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
返回頂部
5.创建映射配置文件 IUserDao.xml
- 在resource目录下创建映射配置文件,注意和主配置文件中的路径保持一致!!!
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyx.core.day1.dao.IUserDao">
<!-- 配置查询所有 -->
<!-- id写方法名 resultType写结果映射的实体类 -->
<select id="findAll" resultType="com.zyx.core.day1.somain.User">
select * from user;
</select>
</mapper>
返回頂部
6.配置日志文件
- 在resource目录下创建log4j.properties日志配置文件
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=G:\\Projects\\Log\\mybatis.log # 注意本地路径的存在性!!!
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
返回頂部
注意事项
- 第一个: 创建IUserDao.xml和 IUserDao.java时名称是为了和我们之前的知识保持一致
在 Mybatis中它把持久层的操作接口名称和映射文件也叫做: Mapper
所以: IUserDao和 IUserMapper是一样的 - 第二个:在idea中创建目录的时候,它和包是不一样的
- 包在创建时:com. itheima.dao它是三级结构
- 目录在创建时:com. itheima.dao是一级目录
- 第三个: mybatis的映射配置文件位置必须和dao接口的包结构相同
- 第四个:映射配置文件的mapper的namespace标签属性的取值必须是dao接口的全限定类名
- 第五个:映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
当按照3、4、5要求执行后,我们在开发过程中就不需要再写dao层的实现类,MyBatis会自动帮助我们去执行相应的数据库操作,大大提高了开发效率!
返回頂部
三、入门
1.读取配置文件
2.创建SqlSessionFactory工厂
3.创建SqlSession对象
4.创建Dao接口的代理对象
5.执行dao中的方法
6.释放资源
package com.zyx.core.Test;
import com.zyx.core.day1.dao.IUserDao;
import com.zyx.core.day1.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 java.io.InputStream;
import java.util.List;
public class MyBatisTest {
public static void main(String[] args) throws Exception{
// 1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
// 4.使用SqlSession对象创建Dao接口的代理对象
IUserDao iUserDao = session.getMapper(IUserDao.class);
// 5.使用代理对象执行方法
List<User> list = iUserDao.findAll();
for (User u:list){
System.out.println(u);
}
// 6.释放资源
session.close();
in.close();
}
}
关键
报错:Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement ‘com.zyx.core.day1.dao.IUserDao.findAll’. It’s likely that neither a Result Type nor a Result Map was specified.(错误锦集)
这个错主要是因为,我们只通过整个流程使用MyBatis去进行数据库的操作,但是并没有指定查到结果后的返回类型。在代码中我们是要查询所有,同时创建了实体类,所以这里我们最终的返回类型就应该是实体类类型,但是在程序中并没有指明;所以,要通过resultType
属性设置返回类型的全路径类。
最终运行结果:
返回頂部
四、MyBatis的映射文件概述
返回頂部
五、设计模式分析
一、代码解析
二、流程分析
三、整体分析
返回頂部