以下是原始的查询操作
//注册驱动
Class.forName("com,mysql.jdbcDriver");
//获得连接
Connection connection = Driverllanager.get(onnection( url: "jdbc:mysql:///test", user: "root", password: "123456");
//获得statement
statementPreparedStatement statement = connection.prepareStatement( sql: "select id,username,password from user");
//执行查询
ResultSet resultSet = statement .executeQuery();
//遍历结果集
while(resultSet.next()){
//封装实体
User user = new User();
user.setId(resultSet.getInt( columnLabel: "id"));
user.setUsername(resultSet .getString( columnLabel: "username"));
user.setPassword(resultSet.getString( columnLabel: "password"));
//user实体封装完毕
System.out.printIn(user);
}
//释放资源
resultSet.close();
statement .close();
connection.close();
无论是原始的查询操作、插入操作、删除操作,都需要做重复的工作:
这种原始Jdbc操作的弊端是:
应对上述问题,MyBatis可以给出对应的解决方案:
MyBatis开发步骤如下:
添加MyBatis坐标
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
添加SQL连接的坐标
<dependency>
<groupId>com.mysqlgroupId>
<artifactId>mysql-connector-jartifactId>
<version>8.0.33version>
dependency>
这里需要安装MySQL,选择性安装Navicat(可视化界面)。
只安装MySQL用一下建表语句创建就行,可视化界面创建相对而言比较方便一些。
这里用Navicat创建了user数据表:
在com.example.demo.domain
包里创建User类,通过Alt+Insert
快速创建所有的Setter和Getter方法
package com.example.demo.domain;
public class User {
int id;
String username;
String password;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
这个映射文件里边写的是SQL语句
在Resource下建立UserMapper.xml
,写入以下代码:
在写第一个标签mapper的时候注意要指定命名空间namespace
。因为可能有很多个mapper文件,每个mapper文件中可能都有“findAll”方法,指定命名空间可以快速定义到某mapper文件下的某个方法:命名空间.方法id
,与下面的语句id
组成查询的标识
select
表示选择语句,类似的还有insert
、update
等等,id
类似于SQL语句的名称,和上面的命名空间组成查询标识,resultType
指定返回值,也就是让MyBatis把返回值封装到我们创建好的User类中,指定查询结果的实体类型,两个语句中间写的是具体的SQL语句
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="userMapper">
<select id="findAll" resultType="com.example.demo.domain.User">
select * from user
select>
mapper>
其中应该是一种指示xml格式的固定头,映射文件DTD约束头
编写好了SQL语句,我们还应当指定数据库的数据源,要不然代码无法运行
在Resource下建立SqlMapper.xml
,写入以下代码:
需要配置数据源环境、加载映射文件
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/UserMapper.xml">mapper>
mappers>
configuration>
其中应该是一种指示xml格式的固定头,这里与上面的区别就只有开始时候一个是
mapper
一个是configuration
,后面一个是-mapper
一个是-config
environments
指定默认的环境名称
environment
指定当前环境名称
transactionManager
指定事务管理类型是JDBC
dataSource
指定当前数据源类型是连接池,下面的property
数据源配置的基本参数
mapper
标签的作用是加载映射,加载方式有以下几种:
执行以下代码,每一步具体做的都已经加了注释:
package com.example.demo;
import com.example.demo.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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class DemoApplication {
public static void main(String[] args) throws IOException {
// 1. 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2. 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 3. 创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 4. 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行查询,获取结果User
List<User> userList = sqlSession.selectList("userMapper.findAll");
System.out.println(userList);
// 6. 释放资源
sqlSession.close();
}
}
结果为:
[User{id=0, username='aaa', password='bbb'}, User{id=1, username='ccc', password='ddd'}]
在SqlMapper.xml中加入如下的内容,该内容应该在标签
下:
其中,
表示插入操作,由于插入操作,我们应该向插入操作中传入具体需要插入的对象,即这里指定了一个parameterType
表示传入参数的类型,#{}
里边表示的是该parameterType下的具体属性
<insert id="insert" parameterType="com.example.demo.domain.User">
insert into user values(#{id},#{username},#{password})
insert>
测试的时候,代码就使用如下部分替代上面的查询部分。只要是对数据库执行更新的相关操作,就需要使用sqlSession.commit()
提交事务
// 插入操作
// 模拟User对象
User user = new User();
user.setUsername("eee");
user.setPassword("fff");
sqlSession.insert("userMapper.insert", user);
// MyBatis执行数据库更新相关操作,需要提交事务
sqlSession.commit();
在SqlMapper.xml中加入如下的内容,该内容应该在标签
下:
<update id="update" parameterType="com.example.demo.domain.User">
update user set username=#{username}, password=#{password} where id=#{id}
update>
测试代码:
// 修改操作
// 模拟User对象
User user = new User();
user.setId(2);
user.setUsername("ggg");
user.setPassword("hhh");
sqlSession.insert("userMapper.update", user);
// MyBatis执行数据库更新相关操作,需要提交事务
sqlSession.commit();
在SqlMapper.xml中加入如下的内容,该内容应该在标签
下:
注:Sql语句中使用#{任意字符串}
方式引用传递的单个参数
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
delete>
测试代码:
// 删除操作
sqlSession.insert("userMapper.delete", 2);
// MyBatis执行数据库更新相关操作,需要提交事务
sqlSession.commit();
在上面的SqlMapper.xml文件中,我们是已经把driver、url、username、password等信息写死了,可能这些信息来自外部文件,那么这时候我们可以在其中导入properties文件。
在SqlMapper.xml的
中加上:
<properties resource="jdbc.properties">properties>
jdbc.properties文件写如下属性:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456
并将原始的SqlMapper中写死的内容使用${}
来替代,完整的SqlMapper文件如下:
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties">properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/UserMapper.xml">mapper>
mappers>
configuration>
执行查询测试:
package com.example.demo;
import com.example.demo.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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class DemoApplication {
public static void main(String[] args) throws IOException {
// 1. 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2. 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 3. 创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 4. 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行查询,获取结果User
// 查询操作
List<User> userList = sqlSession.selectList("userMapper.findAll");
System.out.println(userList);
// 6. 释放资源
sqlSession.close();
}
}
可以正常打印出信息:
[User{id=0, username='aaa', password='bbb'}, User{id=1, username='ccc', password='ddd'}]
在MyBatis中给我们定义了一些别名:
我们在写删除操作时,原本的配置代码是:
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
delete>
但是parameterType
太长了,基于上面给出的别名表,我们可以修改成以下内容同样可用:
<delete id="delete" parameterType="int">
delete from user where id=#{id}
delete>
以上是一些简单类型可以直接进行替换,对于以下代码,如:
<select id="findAll" resultType="com.example.demo.domain.User">
select * from user
select>
我们想将其替换成:
<select id="findAll" resultType="user">
select * from user
select>
那么此时我们就需要使用typeAliases
来定义com.example.demo.domain.User
的别名为user
。
这个typeAliases
是写在sqlMapConfig.xml文件中的,写的时候需要注意顺序:
typeAliases
需要在properties
的后面、environments
的前面,标签中的type
指定类型,alias
指定别名:
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties">properties>
<typeAliases>
<typeAlias type="com.example.demo.domain.User" alias="user">typeAlias>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/UserMapper.xml">mapper>
mappers>
configuration>
此时,我们就可以将查询时候的resultType
写成这个别名了:
<select id="findAll" resultType="user">
select * from user
select>
运行后会正常查询:
[User{id=0, username='aaa', password='bbb'}, User{id=1, username='ccc', password='ddd'}]
SqlSessionFactory build(InputStream inputStream)
,通过加载mybatis的核心文件的输入流形式构建一个SqlSessionFactory
对象
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 加载SqlMapConfig.xml配置文件,成为一个输入流
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 输入流注入到工厂对象中,创建SqlSessionFactory对象,让工厂对象帮我们创建与数据交互的SqlSession对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
通过构建器创建SqlSession实例,常见的有如下两种方法:
SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
其中selectOne
就是返回一个对象
而后面的selectList
是返回多个对象
commit
和rollback
分别是提交和回滚