`Mybatis查询手册
第1章 Mybatis
1.1 Mybatis 环境搭建步骤
第一步: 创建maven工程
第二步: 导入坐标
第三步: 编写必要代码(实体类和持久层接口)
第四步: 编写SqlMapConfig.xml
第五步: 编写映射配置文件
第六步: 编写测试类
第一步:创建maven工程
这个不用解释
第二步:导入坐标
在pom.xml文件中添加依赖jar包的坐标:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
第三步:编写必要代码(实体类和持久层接口)
User实体类
package domain;
import java.io.Serializable;
import java.util.Date;
/**
* @author Administrator
* @date 2020/11/209:37
*/
public class User implements Serializable {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
public int getId() {
return id;
}
public void setId(int 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;
}
}
编写持久层接口UserDao
package dao;
import domain.User;
import java.util.List;
/**
* @author Administrator
* @date 2020/11/209:39
*
* User的持久层接口
*/
public interface UserDao {
/**
* @return 返回
*
* 查询所有方法
*/
List<User> findAll();
}
第四步:编写SqlMapConfig.xml
在maven工程中,SqlMapConfig.xml存放在resources文件夹中
- 需要导入约束
- 配置环境
<?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"><!-- 默认值,这个可以叫任意名字,一般用数据库名字 -->
<environment id="mysql"><!-- 上面的default叫啥,这个id就叫什么 -->
<!-- 配置事物类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<!-- 配置连接数据库的4个基本信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件,映射配置文件指的是每个dao独立的配置文件 -->
<!-- 告知mapper映射的位置 -->
<mappers>
<mapper resource="dao/UserDao.xml"/>
</mappers>
</configuration>
第五步:编写映射配置文件
在maven工程中,映射配置文件存放在resource文件夹中,且映射配置文件的名字以及包路径与接口的路径相同
例如:接口文件路径:java/dao/UserDao.java
映射配置文件路径:resource/dao/UserDao.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">
<!-- UserDao.xml下写UserDao接口的映射 -->
<!-- 配置指定接口方法下的sql语句 -->
<mapper namespace="dao.UserDao">
<select id="findAll" resultType="domain.User">
select * from user
</select>
</mapper>
注意事项:
- 在Mybatis中,操作持久层的接口名称和映射文件也叫做Mapper
因此为了与之前的知识对应起来:Dao与Mapper的内涵是一样的- 在idea中创建目录与创建包的一些细节是不一样的,
包在创建时,com.db.dao是三级结构
目录在创建时,com.db.dao是一级结构- Mybatis的映射配置文件位置必须和dao接口的包结构相同
- 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名
- 映射配置文件的操作位置,id属性的取值必须是dao接口的方法名
第六步:编写测试类
import dao.UserDao;
import 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 org.junit.Test;
import java.io.InputStream;
import java.util.List;
/**
* @author Administrator
* @date 2020/11/209:50
*/
public class MybatisTest {
/**
* findAll接口的测试类
*/
@Test
public void testFindAll() throws Exception{
// 1. 读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 创建SqlSessionFactory的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 3. 使用构建者创建工厂对象SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
// 使用SqlSessionFactory生产SqlSession对象
SqlSession session = factory.openSession();
// 使用SqlSession创建dao接口的代理对象
UserDao userDao = session.getMapper(UserDao.class);
// 使用代理对象执行查询所有方法
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
// 释放资源
session.close();
in.close();
}
}
注意事项
不要忘记在配置文件中告知Mybatis要封装到哪个实体类中。
配置方式:指定实体类的全限定类名
注解开发annotation
Mybatis基于注解的入门案例:
把UserDao.xml移除,在dao接口的方法上使用@Select注解,并指定SQL语句
同时需要在SqlMapConfig.xml中的mapper配置,使用class属性指定dao接口的全限定类名
自定义Mybatis_深入剖析Mybaits
实际开发中读取配置文件的方式
一般都不使用绝对路径和相对路径
如果使用绝对路径的话,当更换一台电脑的时候,盘符或者文件的路径会发生改变,不能保证绝对读取
如果使用相对路径的,例如:src/java/main/xxx.xml
项目部署之后,src目录会消失
因此一般情况下我们不会使用绝对路径以及相对路径
- 实际开发中使用的读取配置文件的方法
第一个:使用类加载器。它智能读取类路径的配置文件
第二个:使用ServletContext对象的getRealPath(),获取当前应用的绝对路径
Mybatis使用了构建者模式来创建工厂
构建者模式,用通俗的话来说,我现在需要建设一套别墅
我自己来做的话需要考虑各种细节,但如果交给包工头
我只需要给钱给包工头,包工头就会做好别墅交接给我
优势:把对象的创建细节隐藏,使使用者直接调用方法即可拿到对象
在Mybatis中,SqlSessionFactoryBuilder这个对象就是包工头,
用SqlSessionFactoryBuilder new 一个新的builder出来,
给builder传输SqlMapConfig.xml(钱)就可以建造出一个工厂factory
使用工厂模式生产SqlSession
生产SqlSession使用了工厂模式
避免了在代码中new一个新的SqlSession
优势:解耦(降低类之间的依赖关系)
创建Dao接口使用了代理模式
优势:不修改源码的基础上对原有方法增强
1.2 Mybatis中的CRUD操作
保存
1. 在UserDao方法中创建保存用户的方法
void saveUser(User user);
2. 在配置文件中配置代码
<insert id="saveUser" parameterType="domian.User">
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
上面id配置的使接口中对应的方法的名字
parameterType传输的是方法中传入的参数的封装对象,
为了让Mybatis能够知道自己给你封装的是什么对象
3. 使用测试类实现该方法
注意:调用方法之后需要提交事物sqlSession.commit
否则保存方法执行成功也无法保存记录
4. 更新与删除的方法与保存方法使用的东西类似,可以举一反三进行学习
5. 删除操作的配置文件
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id};
</delete>
注意:
* 因为传入的只有一个Integer参数,因此#{}大括号中间的参数可以取任意名字,没有要求。
* #{} 与 ${} 的区别:
#{}表示一个占位符号通过#{}可以实现 preparedStatement 向占位符中设置值,
自动进行 java 类型和 jdbc 类型转换,#{}可以有效防止 sql 注入。 #{}可
以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型
值,#{}括号中可以是 value 或其它名称。
${}表示拼接 sql 串
通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类
转换, ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单
个简单类型值,${}括号中只能是 value。
6. 区分parameterType与resultType,前者为传入参数的类型,后者为结果集对象
在配置插入操作后,获取插入数据的id
<insert id="saveUser" parameterType="domian.User">
<!-- 配置插入操作后,获取插入数据的id -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
<!-- 这里keyProperty表示id的属性名称 -> 对应实体类 -->
<!-- 这里keyColumn表示id的列名 -> 对应表的 -->
<!-- resultType以及order -> 分别表示结果集类型、执行的时间 -->
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
<!-- 使用这个方法之后就可以得到新添加对象的id -->
深入了解Mybatis的参数
PGNL表达式(Object Graphic Navigation Language)
对象图导航语言
它是通过对象的取值方法来获取数据。在写法上把get给省略了。
比如:我们获取用户的名称
类中的写法:user.getUsername();
OGNL表达式的写法:user.username
Mybatis中为什么能够直接写username,而不用user.呢
因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名。
当POJO对象的属性名与Mysql数据表中数据名有差异时
俩个解决方案:
1. 起别名:
属性名与Mysql列名对不上,因此给Mysql语句中的列名起别名(与属性名一致)即可
select id as userId, username as userName, address as userAddress .... from user;
这种方式的效率比较高
2. 在UserDao.xml文件中配置 查询结果的列名和实体类的属性名的对应关系
<!-- 配置查询结果的列名和实体类的属性名的对应关系 -->
<resultMap id="userMap" type="domain.User">
<!-- 主键字段的对应 -->
<id property="userId" column="id"></id>
<!-- 非主键字段的对应 -->
<result property="userName" column="username"></result>
....
</resultMap>
<!-- property对应Java中的对象, column对应的为数据库中的属性 -->
* 配置完成后,将配置文件中的resultType变换为resultMap并将id值填入
1.3 Mybatis编写Dao实现类的使用方式
了解即可,使用Mybatis一般不会使用Dao实现类
这会徒增很多工作,并没有好好的利用Mybatis