目录
- Mybatis的基本使用
Mybatis的基本使用
学习目标
- 认识Mybatis
- 了解Mybatis功能
- 知道为什么学习Mybatis
- 利用Mybatis编写一个简单程序
- 学会使用Mybatis基本功能
- 了解Mybatis的基本配置
一、认识Mybatis
1. 简介
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,屏蔽了jdbc api底层访问细节,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
2. 原理
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
3. 为什么使用Mybatis
原生jdbc连接
import org.junit.Test;
import java.sql.*;
/**
* description:java原生方式mysql
*
* @author jiaoqianjin
* Date: 2021/3/3
**/
public class MySQLTest {
static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/test2?useSSL=false&allowPublicKeyRetrieval=true" +
"&serverTimezone=UTC";
// 数据库的用户名与密码,需要根据自己的设置
static final String USER = "root";
static final String PASS = "123456";
/**
* 测试原生sql方式查询
*/
@Test
public void testQuery() {
Connection conn = null;
Statement stmt = null;
try {
// 1.注册 JDBC 驱动
Class.forName(JDBC_DRIVER);
// 2.打开链接
System.out.println("连接数据库...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 3.执行查询
System.out.println(" 实例化Statement对象...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, name, age FROM user WHERE name='小王'";
ResultSet rs = stmt.executeQuery(sql);
// 4.展开结果集数据库
while (rs.next()) {
// 通过字段检索
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
// 输出数据
System.out.print("ID: " + id);
System.out.print("name: " + name);
System.out.print("age: " + age);
System.out.print("\n");
}
// 5.完成后关闭
rs.close();
stmt.close();
conn.close();
} catch (Exception se) {
// 处理 JDBC 错误
se.printStackTrace();
}// 处理 Class.forName 错误
finally {
// 关闭资源
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException ignored) {
}// 什么都不做
try {
if (conn != null) {
conn.close();
}
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
存在的问题
-
数据库连接频繁开启和关闭,会严重影响数据库的性能。
-
代码中存在硬编码,分别是数据库部分的硬编码和SQL执行部分的硬编码。
Mybatis的存在:
-
Mybatis就是帮助我们将数据存入数据库中 , 和从数据库中取数据
-
MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) -->对象关系映射
当然,所有的事情,不用Mybatis依旧可以做到,只是用了它,所有实现会更加简单!
4. Mybatis的优点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供xml标签,支持编写动态sql。
- 用户量大,公司需要
5. Mybatis的核心
- mybatis配置文件,包括Mybatis****全局配置文件和Mybatis映射文件**,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的 信息。
- mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
- 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
- SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
- Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型。
6. 如何获取mybatis
- Maven
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
-
Github:https://github.com/mybatis/mybatis-3
-
源码中文注释: https://github.com/tuguangquan/mybatis
要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中即可。
二、Mybatis入门
项目结构
1. 环境搭建
- 创建数据库
CREATE DATABASE `mybatis_01`;
USE `mybatis_01`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`phone` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`name`,`phone`) values (1,'张三','1536537156'),(2,'李四','1536537157'),(3,'王五','1536537158');
新建一个Maven项目作为父工程,删除src目录,
- 导入相关Maven依赖
<dependencies>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>mysql</groupId>-->
<!-- <artifactId>mysql-connector-java</artifactId>-->
<!-- <version>8.0.12</version>-->
<!-- </dependency>-->
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2. 创建一个模块,编写MyBatis核心配置文件
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>
<!-- 配置mybatis的环境信息 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源,采用传统的javax. sql. DataSource规范中的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 如果数据库驱动使用的是8.0.12需要使用下面的配置 -->
<!--<property name="url" value="jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&useUnicode=true&serverTimezone=UTC&characterEncoding=utf8"/>-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/shida/dao/UserMapper.xml"/>
</mappers>
</configuration>
3. 编写MyBatis工具类
MybatisUtil
public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 1. 读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 2. 通过SqlSessionFactoryBuilder创建sqlSessionFactory会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*功能描述:获取SqlSession连接
* @author jiaoqianjin
* @date 2021/3/3
*/
public static SqlSession getSession(){
// 使用sqlSessionFactory创建SqlSession
return sqlSessionFactory.openSession();
}
}
4. 创建实体类
User
public class User {
private int id; //id
private String name; //姓名
private String phone; //手机号
//构造,有参,无参
//set/get
//toString()
}
5. 编写Mapper接口
public interface UserMapper {
/**
*功能描述: 查询用户集合
* @return java.util.List<com.shida.entity.User>
* @author jiaoqianjin
* @date 2021/3/3
*/
List<User> selectUser();
}
6. 编写Mapper.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:命名空间,它的作用就是对SQL进行分类化管理,可以理解为SQL隔离
注意:使用mapper代理开发时,namespace有特殊且重要的作用
-->
<mapper namespace="com.shida.dao.UserMapper">
<select id="selectUser" resultType="com.shida.entity.User">
select * from user
</select>
</mapper>
7. 编写测试类
public class UserTest {
@Test
public void selectUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
// 调用SqlSession操作数据库
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
// 关闭 SqlSession
session.close();
}
}
8. 运行结果
三、更多案例讲解
1. 通过id查询用户
在UserMapper中添加方法
public interface UserMapper {
/**
*功能描述: 查询用户集合
* @return java.util.List<com.shida.entity.User >
* @author jiaoqianjin
* @date 2021/3/3
*/
List<User> selectUser();
/**
*功能描述: 通过id查询用户
* @param id 用户id
* @return com.shida.entity.User
* @author jiaoqianjin
* @date 2021/3/3
*/
User selectUserById(int id);
}
在UserMapper.xml中添加Select语句
<!--
[id]:statement的id,要求在命名空间内唯一
[parameterType]:入参的java类型
[resultType]:查询出的单条结果集对应的java类型
[#{}]: 表示一个占位符?
[#{id}]:表示该占位符待接收参数的名称为id。注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义
-->
<select id="selectUserById" parameterType="int" resultType="com.shida.entity.User">
SELECT * FROM USER WHERE id = #{id}
</select>
在测试类中添加
@Test
public void tsetSelectUserById() {
SqlSession session = MybatisUtil.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}
运行结果
2. 根据多个参数查询
在UserMapper中添加
/**
*功能描述: 根据多个参数查询用户
* @param name 用户名
* @param phone 手机号
* @return com.shida.entity.User
* @author jiaoqianjin
* @date 2021/3/4
*/
User selectUserByParams(String name, String phone);
在UserMapper.xml中添加
<select id="selectUserByParams" resultType="com.shida.entity.User">
SELECT * FROM USER WHERE name = #{name} and phone = #{phone}
</select>
测试类
@Test
public void testSelectUserByParams() {
SqlSession session = MybatisUtil.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
String name = "王五";
String phone = "1536537158";
User user = mapper.selectUserByParams(name, phone);
System.out.println(user);
session.close();
}
运行结果
报错原因
因为java没有保存形参的记录,java在运行的时候会把 selectUserByParams(name, phone) 中的参数变成这样selectUserByParams(int arg0,int arg1),这样我们就没有办法去传递多个参数。
解决办法一:
在参数前添加**@Param**注解 mybatis提供了@Param这个注解来完成命名传入参数
/**
* 功能描述: 根据多个参数查询用户
*
* @param name 用户名
* @param phone 手机号
* @return com.shida.entity.User
* @author jiaoqianjin
* @date 2021/3/4
*/
User selectUserByParams(@Param("name") String name, @Param("phone") String phone);
解决办法二:
使用Map
User selectUserByParams2(Map<String,String> map);
-------
<select id="selectUserByParams2" parameterType="map" resultType="com.shida.entity.User">
SELECT * FROM USER WHERE name = #{name} and phone = #{phone}
</select>
--------
Map<String,String> map = new HashMap<String, String>();
map.put("name","王五");
map.put("phone","1536537158");
User user = mapper.selectUserByParams2(map);
两种方法对比:
Map方法缺点就在于可读性差,每次必须阅读他的键,才能明白其中的作用,后期维护困难。
@Param,可读性比较强
当参数为2-5个时候,用@param最佳,当大于5的时候,肯定会选择map了
Map替代方法:
使用BO传输
在entity中创建UserBo
public class UserBO {
private String name;
private String phone;
//构造,有参,无参
//set/get
//toString()
}
UserMapper
User selectUserByParams3(UserBO userBO);
UserMapper
<select id="selectUserByParams3" parameterType="com.shida.entity.UserBO" resultType="com.shida.entity.User">
SELECT * FROM USER WHERE name = #{name} and phone = #{phone}
</select>
测试类
@Test
public void testSelectUserByParams3() {
SqlSession session = MybatisUtil.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
UserBO userDTO = new UserBO();
userDTO.setName("王五");
userDTO.setPhone("1536537158");
User user = mapper.selectUserByParams3(userDTO);
System.out.println(user);
session.close();
}
3. 根据name模糊查询
在UserMapper中添加
/**
*功能描述: 根据name 模糊查询
* @param name 用户姓名
* @return com.shida.entity.User
* @author jiaoqianjin
* @date 2021/3/3
*/
User selectUserLikeByName(String name);
在UserMapper.xml中添加Select语句
<!--
[${}]:表示拼接SQL字符串
[${value}]:表示要拼接的是简单类型参数。
注意:
1、如果参数为简单类型时,${}里面的参数名称必须为value
2、${}会引起SQL注入,一般情况下不推荐使用。但是有些场景必须使用${},比如order by ${colname}
-->
<select id="selectUserLikeByName" parameterType="String" resultType="com.shida.entity.User">
select * from USER where name like '%${value}%'
</select>
在测试类中添加
@Test
public void testSelectUserLikeByName() {
SqlSession session = MybatisUtil.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
String name = "李";
User user = mapper.selectUserLikeByName(name);
System.out.println(user);
session.close();
}
**#{}**和${}
#{}:相当于预处理中的占位符?。
#{}里面的参数表示接收java输入参数的名称。
#{}可以接受HashMap、POJO类型的参数。
当接受简单类型的参数时,#{}里面可以是value,也可以是其他。
#{}可以防止SQL注入。
${}:相当于拼接SQL串,对传入的值不做任何解释的原样输出。
${}会引起SQL注入,所以要谨慎使用。
${}可以接受HashMap、POJO类型的参数。
当接受简单类型的参数时,${}里面只能是value。
4. 新增用户
在UserMapper中添加
/**
*功能描述: 新增一个用户
* @param user 用户信息
* @return /
* @author jiaoqianjin
* @date 2021/3/3
*/
int addUser(User user);
在UserMapper.xml中添加insert语句
<insert id="addUser" parameterType="com.shida.entity.User">
insert into user (id,name,phone) values (#{id},#{name},#{phone})
</insert>
如果主键值是通过MySQL自增机制生成的,此处可以不再显式的为id赋值
<insert id="addUser" parameterType="com.shida.entity.User">
insert into user (name,phone) values (#{name},#{phone})
</insert>
在测试类中添加
@Test
public void testAddUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(4,"周六","15936537150");
int i = mapper.addUser(user);
System.out.println(i);
//提交事务,重点!不写的话不会提交到数据库
session.commit();
session.close();
}
5. 修改用户
在UserMapper中添加
/**
*功能描述: 用户修改
* @param user 待修改的用户信息
* @return int
* @author jiaoqianjin
* @date 2021/3/3
*/
int updateUser(User user);
在UserMapper.xml中添加update语句
<update id="updateUser" parameterType="com.shida.entity.User">
update user set name=#{name},phone=#{phone} where id = #{id}
</update>
在测试类中添加
@Test
public void testUpdateUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setName("李思思");
user.setPhone("12345678910");
int i = mapper.updateUser(user);
System.out.println(i);
// 提交事务
session.commit();
session.close();
}
6. 删除用户
在UserMapper中添加
/**
*功能描述: 删除用户
* @param id 待删除用户id
* @return int
* @author jiaoqianjin
* @date 2021/3/3
*/
int deleteUser(int id);
在UserMapper.xml中添加delete语句
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>
在测试类中添加
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.deleteUser(5);
System.out.println(i);
//提交事务,重点!不写的话不会提交到数据库
session.commit();
session.close();
}
四、配置解析
1. 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>
<!-- 配置mybatis的环境信息 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源,采用传统的javax. sql. DataSource规范中的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射器 : 定义映射SQL语句文件 -->
<mappers>
<mapper resource="com/shida/dao/UserMapper.xml"/>
</mappers>
</configuration>
dataSource 有三种内建的数据源类型
type="[UNPOOLED|POOLED|JNDI]"
- unpooled:这个数据源的实现只是每次被请求时打开和关闭连接。
- pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
- jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
- 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…
的用法
<!-- 1. 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="com/shida/dao/UserMapper.xml"/>
</mappers>
<!-- 不使用
2. 使用完全限定路径
-->
<mappers>
<mapper url="F:\teach\project\mybatis-01\src\main\java\com\shida\dao\UserMapper.xml"/>
</mappers>
<!--
3. 使用映射器接口实现类的完全限定类名
需要mapper接口和mapper映射文件称相同,且放到同一个目录下
-->
<mappers>
<mapper class="com.shida.dao.UserMapper"/>
</mappers>
<!-- 推荐使用
4. 将包内的映射器接口实现全部注册为映射器
需要mapper接口和mapper映射文件称相同,且放到同一个目录下
-->
<mappers>
<package name="com.shida.dao"/>
</mappers>
2. Mapper文件
<?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.shida.mapper.UserMapper">
</mapper>
当namespace绑定接口后,不用写接口实现类,mybatis会通过该绑定自动帮你找到对应要执行的SQL语句
namespace中文意思:命名空间:
-
namespace的命名必须跟某个接口同名
-
接口中的方法与映射文件中sql语句id应该一一对应
-
<select id="selectUser" resultType="com.shida.entity.User"> select * from user </select>
-
namespace命名规则 : 包名+类名
3. properties数据库文件配置
properties数据库文件配置,设置为外部配置可替换
新建一个db.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis_01?useSSL=false&useUnicode=true&characterEncoding=utf8
username=root
password=123456
修改mybatis-config.xml
4. typeAliases
别名是使用是为了在映射文件中,更方便的去指定参数和结果集的类型,不再用写很长的一段全限定名。
5. Log4j配置
对于以往的开发过程,我们会经常使用到debug模式来调节,跟踪我们的代码执行过程。但是现在使用Mybatis是基于接口,配置文件的源代码执行过程。因此,我们必须选择日志工具来作为我们开发,调节程序的工具。
- Log4j是Apache的一个开源项目
- 通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…
- 我们也可以控制每一条日志的输出格式;
- 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
使用步骤:
1、导入log4j的包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2、配置文件编写
日志级别在开发阶段设置成DEBUG,在生产阶段设置成INFO或者ERROR。
Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来,也是说大于等于的级别的日志才输出
# 全局日志配置
log4j.rootLogger=WARN, stdout
# MyBatis 日志配置,打印一组映射器的日志,只需要打开映射器所在的包的日志功能即可
log4j.logger.com.shida.dao.UserMapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
3、setting设置日志实现
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
4 在程序中使用Log4j进行输出!
public class UserTest {
static Logger logger = Logger.getLogger(UserTest.class);
@Test
public void selectUser() {
logger.info("info:进入selectUser方法");
logger.debug("debug:进入selectUser方法");
logger.error("error: 进入selectUser方法");
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user);
}
session.close();
}
}
五、ResultMap结果集映射
解决实体类属性名与数据库表的字段名不一致
场景还原
创建一个User1实体类
public class User1 {
private int id;
private String name;
private String number; // 手机号与数据库中的不一样
//构造方法
//set/get
//toString()
}
创建一个接口
/**
* 功能描述: 通过id查询用户
*
* @param id 用户id
* @return com.shida.module.User
* @author jiaoqianjin
* @date 2021/3/3
*/
User1 selectUser1ById(int id);
创建一个查询语句
<select id="selectUser1ById" parameterType="int" resultType="com.shida.entity.User1">
SELECT * FROM USER WHERE id = #{id}
</select>
测试
@Test
public void testSelectUser1ById() {
SqlSession session = MybatisUtil.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
User1 user = mapper.selectUser1ById(1);
System.out.println(user);
session.close();
}
运行结果
分析:
-
select * from user where id = #{id} 可以看做
select id,name,phone from user where id = #{id}
-
mybatis会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写) , 去对应的实体类中查找相应列名的set方法设值 , 由于找不到setPhone() , 所以number返回null ; 【自动映射】
解决方案
- 在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配
<select id="selectUser1ById" parameterType="int" resultType="com.shida.entity.User1">
select
id,
name,
phone as number
from user
where id = #{id}
</select>
- 使用结果集映射->ResultMap
<resultMap id="UserMap" type="com.shida.entity.User1">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<result column="name" property="name"/>
<result column="phone" property="number"/>
</resultMap>
<select id="selectUser1ById" parameterType="int" resultMap="UserMap">
SELECT * FROM USER WHERE id = #{id}
</select>
六、Lombok使用(推荐)
https://zhuanlan.zhihu.com/p/146659383
1、IDEA安装Lombok插件
2、引入Maven依赖
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
3、在代码中增加注解
@Data //GET,SET,ToString,有参,无参构造
public class Teacher {
private int id;
private String name;
}
七、注解实现增删改查
1. 查
/**
* 功能描述: 查询用户集合
*
* @return java.util.List<com.shida.module.User>
* @author jiaoqianjin
* @date 2021/3/3
*/
@Select("select * from user")
List<User> selectUser();
在mybatis的核心配置文件中注入
<!--使用class绑定接口-->
<mappers>
<mapper class="com.shida.dao"/>
</mappers>
测试
@Test
public void selectUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user);
}
session.close();
}
2. 增
改造MybatisUtils工具类的getSession( ) 方法,重载实现。
public static SqlSession getSession(){
//事务自动提交
return sqlSessionFactory.openSession(true);
}
编写接口新增方法
//添加一个用户
@Insert("insert into user (id,name,phone) values (#{id},#{name},#{phone})")
int addUser(User user);
测试
@Test
public void testAddUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(5, "周六", "15936537150");
int i = mapper.addUser(user);
System.out.println(i);
session.close();
}
3. 删除
编写删除接口
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);
测试
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.deleteUser(5);
System.out.println(i);
session.close();
}
4. 修改
编写修改接口
@Update("update user set name=#{name},phone=#{phone} where id = #{id}")
int updateUser(User user);
测试
@Test
public void testUpdateUser() {
SqlSession session = MybatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setName("李2思");
user.setPhone("12345678910");
int i = mapper.updateUser(user);
System.out.println(i);
session.close();
}