MyBatis概述
MyBatis是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,它消除了几乎所有的JDBC代码和参数的手动设置以及对结果集的检索,并实现简单的XML或注解进行配置和原始映射,用以将接口和Java的POJO(普通Java对象)映射成数据库中的记录。
什么是MyBatis
MyBatis框架也被称为ORM(对象关系映射)框架。所谓ORM,就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术,通过描述Java对象与数据库表之间的映射关系自动将Java应用程序中的对象持久化到关系型数据库的表中。
使用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象,而ORM框架则会通过映射关系将这些面向对象的操作转换成底层的SQL操作。
MyBatis入门–增删改查
我们使用Maven来构建Web项目,这样方便我们统一管理Jar。如果还没有使用过Maven的,可以跟着我一步步来创建一个Maven项目。
1.点击File->New Project->选择Maven->勾选上Create from archetype->选择maven-archetype-webapp
到这里,我们已经通过Maven构建好了一个Web项目,接下来我们需要在pom.xml中引入MyBatis和MySql的Jar包。代码如下
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
好了,Mybatis的环境已经构建成功,接下来让我们通过一个用户信息管理的小案例来介绍MyBatis框架的基本使用.
查询用户
根据用户编号(id)查询用户信息
1.这里我使用的是SQLYong管理Mysql,打开SQLYong,在test数据库中创建一个mybatis_test表,同时预先添加几条数据,SQL语句如下:
/*使用数据库test*/
USE test
/*创建数据表 mybatis_text*/
CREATE TABLE mybatis_text(
id INT(32) PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
jobs VARCHAR(50),
phone VARCHAR(16)
);
#往数据表mybatis_text中插入数据记录
INSERT INTO mybatis_text VALUES(1,"小鑫好看",'student','18166117121');
INSERT INTO mybatis_text VALUES(2,"猪心是猪",'pig','17670619593');
INSERT INTO mybatis_text VALUES(3,"邵狗真聪明",'dog','18473920085');
SELECT * FROM mybatis_text
执行最后一条全部SQL语句后,会发现mybatis_text表多出了如下几天数据
2.打开项目工程目录,在main文件下创建一个resources文件夹,并将右键Mark Dircetory as 选择 Resources Root将resoureces文件夹变成资源文件夹,大家或许会有一个疑问为,为什么需要创建resources文件夹呢?
因为无论是Spring还是Mybatis读取配置文件、映射配置文件都是从该文件夹下进行读取,如果将配置文件放在其他文件下,会报找不到错误.
3.在java目录下创建一个com.ssm.po包,在该包下创建持久化类User,并在类中声明id、username、jobs和phone属性,及其对应的getter/setter方法,代码如下:
package com.ssm.po;
public class User {
private Integer id; //用户id
private String username;//用户姓名
private String jobs;//用户职业
private String phone;//用户电话号码
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobs() {
return jobs;
}
public void setJobs(String jobs) {
this.jobs = jobs;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", jobs='" + jobs + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
从上述代码可以看成,持久化类User与普通的JavaBean并没有什么区别,只是其属性字段与数据库中的表字段相对应。实际上,User就是POJO(普通Java对象)。MyBatis就是采用POJO作为持久化类来完成对数据库操作的。
4.在resoures创建映射文件UserMapper.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.ssm.mapper.UserMapper" >
<select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
SELECT * from mybatis_text where id=#{id}
</select>
</mapper>
上述代码中,前面4行是MyBatis的约束配置。 < mapper >元素是配置文件的根元素,包含一个namespace属性,该属性为< mapper >元素指定了唯一的命名空间,通常会设置成"包名+SQL映射文件名"的形式。 子元素< select >中的信息是用于执行查询操作的配置,其id属性是< select >元素在映射文件中的唯一标识; parameterType属性用于指定传入参数的类型,这里表示传递给执行SQL的是一个Integer类型的参数;resultType属性用于指定返回结果的类型,这里表示返回的数据是User类型。在定义的查询SQL语句中,"#{}“用于表示一个占位符,相当于”?"; 而"#{id}"表达该占位符待接收参数的名称为id
5.在resourece目录下创建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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置环境 默认的环境id为mysql-->
<environments default="mysql">
<!--配置mysql的环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置连接数据库的4个基本信息-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useSSL=false"></property>
<property name="username" value="root"></property>
<property name="password" value="1424025155abc"></property>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
<!--如果是用注解来配置的话,此处应该使用class属性指定被注解的dao全限定类名-->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
在上述代码中 < configuration >元素中的内容是我们需要编写的配置信息。 这里按照< configuration >子元素的功能将配置分为了两个步骤: 第1步,配置环境;第2步,配置mapper的位置。
需要注意的是: mapper文件所在的位置必须在resources下,不然MyBatis会报找不到mapper错误
6.在java目录下创建一个com.ssm.test包,在该包下创建测试类MybatisTest,代码如下:
package com.ssm.test;
import com.ssm.po.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 java.io.InputStream;
public class MybatisTest {
public static void main(String[] args) throws Exception {
findUserByIdTest();
}
//根据用户id查询用户信息
public static void findUserByIdTest() throws Exception{
//1.读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//2.根据配置文件构建SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.通过SqlSessionFactory创建SqlSession实例
SqlSession session = sqlSessionFactory.openSession();
//4.SqlSession执行映射文件中定义的SQL,并返回映射结果
User user = session.selectOne("mapper.UserMapper.findUserById",1);
//5.打印输出结果
System.out.println(user);
//6.关闭SqlSession
session.close();
}
}
在上述代码中,首先通过输入流读取了配置文件,然后根据配置文件构造了SqlSessionFactory对象。接下来通过SqlSessionFactory对象又创建了SqlSession对象,并通过SqlSession对象的selectOne()方法执行查询操作。selectOne()方法的第1个参数表示映射SQL的标识字符串,由UserMapper.xml中 < mapper >元素的namespace属性值+ < select >元素的id属性组成;第2个参数表示查询所需要的参数
这里查询的是用户表中id为1的用户。结果如下:
根据用户名模型查询用户信息
模糊查询的实现只需要在映射文件中 < select >元素编写相应的SQL语句,并通过SqlSession的查询方法执行该SQL语句即可
1.在映射文件UserMapper.xml中添加根据用户名模糊查询用户列表的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="mapper.UserMapper">
<select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
SELECT * from mybatis_text where id=#{id}
</select>
<select id="findUserByName" parameterType="String" resultType="com.ssm.po.User">
SELECT * from mybatis_text where username like '%${value}%'
</select>
</mapper>
在上述代码中,与根据用户编号查询相比,其中属性id,parameterType和SQL语句都发生了相应变化。其中,SQL语句中的" $ {}" 用来表示拼接SQL的字符串,即不加解释地原样输出。" ${valie}"表示要拼接的是简单类型参数。
注意:
在使用" $ {}"进行SQL字符串拼接时,无法防止SQL注入问题。想要既能实现模糊查询,又能防止SQL注入,可以使用MySQL中的concat函数进行字符串拼接,代码如下:
select * from mybatis_text where username like concat ('%',${value},‘%’)
2.在测试类MybatisTest中添加一个测试方法findUserByNameTest(),代码如下:
//模糊查询用户列表
public static void findUserByNameTest() throws Exception{
//1.读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//2.根据配置文件构建SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.通过SqlSessionFactory创建SqlSession实例
SqlSession session = sqlSessionFactory.openSession();
//4.SqlSession执行映射文件中定义的SQL,并返回映射结果
List<User> users = session.selectList("mapper.UserMapper.findUserByName","聪明");
//5.打印输出结果
System.out.println(users);
//6.关闭SqlSession
session.close();
}
在上述代码中,由于可能查询处多条结果,因此调用SqlSession的selectList()方法来查询返回结果的集合对象。运行结果如下:
我们已成功查询出用户表中用户名带有"聪明"的两条用户信息。
我们可以从上面两个查询方法总结出,MyBatis的操作大致可分为以下几个步骤:
- 读取配置文件
- 根据配置文件构建SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession
- 使用SqlSession对象操作数据库(包括查询、添加、修改、删除以及提交事务等)
- 关闭SqlSession
添加用户
1.在MyBatis的映射文件中,添加操作是通过< insert >元素来实现的。例如,向数据库中的mybatis_text表插入一条数据,代码如下:
<insert id="addUser" parameterType="com.ssm.po.User">
INSERT INTO mybatis_text(username,jobs,phone)VALUES (#{username},#{jobs},#{phone})
</insert>
在上述代码中,传入的参数是一个User类型,该类型的参数对象被传递到语句时,#{username}会查询参数对象User的username属性,#{jobs}和#{phone}也是一样的,并将其属性值传入SQL语句中
2.在MybatisTest中添加测试方法addUserTest(),代码如下:
//添加用户
public static void addUser() throws IOException {
//1.读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//2.根据配置文件构建SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.通过SqlSessionFactory创建SqlSession实例
SqlSession session = sqlSessionFactory.openSession();
//4.创建User对象
User user = new User();
user.setUsername("小鑫是美女");
user.setJobs("UI设计");
user.setPhone("1145623");
//5.SqlSession执行映射文件中定义的SQL,并返回映射结果
int row = session.insert("mapper.UserMapper.addUser",user);
if(row>0){
System.out.println("成功插入"+row+"条数据!");
}else{
System.out.println("添加数据失败");
}
//6.提交事务
session.commit();
//7.关闭SqlSession
session.close();
}
上述代码中,我们通过SqlSession对象的insert()方法执行插入操作,并通过该操作返回的数据来判断插入操作是否执行成功;最后通过SqlSession的commit()方法提交事务,最后通过SqlSession.close()方法关闭了SqlSession.
打开SQLyong,发生数据确实添加成功了。
更新用户
1.MyBatis的更新操作在映射文件中是通过配置< update >元素来实现的。例如,我们将id为4的用户数据进行修改,代码如下:
<update id="updateUser" parameterType="com.ssm.po.User">
UPDATE mybatis_text set username=#{username},jobs=#{jobs},phone=#{phone} where id=#{id};
</update>
2.在MybatisTest中添加测试方法updateUser(),代码如下:
//修改用户
public static void updateUser() throws IOException {
//1.读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//2.根据配置文件构建SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.通过SqlSessionFactory创建SqlSession实例
SqlSession session = sqlSessionFactory.openSession();
//4.创建User对象
User user = new User();
user.setId(4);
user.setUsername("小鑫是美女这是事实");
user.setJobs("UI设计大师");
user.setPhone("11456236");
//5.SqlSession执行映射文件中定义的SQL,并返回映射结果
int row = session.update("mapper.UserMapper.updateUser",user);
if(row>0){
System.out.println("成功更改"+row+"条数据!");
}else{
System.out.println("添加数据失败");
}
//6.提交事务
session.commit();
//7.关闭SqlSession
session.close();
}
与添加用户的方法相比,更新操作的代码增加了id属性值的设置,并调用SqlSession的update()方法对id为4的用户进行了修改。
打开SQLyong,发生id为4的用户确实得到了修改。
删除用户
MyBatis的删除操作在映射文件中是通过配置< delete >元素来实现的。例如,我们需要将id为4的数据进行删除,代码如下:
<delete id="deleteUser" parameterType="Integer">
DELETE FROM mybatis_text where id=#{id}
</delete>
2.在MybatisTest中添加测试方法deleteUser(),代码如下:
//根据id删除用户
public static void deleteUser() throws Exception{
//1.读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//2.根据配置文件构建SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.通过SqlSessionFactory创建SqlSession实例
SqlSession session = sqlSessionFactory.openSession();
//4.SqlSession执行映射文件中定义的SQL,并返回映射结果
int row = session.delete("mapper.UserMapper.deleteUser",4);
if(row>0){
System.out.println("成功删除了"+row+"条数据!");
}else{
System.out.println("添加数据失败");
}
//5.提交事务
session.commit();
//6.关闭SqlSession
session.close();
}
在上述代码中,我们调用了SqlSession对象的delete()方法并传入需要删除数据的用户id值即可。
打开SQLyong,发生id为4的用户确实删除了。
注意
在删除、修改、添加用户操作上,我们必须要执行 session.commit();来提交事务,不然不会更改数据库中的数据。大家可以自己测试。