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是否正确
@Testpublic 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查询的测试
//查询@Testpublic 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类中完成添加用户的测试
//添加@Testpublic 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类中完成修改的测试
//修改@Testpublic 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类中完成删除的测试
//删除@Testpublic 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查询@Testpublic 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.单元测试类中测试方法
@Testpublic 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.单元测试类中测试方法
@Testpublic 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.单元测试类中测试方法
@Testpublic 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.单元测试类中测试方法
@Testpublic 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.单元测试类中测试方法
@Testpublic 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语句——在数据库中执行下