这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战
简介
什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。(官网说的)
入门
构建一个普通maven工程,导入依赖
<dependencies>
//mybatis依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
//mysql依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
//单元测试依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
//lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
//maven静态资源过滤配置文件
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
数据库表

连接数据库配置文件,注册mapper
```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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_test?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
//注册mapper
<mappers>
<mapper resource="com/study/mapping/UserMapper.xml"/>
</mappers>
</configuration>
配置连接数据库工具类
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//获取核心配置文件获取sqlSessionFactory
String resource = "mybatsi-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession连接
public static SqlSession getSession(){
return sqlSessionFactory.openSession();
}
}
实体类
@Data
public class User {
private int id; //id
private String name; //姓名
private String pwd; //密码
}
接口
public interface UserMapper {
//查询所有
List<User> selectUser();
}
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">
<!--绑定mapping接口-->
<mapper namespace="com.study.mapping.UserMapper">
<select id="selectUser" resultType="com.study.pojo.User">
select * from user
</select>
</mapper>
测试类
@Test
public void selectUser() {
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
运行结果
进门了
接下来看 Crud
先看UserMapper里的个标签意思
namespace 对应的接口的全路径名
select 查询标签
insert 插入标签
delect 删除
update 更新标签
id 对应的方法名
resultType 返回值类型
parameterType 入参类型
//根据id查询
User findUserById(Integer id);
//新增一个用户
void InserUser(User user);
//更新用户信息
void updateUser(User user);
// 删除用户信息
void deleteUserById(Integer id);
增删改查mapper.xml
<select id="findUserById" resultType="com.study.pojo.User" parameterType="int">
select * from user where id =#{id}
</select>
<insert id="InserUser" parameterType="com.study.pojo.User" >
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="com.study.pojo.User">
update user set name=#{name},pwd=#{pwd} where id = #{id}
</update>
<delete id="deleteUserById" parameterType="Int">
delete
from user
where id=#{id};
</delete>
接口
//根据id查询
User findUserById(Integer id);
//新增一个用户
void InserUser(User user);
//更新用户信息
void updateUser(User user);
// 删除用户信息
void deleteUserById(Integer id);
测试类
@Test
public void test2(){
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User userById = mapper.findUserById(1);
System.out.println(userById);
session.close();
}
@Test
public void test3(){
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(4);
user.setName("王麻子");
user.setPwd("12345");
mapper.InserUser(user);
//提交
session.commit();
//关闭资源
session.close();
}
@Test
public void test4(){
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(4);
user.setName("王麻子修改后");
user.setPwd("12345");
mapper.updateUser(user);
//提交
session.commit();
//关闭资源
session.close();
}
@Test
public void test5(){
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUserById(2);
//提交
session.commit();
//关闭资源
session.close();
}
数据库结果
parameterType
参数类型,mapper接口的形参类型,给mybatis来给sql语句参数来赋值的,有两种写法,第一种是写java类型的全新定类型名称,第二种是写mybatsi自定义的别名(下图),还有可以不写可以通过反射自己去获取
给参数赋值,接口的形参是简单数据类型(java基本数据类型和String)我们常用#{任意字符},
只有一个入参的情况下我,我们直接写一个如上边代码findUserById()方法,
有多个简单参数,我们的就得使用@Param注解来绑定参数,参数比较多的情况下我们使用对象来做参数,比如上边的updateUser(),对象类型也可以是自定义的,要有getset方法。
接口
List<User> findUserNameOrPwd (@Param("username") String userName,@Param("pwd") String pwd);
xml
<select id="findUserNameOrPwd" resultType="com.study.pojo.User">
select * from user where name = #{username} or pwd = #{pwd}
</select>
测试类
@Test
public void selectUserLlike1() {
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.findUserNameOrPwd("王麻子","123456");
for (User user: users){
System.out.println(user);
}
session.close();
}
如果不用来绑定参数,他就不知道哪个传给哪个,就会出现下图的报错
还有一种方法,我们可以通过位置来写多个普通参数传参#{arg0}#{arg1}....
List<User> findUserNameOrPwd1 ( String userName, String pwd);
<select id="findUserNameOrPwd1" resultType="com.study.pojo.User">
select * from user where name = #{arg0} or pwd = #{arg1}
</select>
@Test
public void selectUserLlike2() {
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.findUserNameOrPwd1("王麻子","123456");
for (User user: users){
System.out.println(user);
}
session.close();
}
还可以使用map来赋值
List<User> findUserByMap (Map<String,Object> map);
<select id="findUserByMap" resultType="com.study.pojo.User">
select * from user where name = #{username} or pwd = #{pwd}
</select>
@Test
public void selectUserByMap() {
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("username","王麻子");
map.put("pwd","123456");
List<User> users = mapper.findUserByMap(map);
for (User user: users){
System.out.println(user);
}
session.close();
}
#和$
处理占位符# 使用的是PrepareStatment对象,创建PrepareStatment对象,执行sql语句,遇到一个#变成一个占位符,然后通过set方法去给?赋值。 #{}的特点
- 使用PrepareStatment对象效率高
- 避免sql注入
- #{}作为列的值使用,位于等号的右边,#{}位置的值是和数据类型有关的,set值时匹配数据类型选择set方法
{},表示字符创连接,吧sql语句和其他内容链接在一起,创建Statement对象来执行sql语句
${}的特点
- 效率低
- 使用字符创连接 sql注入问题
- 数据原样使用不会区分数据类型
- 常用表名列明
${}用法
表名或者列名的时候直接拼接字符串的
需求 : 一个方法实现不同情况用不同列排序
分析 :使用&{}拼不同的列明
List<User> findUserOderyBy(String colmle);
<select id="findUserOderyBy" resultType="com.study.pojo.User">
select * from user order by ${value}
</select>
@Test
public void selectUserOrderBycomle() {
//获取sqlsession
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
// List<User> users = mapper.findUserOderyBy("id");
// List<User> users = mapper.findUserOderyBy("name");
List<User> users = mapper.findUserOderyBy("pwd");
for (User user: users){
System.out.println(user);
}
session.close();
}