Mybatis-HellWorld
建表
创建java bean
导入必要文件
创建全局配置文件
创建SqlSqssionFactory
创建映射文件
测试
改进(接口式编程)
建表
创建一个Mysql数据库,名为Mybatis,然后在里面创建一张表:
create table btl_employee(
id int(11) primary key auto_increment,
last_name varchar(255),
gender char(1),
email varchar(255)
);
向表中插入一条数据:
insert into mybatis.btl_employee (last_name, gender, email)
values ("jase", "男", "1599869435@qq.com");
创建java bean
创建一个java项目,在src目录下创建com.atguigu.mybatis.bean包,包下创建Employee实体类,并对应数据库中的字段:
package com.atguigu.mybatis.bean;
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
导入必要文件
在项目根目录下新建lib文件夹,并把mybatis的jar包以及需要用到的相关jar包放入该目录,其中,mybatis的jar包可以从官方处下载的文件内找到,而mysql-connector-java则需要到mysql官网下载。log4j.jar用于显示日志,其需要一个log4j的xml,所以我们需要新建一个conf文件夹,将log4j.xml放在里面,此时目录结构:
其中,log4j.xml的内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
不要忘了把conf文件夹设置为配置文件夹,右键点击conf文件夹,找到Mark Directoy as选择Resources Root即可。
创建全局配置文件
我们可以在下载的文件内找到名为mybatis-3.5.7.pdf文件,通过对其阅读,我们发现每一个mybatis应用都是以SqlSessionFactory为中心的,而SqlSessionFactory可以通过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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
property标签和mapper标签内的就是属性就是我们需要修改的地方
driver表示驱动、url表示数据库路径、username和password表示数据库用户名和密码
下面的mapper标签表示将映射文件注册到全局配置文件中
我们在conf目录下新建mybatis-config.xml,内容为pdf文件内提供的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="qks218126"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="EmployeeMapper.xml"/>
</mappers>
</configuration>
注意上面的driver,现在开发一般写com.mysql.cj.jdbc.Driver,而不是以前的com.mysql.jdbc.Driver
mapper标签内的文件改成我们后面创建的EmployeeMapper.xml映射文件
创建SqlSessionFactory
浏览pdf我们发现创建SqlSessionFactory还需要在一个具体类中写上创建代码。
开发目录下新建test包,下面新建测试类MybatisTest,写上测试方法text(),并在方法内写上创建代码:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
如果没有@Test,需要额外引入JUnit
接下来我们需要获取sqlsession实例,该实例能通过调用方法执行映射的sql语句:
SqlSession openSession = sqlSessionFactory.openSession();
SqlSession其实表示和数据库的一次会话
创建映射文件
这个时候我们发现了一个问题:映射文件在哪?需要映射的sql语句在哪?
这个问题的答案我们可以通过翻阅pdf获知,里面提供了一个映射文件模板:
<?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.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
namespace:名称空间,我们可以根据自己的项目进行修改
id:唯一标识
resultType:返回类型,可以用于将结果封装成我们想要的对象
#{}:表示的是方法调用时传进来的参数的值
在conf目录下新建EmployeeMapper.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">
<mapper namespace="com.atguigu.mybatis.EmployeeMapper">
<select id="selectEmp" resultType="com.atguigu.mybatis.bean.Employee">
select id, last_name lastName, gender, email from btl_employee where id = #{id}
</select>
</mapper>
这个就是我们开发过程中需要具体编写sql的映射文件
这里因为数据库中的last_name字段跟Employee类中的lastName字段不一致,所以查询的语句需要加个重命名
测试
再返回MybatisTest类,通过查询pdf文档得知,SqlSession实例的selectOne方法可以用来调用映射文件的sql,并获取一个实例对象:
Employee employee = openSession.selectOne("com.atguigu.mybatis.EmployeeMapper.selectEmp", 1);
selectOne方法的第一个参数表示一个具体id值,这个id要跟我们的编写的映射文件(EmployeeMapper.xml)内的sql语句的id(这里是selectEmp)对应,为了避免不同配置文件内有重名的id,最好在id前面加上配置文件内定义的名称空间(这里是com.atguigu.mybatis.EmployeeMapper)
第二个参数表示传递给sql语句的参数,这里传了一个数字1,具体对应上面EmployeeMapper.xml内select语句的#{id}
下面是测试类的完整代码:
package com.atguigu.mybatis.test;
import com.atguigu.mybatis.bean.Employee;
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.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
public class MybatisTest {
/**
* 根据xml配置文件创建一个SqlSessionFactory对象
* @throws IOException
*/
@Test
public void test() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession实例,直接执行已经映射的sql语句
try (SqlSession openSession = sqlSessionFactory.openSession()) {
Employee employee = openSession.selectOne("com.atguigu.mybatis.EmployeeMapper.selectEmp", 1);
System.out.println(employee.toString());
}
}
}
下面是完整的项目目录:
其中标红框的文件就是我们开发时需要不断编写的文件,总体来说不算复杂
接下来运行测试方法test:
可以看到已经拿到数据库里面的值了。
改进(接口式编程)
如果我们查看selectOne方法的介绍,我们不难发现它的第二个参数允许传递一个Object,假如我传递了一个字符串,但是对应的#{id}却要求为int,这个时候就产生了问题。
Mybatis给这种问题提供了解决方案——运用接口式编程。
Mybatis允许通过接口来指定查询的方法和参数类型,避免传参错误的出现。
创建dao包,包下创建接口EmployeeMapper,类内编写方法getEmpById:
package com.atguigu.mybatis.dao;
import com.atguigu.mybatis.bean.Employee;
public interface EmployeeMapper {
Employee getEmpById(Integer id);
}
这个接口其实就是用来得到映射文件的查出结果并封装成所需对象的,不需要实现类,接口内方法直接对应映射文件。
这个时候映射文件要作改动:命名空间、方法id
命名空间应当设置成接口的全类名:
<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">
select方法的id的值应当改成映射接口中对应方法的方法名:
id="getEmpById"
完整映射文件:
<?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.atguigu.mybatis.dao.EmployeeMapper">
<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee">
select id, last_name lastName, gender, email from btl_employee where id = #{id}
</select>
</mapper>
接下来重新编写测试方法:
@Test
public void test1() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession openSession = sqlSessionFactory.openSession()) {
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmpById(1);
System.out.println(employee.toString());
}
}
可以看到,在获取SqlSession对象之后,我们并不是像之前那样通过调用selectOne方法来获取Employee对象,而是通过调用getMapper方法来获取EmployeeMapper接口的实例,通过该实例调用getEmpById方法来获取Employee对象,这样就能唯一指定参数类型。
下面是测试的结果:
可以看到是正常的。
如果对方法内的mapper对象进行打印,我们就会看到下面的结果:
可以看到mapper是一个代理对象,Mybatis在执行的过程中会为接口自动创建一个代理对象,然后由这个代理对象去执行方法