文章目录
一、简介
先上理论,不想看的小伙伴可以粗略阅读或者直接跳到干货实操部分
1.1什么是Mybatis
Mybatis是一款优秀的持久层(DAO)框架,它自定义SQL、存储过程以及高级映射。Mybatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。Mybatis可以通过简单的xml或注解来配置和映射原始类型、接口和JavaPojo(Plain Old Java Objects,普通老式Java对象)为数据库中的记录。
回顾一下传统的JDBC连接数据库
① 定义数据库连接信息:驱动、url、用户名、密码
② 加载驱动
③ 获得和数据的连接:Connection对象
④ 生成操作数据库的对象:Statement或者PreStatement(可以使用他们执行SQL语句)
⑤ 假如执行查询,得到的结果Resultset对象,逐个字段获取,然后再封装
⑥ 关闭资源
相信很多小伙伴在初学SQL连接和CRUD的时候,饱受折磨,需要写很多代码,而mybatis就很好的解决了这些繁琐的问题,通过简单的xml即可完成这些复杂的操作
1.2持久化
数据的持久化
- 持久化就是将程序中的数据在持久状态和瞬时状态的过程,简单理解就是把内存中的数据存放到硬盘上
- 内存:断电即失
- 数据库:持久化保存,数据库中的数据是保存在硬盘上
为什么要使用持久化?
- 有些数据不能丢失,需要永久保存
- 内存比较贵,而且容量比较小
什么是持久层(DAO)?
完成持久化工作的代码块
1.3为什么使用Mybatis
- 方便我们将数据存放到数据库中
- 传统的JDBC代码有一定的弊端,代码复杂,硬编码mybatis简化了JDBC的代码
- 优点
简单易学
灵活
sql语句和代码进行了分离,提高维护性
提供映射标签,支持对象与数据库字段的映射关系
提供xml标签,支持编写动态SQL
二、入门程序(实操)
前言:
从这里开始就是实操部分,尽量跟着敲,理解每一行代码
我的编程工具是IDEA2020,必须先装maven,没装maven可以先看这篇文章
《Maven安装与配置(详细版+idea集成)》
思路:
搭建环境–>导入依赖–>编写代码–>测试
2.1准备数据
创建数据库mybatis,并且创建一个users表
CREATE DATABASE mybatis;
USE mybatis;
CREATE TABLE `user` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `user` VALUES (1, 'tom', '123456');
INSERT INTO `user` VALUES (2, '张三', '123456');
INSERT INTO `user` VALUES (3, '李莉', '123456');
INSERT INTO `user` VALUES (4, 'jack', '123456');
2.2搭建环境
① 创建一个maven工程
② 引入mybatis相关依赖
除了本次实操使用的两个依赖外,后续进阶学习的依赖可以在这个网址查询https://mvnrepository.com/
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--Mysql数据库驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
</dependencies>
③ 完善目录结构
在example目录下新建dao和pojo两个包
dao是持久层(接口层),pojo是实体类
④ 创建一个mybatis的核心配置文件在src/main/resources目录下
mybatis_config.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"> <!--数据源-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/> <!--绑定映射文件-->
</mappers>
</configuration>
2.4编写代码实现功能
① 创建实体类
在pojo目录下创建User类
package org.example.pojo;
public class User {
private Integer id;
private String name;
private String pwd;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
② 创建对应接口
在dao目录下创建UserMapper接口
public interface UserMapper {
/**
\* 查询所有的用户 * @return
*/
List<User> findAll();
}
③ 在resources目录下创建,一个mapper文件夹,在下面编写映射文件UsersMapper.xml和接口对应,调用UserMapper里面的findAll()方法等于执行映射文件内对应id的sql语句
<?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="org.example.dao.UserMapper">
<select id="findAll" resultType="org.example.pojo.User">
select * from user
</select>
</mapper>
2.5测试
编写测试类
@Test
public void testFindAll() throws IOException {
// 获取SqlSession对象
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
// 获取接口对象
UserMapper mapper = session.getMapper(UserMapper.class); // 调用findAll方法查询数据库
List<User> users = mapper.findAll();
for (User user : users) {
System.out.println(user);
}
// 释放资源
session.close();
}
出现以下结果就是成功
三、进阶程序
说明:以下程序主要是增删改查操作,旨在提高熟练度,加深理解。因为有前面的铺垫,后面就不一一截图,对应好文件名,代码都有详细的注释
3.1mybatis_config.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属性-->
<environment id="development"> <!--配置环境-->
<!--JDBC的事务处理方式:成功就提交,失败就回滚-->
<transactionManager type="JDBC"/> <!--事务的方式-->
<dataSource type="POOLED"> <!--数据源:数据池的管理方式-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/> <!--驱动-->
<!--
mysql8.0以下的版本,驱动:com.mysql.jdbc.Driver
mysql8.0以上的版本,驱动:com.mysql.cj.jdbc.Driver
-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <!--连接数据库的URL(统一资源定位器)-->
<!--localhost:本机IP,如果不是本机,输入对应IP地址-->
<property name="username" value="root"/> <!--账户-->
<property name="password" value="123456"/> <!--密码-->
</dataSource>
</environment>
</environments>
<!--指定映射文件的位置-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/> <!--绑定映射文件-->
</mappers>
</configuration>
3.2pojo:User.java
代码相较于前文没有改变,只是增加了更为详细的注释
package org.example.pojo;
//数据库中表(table)的记录是没有办法在Java中直接体现的,
//所以把数据库表对应成一个类,元素互相对应(映射),
//从而使用Java对象去体现数据库的操作
public class User {
//封装
private int id;
private String name;
private String pwd;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
3.3dao:UserMapper.java
新增了条件查询、新增用户、删除用户以及修改用户等方法。
package org.example.dao;
import org.apache.ibatis.annotations.Param;
import org.example.pojo.User;
import java.util.List;
public interface UserMapper {
//查询用户表的抽象方法
//用集合一一映射接收,集合内放一个个User
List<User> findAll();
//---------------------------新增接口
//单条件
//根据姓名查询用户
List<User> findUserByName(String name);
//根据id查询用户
List<User> findUsersById(int id);
//多条件
//根据id和姓名查询用户
//无@Param注解的
//List<Users> findUserByIdAndName(int id,String name);
//在参数前加上@Param("value"注解,参数就可以以#{value}的形式被映射文件获取)
List<User> findUserByIdAndName(@Param("id") int id, @Param("name") String name);
//如果传入的参数:条件比较多的情况,可以直接把条件封装在对象里
//通过传入对象作为条件s
List<User> findUserByUsers(User user);
//模糊查询:查询姓张的用户
List<User> findUserNameLike(String namestr);
//新增用户,会返回一个整数,代表对数据库影响了多少行记录
int addUser(User user);
//删除用户
int delUser(User user);
//修改用户
int modUser(User user);
}
3.4mapper:UserMapper.xml
对应dao层实现方法的映射
<?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="org.example.dao.UserMapper">
<!--查询全部用户-->
<!--实现接口的抽象方法——查询,id要和接口内对应的方法名一致-->
<select id="findAll" resultType="org.example.pojo.User">
select * from user
</select>
<!--单条件:根据姓名查询用户-->
<!--resultType:返回值类型,parameterType:传入参数类型-->
<select id="findUserByName" resultType="org.example.pojo.User" parameterType="string">
<!--{}中的name对应的是UserMapper中的参数名,接口只传入一个参数,可以用#{参数名}获得参数-->
select * from user where name=#{name}
</select>
<!--单条件:根据id查询用户-->
<select id="findUsersById" resultType="org.example.pojo.User" parameterType="int">
select * from user where id=#{id}
</select>
<!--多条件:根据id和姓名查询,因为此时的传入参数类型有int、String,故此类情况可不写传参类型-->
<select id="findUserByIdAndName" resultType="org.example.pojo.User">
<!--在接口传入多个参数的情况下,无法直接通过#{参数名}来获取参数
mybatis默认按照参数传入顺序来获取#{parami},i表示传入参数的顺序-->
<!--select * from users where id=#{param1} and name=#{param2}-->
<!--若想直接使用#{参数名}的方式获取参数,则需在接口的参数前加上@Param注解,来将参数和映射文件中的参数进行绑定-->
select * from user where id=#{id} and name=#{name}
</select>
<!--封装参数-->
<!--直接通过#{对象的属性}获取参数-->
<select id="findUserByUsers" parameterType="org.example.pojo.User" resultType="org.example.pojo.User">
select *from user where id=#{id} and name=#{name}
</select>
<!--模糊查询-->
<select id="findUserNameLike" resultType="org.example.pojo.User" parameterType="String">
select * from user where name Like #{namestr}
</select>
<!--新增用户-->
<!--增加、删除默认返回一个整数,所以不用写resultType-->
<insert id="addUser" parameterType="org.example.pojo.User">
insert into user values(#{id},#{name},#{pwd})
</insert>
<!--删除用户-->
<delete id="delUser" parameterType="org.example.pojo.User">
delete from user where id=#{id} and name=#{name} and pwd=#{pwd}
</delete>
<!--修改用户-->
<update id="modUser" parameterType="org.example.pojo.User">
update user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
</mapper>
3.5测试APPTest
我们会发现,我们在测试的时候,有些代码是重复的,就是我们连接数据库建立会话工厂的那段以及关闭数据连接的代码。
那么我们其实可以把代码给封装起来,因此新建一个tool包,编写MybatisTool.java
package org.example.tool;
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.IOException;
import java.io.InputStream;
public class MyBatisTool {
//获得sqlSession(数据库连接)
//只需这个方法的返回值最后是sqlSession
public static SqlSession getSqlSession() throws IOException {
//static静态方法不用new(调用时不用对象),方便调用!!(公共资源)
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
//关闭会话
public static void closeSqlSession(SqlSession sqlSession){
sqlSession.close();
}
}
以下是测试代码:
package org.example;
import static org.junit.Assert.assertTrue;
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.example.dao.UserMapper;
import org.example.pojo.User;
import org.example.tool.MyBatisTool;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
}
//查询所有用户
@Test
public void testGetAllUsers(){
try {
//以IO流的形式——读取核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
//mybatis的核心对象:SqlSessionFactory创建和数据库连接的会话工厂S
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//用SqlSessionFactory打开一次和数据库的会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//通过接口调用对应的方法实现查询
List<User> userList = userMapper.findAll();
//查看结果
for(User u: userList){
System.out.println(u);
}
sqlSession.close();//执行完,不用的情况下,关闭会话(数据库资源)
} catch (Exception e) {
e.printStackTrace();
}
}
//按姓名查询
@Test
public void testfindUserByName() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//执行根据姓名查询用户
List<User> userList = userMapper.findUserByName("张三");
for(User u: userList){
System.out.println(u);
}
sqlSession.close();
}
//按id查询
@Test
public void testfindUsersById() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//根据id查询
List<User> userList = userMapper.findUsersById(1);
for (User u: userList) {
System.out.println(u);
}
sqlSession.close();
}
//按id和姓名查询
@Test
public void testfindUserByIdAndName() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//根据id和姓名查询
List<User> userList = userMapper.findUserByIdAndName(3,"李莉");
for (User u: userList) {
System.out.println(u);
}
sqlSession.close();
}
//按封装类型查询
@Test
public void testfindUserByUsers() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//根据封装类型查询
User user = new User();
user.setId(1);
user.setName("tom");
List<User> userList = userMapper.findUserByUsers(user);
for (User u: userList) {
System.out.println(u);
}
sqlSession.close();
}
//模糊查询
@Test
public void testfindUserNameLike() throws IOException {
//通过工具类MyBatisTool获得SqlSession
SqlSession sqlSession = MyBatisTool.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//%代表多个任意内容的字符,实际上是一个占位符
List<User> userList = userMapper.findUserNameLike("张%");
for (User u: userList) {
System.out.println(u);
}
sqlSession.close();
}
//新增用户
@Test
public void testaddUser() throws IOException {
SqlSession sqlSession = MyBatisTool.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(6);
user.setName("小明");
user.setPwd("123456");
//返回整数
int addresult = userMapper.addUser(user);
//增删改:需要事物提交(即提交操作),否则不能真正修改数据库内容
sqlSession.commit();
if(addresult>0){
System.out.println("新增用户成功!");
}
else{
System.out.println("新增用户失败!");
}
sqlSession.close();
}
//删除用户
@Test
public void testdelUser() throws IOException {
SqlSession sqlSession = MyBatisTool.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(2);
user.setName("张三");
user.setPwd("123456");
int delresult = userMapper.delUser(user);
sqlSession.commit();
if(delresult>0){
System.out.println("删除用户成功!");
}
else{
System.out.println("删除用户失败!");
}
sqlSession.close();
}
//修改用户
@Test
public void testmodUser() throws IOException {
SqlSession sqlSession = MyBatisTool.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setName("巴拉巴拉");
user.setPwd("abcd");
int modresult = userMapper.modUser(user);
sqlSession.commit();
if(modresult>0){
System.out.println("修改用户成功!");
}
else{
System.out.println("修改用户失败!");
}
sqlSession.close();
}
}