1. what
MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射实体类型、接口、Java POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录。
持久层:就是和数据库交互的一层——dao层,用于操作数据表记录的
框架:就是一个半成品,我们只需要引入该框架,加入自己的代码就可以完成相应的业务功能
持久层框架:MyBatis hirenate jpa等
ORM框架:Object Relative Mapping(对象关系映射)。表——实体类;一条记录——实体类的对象
表的字段——java实体类的属性
2. why
思考:JDBC操作数据库时代码量很大。
比如:查询时:需要手动给占位符赋值,需要手动把查询的结果封装到实体类中,需要手动关闭资源。
使用MyBatis可以帮你完成上面的操作。
3.快速搭建
1. 创建一个maven的java工程
File——New——New Project——Maven
Name : mybatis01
GroupId : com.zmq
2.引入MyBatis和mysql的依赖
<dependencies>
<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!--mysql的依赖-->
<dependency>
<groupId>repMaven.mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!--lombok的依赖-->
<dependency>
<groupId>repMaven.org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<!--junit依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
引入的依赖有顺序,否则会报红,mybatis依赖需要在最前面
3.创建实体类,为了映射表中的记录
4.mybatis的配置文件——配置数据源信息
不需要背
<?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">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!--name是固定的 value根据需要配置为自己的内容-->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/zmq?serverTimezone=Asia/Shanghai" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
</configuration>
- 修改为自己的数据库名称——
- 修改为自己的数据库用户名
- 修改为自己的数据库密码
5.mybatis的映射文件——编写自己的sql语句
在resources下创建mapper目录,在该目录下创建对应的映射文件——UserMapper.xml
<?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">
<!--namespace:命名空间
-->
<mapper namespace="aaa">
<!--select:用于编写查询的sql语句
id:唯一标签
resultType:结果类型 sql执行完毕后返回对应的java实体类的类型 把查询的结果自动封装到该实体类的属性上
-->
<select id="getById" resultType="com.zmq.entity.User">
select * from user where id=#{id}
</select>
</mapper>
6.将映射文件放入配置文件中
未来我们读取的只有配置文件
<!--引入映射文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
7.测试mybatis是否正确
@Test
public void test01() throws Exception{
//1. 读取mybatis的配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2. 获取SqlSessionFactory对象---创建sqlSession的对象
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3. 获取SqlSession对象---表示java与数据库的一次连接
SqlSession sqlSession=sessionFactory.openSession();
//4. 执行sql语句
//String statement, 执行映射文件中的哪个标签
// Object parameter 需要的参数值
User user= sqlSession.selectOne("aaa.getById",1);
System.out.println(user);
}
4. mybaits完成CRUD
4 .1 根据id查询
1.UserMapper.xml配置文件中写根据id查询的sql语句
<select id="getById" resultType="com.zmq.entity.User">
select * from user where id=#{id}
</select>
- select:用于编写查询的sql语句
- id:唯一标签
- resultType:结果类型 sql执行完毕后返回对应的java实体类的类型 把查询的结果自动封装到该实体类的属性上
- #{名称},相当于占位符
2.UserTest类中完成根据id查询的测试
//查询
@Test
public void test01() throws Exception{
//1.读取mybatis的配置文件按
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2.获取SqlSessionFactory对象
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.
SqlSession sqlSession = sessionFactory.openSession();
//4.
User user = sqlSession.selectOne("UserMapper.getById",9);
System.out.println(user);
}
前三个步骤是固定的
首先:读取mybatis的配置文件,即mybatis.xml文件
获取SqlSessionFactory对象,创建sqlSession的对象
new SqlSessionFactoryBuilder().build(resourceAsStream)
- 获取SqlSession对象,表示java与数据库的一次连接
sessionFactory.openSession()
- 执行sql语句,有两个参数:
String statement, 执行映射文件中的哪个标签
Object parameter 需要的参数值
- 执行sql语句时,调用selectOne方法
4.2 添加
1.UserMapper.xml配置文件中写添加用户的sql语句
<!--增加-->
<insert id="add">
insert into user values (null,#{u_name},#{password})
</insert>
- insert:用于编写添加的sql语句
- #{名称},必须和实体类属性名一致
- 实体类中id为Integer类型,不然后续测试时会报错
- 不需要resultType
2.UserTest类中完成添加用户的测试
//添加
@Test
public void testAdd() throws Exception{
//1.读取mybatis的配置文件按
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2.获取SqlSessionFactory对象——创建swssionFactory对象
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取sqlSession对象——java与数据库的一次连接
SqlSession sqlSession = sessionFactory.openSession();
//4.创建一个user对象,传入添加用户的信息
User user=new User(null,"汪芜","123456");
//5.执行sql语句
int row = sqlSession.insert("UserMapper.add", user);
//将数据提交到数据库中
sqlSession.commit();
System.out.println(row);
}
增删改与查询的不同点:
- 因为执行sql语句时,传入的是一个对象,而不能一次传递多个值,所以需要创建一个user对象,将要传递的值放入到user对象中,再在执行sql语句中传递符合要求的user对象
User user=new User(null,“汪芜”,“123456”);
int row = sqlSession.insert(“UserMapper.add”, user);
- 在执行完sql语句后,必须要提交到数据库中
sqlSession.commit();
- 执行时调用insert方法
4.3 修改
1.UserMapper.xml配置文件中写修改的sql语句
<!--修改-->
<update id="update">
update user set u_name=#{name},password=#{password} where id=#{id}
</update>
- update:用于编写修改的sql语句
- #{名称}:必须和实体类属性名一致
2.UserTest类中完成修改的测试
//修改
@Test
public void testUpdate() throws Exception {
//1.读取mybatis的配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2.获取SqlSessionFactory对象---创建sqlSession的对象
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取SqlSession对象---表示java与数据库的一次连接
SqlSession sqlSession = sessionFactory.openSession();
//4.创建一个user对象
User user=new User(12,"lay","1007");
//5.执行sql语句
// String statement, 执行映射文件中的哪个标签
// Object parameter 需要的参数值
int row = sqlSession.update("UserMapper.update", user);
//6.提交
sqlSession.commit();
System.out.println(row);
}
- 和增加一样,需要创建一个user对象用来传递数据
- 执行时,调用update方法
- 执行完毕后,需要提交到数据库
4.4 删除
1.UserMapper.xml配置文件中写删除的sql语句
<!--删除-->
<delete id="del">
delete from user where id=#{id}
</delete>
2.UserTest类中完成删除的测试
//删除
@Test
public void testDel() throws Exception {
//1.创建mybatis的配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2.创建SqlSessionFactory对象——创建sqlSession对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取sqlSession对象——表示java与数据库的一次连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.执行sql语句
int row = sqlSession.delete("UserMapper.del", 30);
sqlSession.commit();
System.out.println(row);
}
- 因为删除只需要传递一个id,所以不需要和增江、修改一样创建一个对象来传递值
- 同样,在执行完毕sql语句后,需要提交到数据库
5.企业开发模式
上面我们操作数据库表记录都是使用SqlSession类中的方法,而实际开发中我们习惯自己写方法,调用自己的方法传递相应的参数。但是这些方法没有方法体{},在接口中。而方法的实现交于mybatis框架完成
1.创建一个接口
public interface UserDao {
//根据id查询用户信息
public User queryById(int id);
}
2.映射文件
<?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">
<!--namespace:命名空间必须和接口名一致
-->
<mapper namespace="com.zmq.dao.UserDao">
<!--select:用于编写查询的sql语句
id:唯一标签,必须和Dao接口中的方法名一致
resultType:结果类型 sql执行完毕后返回对应的java实体类的类型 把查询的结果自动封装到该实体类的属性上
-->
<select id="getById" resultType="com.zmq.entity.User">
select * from user where id=#{id}
</select>
</mapper>
3.测试
public class UserTest {
//根据id查询
@Test
public void testGetById() throws IOException {
//1.获取mybatis的配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2.获取SqlSessionFactory对象——创建sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.获取dao接口的代理实现类
UserDao userDao=sqlSession.getMapper(UserDao.class);
//5.调用自己类中的方法
User user = userDao.getById(12);
System.out.println(user.getU_name());
}
}
4.补充@Before注解
@Before注解:是Junit中的一个注解,它用于标记一个方法,在每个测试方法执行之前都会被自动调用。 通过使用@Before注解,我们可以将一些通用的准备操作(如创建对象、初始化变量等)放置在一个方法中,以避免在每个测试方法中重复编写相同的准备代码。
@Before注解可以将测试中的一些固定步骤提取出来
UserDao userDao=null;
SqlSession sqlSession=null;
@Before
public void before() throws Exception{
//1.获取mybatis的配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
//2.获取SqlSessionFactory对象——创建sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取sqlSession对象
sqlSession = sqlSessionFactory.openSession();
//4.获取dao接口的代理实现类
userDao=sqlSession.getMapper(UserDao.class);
}
6.企业模式完成CRUD
6.0 前期准备
1.引入依赖
创建好一个mybatis的java工程后,需要在pom.xml文件中引入相关依赖
<dependencies>
<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!--mysql的依赖-->
<dependency>
<groupId>repMaven.mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!--lombok的依赖-->
<dependency>
<groupId>repMaven.org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<!--junit依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--打印日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.2</version>
</dependency>
</dependencies>
2.在resources下创建配置文件——mybatis.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">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!--name是固定的 value根据需要配置为自己的内容-->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/zmq?serverTimezone=Asia/Shanghai" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
</configuration>
3.创建相应的实体类——entity——Student
package com.zmq.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: mybatis01work
* @description: 学生表
* @author: 赵梦倩
* @create: 2024-05-20 16:42
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer id;
private String name;
private String phone;
private String email;
private String profession;
private Integer age;
}
4.创建相应的接口——dao——StudentDao
package com.zmq.dao;
import com.zmq.entity.Student;
import java.util.List;
/**
* @program: mybatis01work
* @description: 学生表的相关方法接口
* @author: 赵梦倩
* @create: 2024-05-20 16:44
**/
public interface StudentDao {
//1.根据id查询
public Student getById(int id);
//2.查询所有
public List<Student> getAll();
//添加
public int add(Student student);
//修改
public int update(Student student);
//删除
public int delete(int id);
}
5.创建mybatis的映射文件——mapper——StudentMapper.xml
<?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">
<!--namespace:命名空间
-->
<mapper namespace="com.zmq.dao.StudentDao">
</mapper>
6.在配置文件中引入映射文件
<!--引入映射文件-->
<mappers>
<mapper resource="mapper/StudentMapper.xml"/>
</mappers>
6.1 查询所有
1.映射文件【StudentMapper.xml】中写sql语句
<select id="getAll" resultType="com.zmq.entity.Student">
select * from t_student
</select>
2.单元测试类中测试方法
@Test
public void testGetAll() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
List<Student> all = studentDao.getAll();
for (Student s:all) {
System.out.println(s.getName());
}
}
6.2 根据id查询
1.映射文件【StudentMapper.xml】中写sql语句
<select id="getById" resultType="com.zmq.entity.Student">
select * from t_student where id=#{id}
</select>
2.单元测试类中测试方法
@Test
public void testGetById() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student byId = studentDao.getById(2);
System.out.println(byId.getName());
}
6.3 添加
1.映射文件【StudentMapper.xml】中写sql语句
<insert id="add" >
insert into t_student values (null,#{name},#{phone},#{email},#{profession},#{age})
</insert>
2.单元测试类中测试方法
@Test
public void testAdd() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=new Student(null,"张数","1007","110qq.com","软件工程",16);
int add = studentDao.add(student);
System.out.println(add);
sqlSession.commit();
}
6.4 修改
1.映射文件【StudentMapper.xml】中写sql语句
<update id="update">
update t_student set name=#{name},phone=#{phone},email=#{email},profession=#{profession},age=#{age} where id=#{id}
</update>
2.单元测试类中测试方法
@Test
public void testUpdate() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=new Student(25,"张数三","1007","110qq.com","软件工程",16);
int update = studentDao.update(student);
System.out.println(update);
sqlSession.commit();
}
6.5 删除
1.映射文件【StudentMapper.xml】中写sql语句
<delete id="delete">
delete from t_student where id=#{id}
</delete>
2.单元测试类中测试方法
@Test
public void testDel() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
int delete = studentDao.delete(25);
System.out.println(delete);
sqlSession.commit();
}
7. idea安装的相关插件
插件1:MyBatisX
可以用于纠错
插件2:Lombok
帮忙生成set,get,toString,构造方法——通过注解
- 引入lombok依赖
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
- 实体类中使用lombok注解
//set和get以toString方法生成
@Data
//无参构造方法
@NoArgsConstructor
//有参构造方法
@AllArgsConstructor
8.易错点
8.1 导包时
两个xml文件要打开记事本粘贴
否则会报错——创建实例错误
8.2 获取结果name为空
因为创建实体类时属性与数据库表属性不一致导致
解决:实体类属性与数据库表属性完全一致
8.3 Mapped Statements collection does not contain
两种可能:
①写错名称
②配置文件中没有引入映射文件
其他错误:
①密码账号错误
②写错sql语句——在数据库中执行下