MyBatis增删改查(步骤详细,由浅入深,适合初学者,只看这一篇就够了)
MyBatis目录
java(后端框架)MyBatis的使用
mybatis的简介这里就不多说了,百度一大堆,我们只需要这是一个JDBC的升级版,让我们更好的操作数据库,减少不必要的代码,让我们专注于实现自己的业务逻辑.
web开发的三层架构 (mvc )
-
三层架构
界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果的。(jsp ,html ,servlet)
业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
数据访问层: 就是访问数据库, 执行对数据的查询,修改,删除等等的。三层对应的包
界面层: controller包 (servlet)
业务逻辑层: service 包(XXXService类)
数据访问层: dao包(XXXDao类)三层中类的交互
用户使用界面层–> 业务逻辑层—>数据访问层(持久层)–>数据库(mysql)三层对应的处理框架
界面层—servlet—springmvc(框架)
业务逻辑层—service类–spring(框架)
数据访问层—dao类–mybatis(框架)
使用 JDBC 的缺陷
- 代码比较多,开发效率低
- 需要关注 Connection ,Statement, ResultSet 对象创建和销毁
- 对 ResultSet 查询的结果,需要自己封装为 List
- 重复的代码比较多些
- 业务代码和数据库的操作混在一起
MyBatis 解决的主要问题
mybatis完全是一个升级版的JDBC,他是可以完全独立抽取出来的使用的.
MyBatis 可以完成:
- 注册数据库的驱动,
- 创建 JDBC 中必须使用的 Connection , Statement, ResultSet 对象
- 从 xml 中获取 sql,并执行 sql 语句,把 ResultSet 结果转换 java 对象
4.关闭资源
ResultSet.close() , Statement.close() , Conenection.close()
mybatis使用步骤:
1.导入maven环境
2.创建dao接口,里面定了你需要对数据库执行什么操作
3.编写mapper文件,sql映射文件,写上你的sql语句
4.创建mybatis主配置文件,读取配置文件中的内容,连接到数据库
5.使用mybatis对象执行sql语句:sqlSession对象
6.关闭连接:sqlSession.close();
1.mybatis基本使用
新建数据库表
CREATE TABLE
t_user
(
id
int NOT NULL AUTO_INCREMENT,
username
varchar(255) DEFAULT NULL,
password
varchar(255) DEFAULT NULL,
email
varchar(255) DEFAULT NULL,
phone
varchar(255) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
1.使用maven新建一个项目(项目 目录结构)
1.1准备一个java Use 类
public class User {
private Integer id;
private String username;
private String password;
private String email;
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public User() {
}
public User(Integer id, String username, String password, String email, String phone) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
2.配置pom.xml文件导入相应的依赖包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mybais</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!-- 把mybatis配置文件拷贝到target/clasess目录下-->
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
3.编写dao接口
public interface UserManagerDao {
/**
* 查询所有的数据 用于视图展示
* @return 返回一个List集合
*/
public List<User> queryUser();
/**
* 添加
* @param user 一个user对象
* @return 成功返回true 失败返回false
*/
public Boolean addUser(User user);
/**
* 删除用户
* @param id 需要删除的用户id
* @return 成功返回true 失败返回false
*/
public Boolean delUser(String id);
/**
* 修改用户信息
* @param user 需要一个user对象
* @return 成功返回true 失败返回false
*/
public Boolean updateUser(User user);
/**
* 按照用户名查找用户
* @param name 需要查找的用户名
* @return 返回一个List集合
*/
public List<User> likeUser(String name);
}
4.编写dao接口的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:必须有值,自定义的唯一字符串
推荐使用:dao 接口的全限定名称
-->
<mapper namespace="bookMall.dao.UserManagerDao">
<select id="queryUser" resultType="bookMall.bean.User" >
<!--查询操作-->
select id,username,password,email,phone from t_user where id>0
</select>
<select id="likeUser" resultType="bookMall.bean.User" >
<!--跟参数的查询操作-->
select id,username,password,email,phone from t_user where username=#{username}
</select>
<!--添加操作-->
<insert id="addUser" >
insert into t_user values(#{id},#{username},#{username},#{email},#{phone})
</insert>
</mapper>
5.资源目录下的 mybatis.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>
<!--环境配置: 数据库的连接信息 default:必须和某个environment的id值一样。 告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库 -->
<environments default="mydev">
<!-- environment : 一个数据库信息的配置, 环境 id:一个唯一值,自定义,表示环境的名称。 -->
<environment id="mydev">
<!--transactionManager :mybatis的事务类型 type: JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理) -->
<transactionManager type="JDBC"/>
<!-- dataSource:表示数据源,连接数据库的 type:表示数据源的类型, POOLED表示使用连接池 -->
<dataSource type="POOLED">
<!-- driver, user, username, password 是固定的,不能自定义。 -->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost/book_ctiy?serverTimezone=GMT%2B8"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="2732195202"/>
</dataSource>
</environment>
</environments>
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个文件的位置。 从类路径开始的路径信息。 target/clasess(类路径)-->
<mapper resource="bookMall\dao\UserManagerDao.xml"/>
</mappers>
</configuration>
6.测试是否可以用
@Test
void queryUser() throws IOException {
//访问mybatis读取student数据
//1.定义mybatis主配置文件的名称, 从类路径的根开始(target/clasess)
String config="mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建了SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6.【重要】指定要执行的sql语句的标识。 sql映射文件中的namespace + "." + 标签的id值
String sqlId = "bookMall.dao.UserManagerDao" + "." + "queryUser";
// String sqlId = "bookMall.dao.UserManagerDao";
//7. 重要】执行sql语句,通过sqlId找到语句
List<User> studentList = sqlSession.selectList(sqlId);
//8.输出结果
//studentList.forEach( stu -> System.out.println(stu));
for(User user : studentList){
System.out.println("查询的学生="+user);
}
//9.关闭SqlSession对象
sqlSession.close();
}
7.测试结果:
注意事项:
1:target目录下一定要有这两个文件,如果没有,手动复制进去也行
2.mysql的依赖配置如果是高版本的:
driver的值是:com.mysql.cj.jdbc.Driver
3.mysql的依赖配置如果是高版本的,url是这样的:
dbc:mysql://localhost/book_ctiy?serverTimezone=GMT%2B8
一定要加上时区,不然会报错
4.在pom.xml配置文件中需要加上,才能更好的将pom.xml和UserManagerDao.xml文件映射出去
2.mybatis工具类的封装和实现增删改查
项目的目录结构: :
需要注意的是target目录下必须有标记红色框的那两个文件,否则执行的时候回报错
1.准备数据库表
CREATE TABLE `t_user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `t_user`(`id`, `username`, `password`, `email`, `phone`) VALUES (1, 'admin', 'admin', 'admin@qq.com', '1008611');
INSERT INTO `t_user`(`id`, `username`, `password`, `email`, `phone`) VALUES (2, 'root', 'root', 'root@qq.com', '1008622');
INSERT INTO `t_user`(`id`, `username`, `password`, `email`, `phone`) VALUES (19, 'admin2', 'root2', 'root@qq.com2', '1008644');
2.创建实体类
public class User {
private Integer id;
private String username;
private String password;
private String email;
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public User() {
}
public User(Integer id, String username, String password, String email, String phone) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
3.创建maven项目,大多数配置一样,但是某些配置根据自己的来
注意:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
因为我的jdk9,所以我写的就是9,你们根据自己的jdk版本来写.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!-- 把mybatis配置文件拷贝到target/clasess目录下-->
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
4.配置mybatis的主配置文件
注意点:
mysql驱动包如果是高版本的:
driver的值需要些成:com.mysql.cj.jdbc.Driver 否则会报异常
url需要加上时区:否则执行会报错
url= jdbc:mysql://主机名/数据库名?serverTimezone=GMT%2B8
<?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>
<!-- <settings>
<!-- 输出mybatis 执行sql 语句的日志信息-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
-->
<environments default="localhost">
<!-- environment : 一个数据库信息的配置, 环境 id:一个唯一值,自定义,表示环境的名称。 -->
<environment id="localhost">
<!--transactionManager :mybatis的事务类型 type: JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理) -->
<transactionManager type="JDBC"/>
<!-- dataSource:表示数据源,连接数据库的 type:表示数据源的类型, POOLED表示使用连接池 -->
<dataSource type="POOLED">
<!-- driver, user, username, password 是固定的,不能自定义。 -->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost/book_ctiy?serverTimezone=GMT%2B8"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="2732195202"/>
</dataSource>
</environment>
</environments>
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个文件的位置。 从类路径开始的路径信息。 target/clasess(类路径)-->
<mapper resource="com\mybatis\dao\UserManagerDao.xml"/>
</mappers>
</configuration>
5.编写mybatis工具类
工具类就是为了简化代码,因为有很多重复写,而且没有意义的代码,可以创建工具类,有工具类完成,使我们的代码更加简洁.
public class MyBatisUtils {
private static SqlSessionFactory factory = null;
static {
//读取mybatis.xml配置文件
String config="mybatis.xml";
try {
//将配置文件加入到流中
InputStream in = Resources.getResourceAsStream(config);
//创建factory对象
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (factory!=null){
//如果 factory!=null 就创建 sqlSession对象
sqlSession = factory.openSession(false);//非自动提交事务
}
return sqlSession;
}
}
5.定义dao接口,看我们需要实现哪些功能
public interface UserManagerDao {
/**
* 查询所有的数据 用于视图展示
* @return 返回一个List集合
*/
public List<User> queryUser();
/**
* 添加
* @param user 一个user对象
* @return 成功返回true 失败返回false
*/
public Boolean addUser(User user);
/**
* 删除用户
* @param id 需要删除的用户id
* @return 成功返回true 失败返回false
*/
public Boolean delUser(String id);
/**
* 修改用户信息
* @param user 需要一个user对象
* @return 成功返回true 失败返回false
*/
public Boolean updateUser(User user);
/**
* 按照用户名查找用户
* @param name 需要查找的用户名
* @return 返回一个List集合
*/
public List<User> likeUser(String name);
}
6.编写Dao.xml文件.让这个xml文件去代替我们的JDBC
注意点:
mapper 标签的namespace的值
尽量按照这个规范:com.mybatis.dao.UserManagerDao
方便后面使用动态代理,使用反射机制.
模糊查询的sql语句参数是$不是#
是这样
select * from t_user where username like '%${username}%'
而不是这样
select * from t_user where username like '%#{username}%'
<?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.mybatis.dao.UserManagerDao">
<select id="queryUser" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user
</select>
<select id="likeUser" parameterType="String" resultType="com.mybatis.bean.User">
select * from t_user where username like '%${username}%'
</select>
<insert id="addUser">
insert into t_user values(#{id},#{username},#{username},#{email},#{phone})
</insert>
<delete id="delUser">
delete from t_user where id=#{id}
</delete>
<update id="updateUser">
update t_user set username=#{username},password=#{password},email=#{email},phone=#{phone} where id=#{id}
</update>
</mapper>
7.编写daoImpl
注意点:
执行完sql语句之后一定要几点关闭数据库连接
sqlSession.close();
在执行增删改的时候mybatis是默认手动提交事务,需要我们手动设置为自动提交事务
方法1: sqlSession.commit();
方法2:在工具类中设置:sqlSession = factory.openSession(true);//自动提交事务
public class UserManagerDaoImpl implements UserManagerDao {
/**
* 查询所有的数据 用于视图展示
*
* @return 返回一个List集合
*/
@Override
public List<User> queryUser() {
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.mybatis.dao.UserManagerDao.queryUser";
//执行sql语句
List<User> userList = sqlSession.selectList(sqlId);
// sqlSession.commit(); //mybatis默认不会手动提交事务,在修改数据之后要 提交事务
//关闭连接
sqlSession.close();
return userList;
}
/**
* 添加
*
* @param user 一个user对象
* @return 成功返回true 失败返回false
*/
@Override
public Boolean addUser(User user) {
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.mybatis.dao.UserManagerDao.addUser";
//执行sql语句
int updateCount = sqlSession.update(sqlId,user);
sqlSession.commit(); //mybatis默认不会手动提交事务,在修改数据之后要 提交事务
//关闭连接
sqlSession.close();
if(updateCount>0){
return true;
}else{
return false;
}
}
/**
* 删除用户
*
* @param id 需要删除的用户id
* @return 成功返回true 失败返回false
*/
@Override
public Boolean delUser(String id) {
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.mybatis.dao.UserManagerDao.delUser";
//执行sql语句
int delete = sqlSession.delete(sqlId, id);
sqlSession.commit(); //设置为自动提交事务
//关闭连接
sqlSession.close();
if(delete>0){
return true;
}else {
return false;
}
}
/**
* 修改用户信息
*
* @param user 需要一个user对象
* @return 成功返回true 失败返回false
*/
@Override
public Boolean updateUser(User user) {
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.mybatis.dao.UserManagerDao.updateUser";
//执行sql语句
int updateCount = sqlSession.update(sqlId,user);
sqlSession.commit(); //设置为自动提交事务
//关闭连接
sqlSession.close();
if(updateCount>0){
return true;
}else {
return false;
}
}
/**
* 按照用户名查找用户
*
* @param name 需要查找的用户名
* @return 返回一个List集合
*/
@Override
public List<User> likeUser(String name) {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.mybatis.dao.UserManagerDao.likeUser";
List<User> userList = sqlSession.selectList(sqlId, name);
sqlSession.commit();
//关闭连接
sqlSession.close();
return userList;
}
}
8.编写Test类 测试我们的方法是否可用
class UserManagerDaoImplTest {
UserManagerDaoImpl userManagerDao = new UserManagerDaoImpl();
@Test
void queryUser() {
List<User> userList = userManagerDao.queryUser();
for (User user : userList) {
System.out.println(user);
}
}
@Test
void ListUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao userDao = sqlSession.getMapper(UserManagerDao.class);
List<User> userList = userDao.queryUser();
for (User user : userList) {
System.out.println(user);
}
}
@Test
void addUser() {
User user = new User(null,"admin","root","root@qq.com","1008644");
Boolean flag = userManagerDao.addUser(user);
System.out.println(flag);
}
@Test
void delUser() {
Boolean flag = userManagerDao.delUser("23");
System.out.println(flag);
}
@Test
void updateUser() {
User user = new User(19,"admin2","root2","root@qq.com2","1008644");
Boolean flag = userManagerDao.updateUser(user);
System.out.println(flag);
}
@Test
void likeUser() {
List<User> userList = userManagerDao.likeUser("admin");
for (User user : userList) {
System.out.println(user);
}
}
}
3.mybatis中主要类的介绍
- Resources: mybatis中的一个类, 负责读取主配置文件
InputStream in = Resources.getResourceAsStream(“mybatis.xml”);
2.SqlSessionFactoryBuilder : 创建SqlSessionFactory对象,
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
3.SqlSessionFactory : 重量级对象, 程序创建一个对象耗时比较长,使用资源比较多。
SqlSessionFactory:接口 , 接口实现类: DefaultSqlSessionFactory
SqlSessionFactory作用: 获取SqlSession对象。
SqlSession sqlSession = factory.openSession();
openSession()方法说明:
1. openSession() :无参数的, 获取是非自动提交事务的SqlSession对象
2. openSession(boolean): openSession(true) 获取自动提交事务的SqlSession.
openSession(false) 非自动提交事务的SqlSession对象
4.SqlSession: 执行sql语句的对象
SqlSession接口 :定义了操作数据的方法 例如 selectOne() ,selectList() ,insert(),update(), delete(), commit(), rollback()
SqlSession接口的实现类DefaultSqlSession。
使用要求: SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。
在执行完sql语句后,需要关闭它,执行SqlSession.close(). 这样能保证他的使用是线程安全的
4.nybatis实现动态代理:(使用的是反射机制,重点掌握)
在mybatis增删改查的基础上,我们只需要删除daoImpl实现类就好了,其余的不变
使用mybatis动态代理的注意事项:
测试userManagerDao中的接口方法
class UserManagerDaoImplTest {
//mybatis动态代理
@Test
void queryUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<User> userList = mapper.queryUser();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
@Test
void addUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
sqlSession.commit();
User user = new User(null,"admin","root","root@qq.com","1008644");
Boolean flag = mapper.addUser(user);
System.out.println(flag);
sqlSession.close();
}
@Test
void delUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
Boolean flag = mapper.delUser("19");
sqlSession.commit();
System.out.println(flag);
sqlSession.close();
}
@Test
void updateUser() {
User user = new User(19,"admin","root","root@qq.com2","1008644");
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
Boolean flag = mapper.updateUser(user);
sqlSession.commit();
System.out.println(flag);
sqlSession.close();
}
@Test
void likeUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
sqlSession.commit();
List<User> userList = mapper.likeUser("admin");
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
5.mybatis参数传递:
其实传参的方式有很多种,我们掌握以下三种,已经完全够用,如果不够用可以上网查看更多的传参方式。
使用@Param进行传参:
1.1接口中的写法
/**
* 使用@Param自定义传值
* @return 返回一个List集合
*/
public List<User> queryUserList(@Param("myId") String id);
1.2.dao.xml文件中的写法 @Param(“myId”) 和我们的参数是相对应的
<select id="queryUserList" parameterType="int" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user where id=#{myId}
</select>
1.3.使用动态代理的时候传参方式
//使用@Param 自定义参数传值
@Test
void queryUserList() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<User> userList = mapper.queryUserList("1");
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
使用java对象进行传参:
2.dao接口
/**
* 修改用户信息 使用对象传值
* @param user 需要一个user对象
* @return 成功返回true 失败返回false
*/
public Boolean updateUser(User user);
2.2.dao.xml文件配置
<!--使用对象传值: #{对象的属性名} -->
<update id="updateUser">
update t_user set username=#{username},password=#{password},email=#{email},phone=#{phone} where id=#{id}
</update>
2.3.调用dao接口方法
@Test
void updateUser() {
User user = new User(19,"admin","root","root@qq.com2","1008644");
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
Boolean flag = mapper.updateUser(user); //参数类型无限制,底层使用泛型
sqlSession.commit();
System.out.println(flag);
sqlSession.close();
}
3:使用map集合传参
3.1集合中传map集合
/**
* 使用map集合传值
* @return 返回一个List集合
*/
public List<User> queryUserMap(Map<String,Object> map);
3.2dao.xml中使用map的key值进行传参
<!-- 使用map传值-->
<select id="queryUserMap" parameterType="map" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user where id=#{id}
</select>
3.3测试类的实现
//使用map集合传递参数
@Test
void queryUserMap() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
Map<String,Object> map = new HashMap<>();
map.put("id",1);
List<User> userList = mapper.queryUserMap(map);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
6.$和#的区别(重点掌握)
select id,name, email,age from student where id=#{studentId}
(#) 的结果: select id,name, email,age from student where id=?
select id,name, email,age from student where id=${studentId}
( $) 的结果:select id,name, email,age from student where id=1001
String sql=“select id,name, email,age from student where id=” + “1001”;
使用的Statement对象执行sql, 效率比PreparedStatement低。
$:可以替换表名或者列名, 你能确定数据是安全的。可以使用$
# 和 $ 区别
1. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
2. #能够避免sql注入,更安全。
3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
4. $有sql注入的风险,缺乏安全性。
5. $:可以替换表名或者列名
7.ResultType的使用
mybatis返回值类型支持的别名机制对应表
resultType:的返回值可以是别名,也可以是返回值类型的全限定义名称(可以是任意类型)
自定义 resultType:的返回值类型
第一种方式:
1.在mybatis主配置文件中加上typeAliases标签
<!-- 定义别名:-->
<typeAliases> <!-- 可以指定一个类型的别名:type:自定义的全限定名称-->
<typeAlias type="com.mybatis.bean.User" alias="User"></typeAlias>
</typeAliases>
2.在dao.xml文件中使用即可
<select id="queryUser" resultType="User">
select id,username,password,email,phone from t_user
</select>
第二种方式:
1.在mybatis主配置文件中:
<typeAliases> <!-- package是包名 ,这个包中所有的类,类名就是别名,不区分大小写-->
<!-- 定义别名2:-->
<package name="com.mybatis.bean"/>
</typeAliases>
2.在dao.xml文件中使用即可
<select id="queryUser" resultType="User">
select id,username,password,email,phone from t_user
</select>
查询结果的返回值
1.返回map类型
1.1dao接口
/**
* 返回map集合
* @return
*/
public Map<Object,Object> queryResultMap(Integer id);
1.2dao.xml配置文件
<!-- 设置返回值为map-->
<select id="queryResultMap" resultType="java.util.HashMap" >
select username,password from t_user where id=#{id}
</select>
1.3测试类
//设置返回值为Map类型
@Test
void queryResultMap() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
Map<Object, Object> objectMap = mapper.queryResultMap(1);
System.out.println(objectMap);
sqlSession.close();
}
2.返回对象
2.1 dao接口
/**
* 按照用户名查找用户
* @param name 需要查找的用户名
* @return 返回一个List集合
*/
public List<User> likeUser( @Param("username") String name);
2.2dao接口配置文件
<select id="likeUser" parameterType="String" resultType="com.mybatis.bean.User">
select * from t_user where username like '%${username}%'
</select>
2.3测试方法
@Test
void likeUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
sqlSession.commit();
List<User> userList = mapper.likeUser("admin");
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
使用Map映射关系解决数据库列名和实体类对象属性名不一致,
导致反射异常无法赋值的解决方案:一 (重点掌握)
1.1dao接口方法
/**
* 使用Map定义映射关系 解决数据库列名和对象属性名不一致的方法1
* @return 返回list集合
*/
public List<Student> selectStudents();
1.2dao接口配置文件
<!-- 使用map映射关系,解决数据库列名和对象属性名不一致反射异常的情况
id:自定义名陈 type:java类型的全限定名称
column:列名 property :对象属性名
-->
<resultMap id="studentMap" type="com.mybatis.bean.Student">
<id column="id" property="idStudent"></id> <!-- 主键列 -->
<result column="username" property="usernameStudent"></result> <!-- 普通列 -->
<result column="password" property="passwordStudent"></result> <!-- 普通列 -->
<result column="email" property="emailStudent"></result> <!-- 普通列 -->
<result column="phone" property="phoneStudent"></result> <!-- 普通列 -->
</resultMap>
<select id="selectStudents" resultMap="studentMap">
select id,username,password,email,phone from t_user
</select>
1.3测试是否可行
//使用map映射解决数据库列名和对象属性名不一致导致反射异常无法赋值的解决方案1
@Test
void selectStudents() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<Student> students = mapper.selectStudents();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
数据库表:
实体类对象属性:
测试结果 : ok 可行
使用给列名起别名解决数据库列名和实体类对象属性名不一致,
导致反射异常无法赋值的解决方案:2 (重点掌握)
2.1dao接口方法
/**
* 使用列别名的方式 解决数据库列名和对象属性名不一致的方法2
* @return 返回list集合
*/
public List<Student> queryStudents();
2.2 dao接口配置文件
<select id="queryStudents" resultType="com.mybatis.bean.Student">
select id as idStudent ,username as usernameStudent,password as passwordStudent,email as emailStudent,phone as phoneStudent from t_user
</select>
2.3 测试方法
//使用列别名解决数据库列名和对象属性名不一致导致反射异常无法赋值的解决方案1
@Test
void queryStudents() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<Student> students = mapper.queryStudents();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
总结:两种都可以 :不过第二种要简单一些;
8.动态sql
if , where, Foreach的使用
MyBatis工具类
public class MyBatisUtils {
private static SqlSessionFactory factory = null;
static {
//读取mybatis.xml配置文件
String config="mybatis.xml";
try {
//将配置文件加入到流中
InputStream in = Resources.getResourceAsStream(config);
//创建factory对象
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (factory!=null){
//如果 factory!=null 就创建 sqlSession对象
sqlSession = factory.openSession(false);//非自动提交事务
}
return sqlSession;
}
}
1.1 dao接口
public interface UserManagerDao {
/**
* 动态sql的使用 在使用动态sql 的时候 需要使用java对象作为参数
* @param user 传入一个user对象
* @return
*/
public List <User> selectUserIf( User user);
/**
* 动态sql的使用 在使用动态sql 的时候 需要使用java对象作为参数
* @param user 传入一个user对象
* @return
*/
public List <User> selectUserWhere( User user);
/**
* 动态sql的使用 在使用动态sql 的时候 需要使用java对象作为参数
* @param idList 传入一个int List集合
* @return
*/
public List <User> selectUserForeachInteger(List<Integer> idList);
/**
* 动态sql的使用 在使用动态sql 的时候 需要使用java对象作为参数
* @param studentList 传入一个int List集合
* @return
*/
public List <User> selectUserForeachUser(List<User> studentList);
}
1.2 dao.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.mybatis.dao.UserManagerDao">
<!-- if
<if test="使用java对象的属性值作为判断条件,语法规则: 属性=xx值">
-->
<select id="selectUserIf" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user where
<if test="username !=null and username !='' ">
username = #{username}
</if>
<if test="id >0 ">
and id>#{id}
</if>
</select>
<!-- where
<where> 用来包含 多个<if>的, 当多个if有一个成立的, <where>会自动增加一个where关键字,
并去掉 if中多余的 and ,or等...
-->
<select id="selectUserWhere" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user
<where>
<if test="username !=null and username !='' ">
username = #{username}
</if>
<if test="id >0 ">
or id>#{id}
</if>
</where>
</select>
<!-- Foreach List<Integer>
collection="接口中参数的数据类型,如果是数组使用array,如果是集合,是List"
item="自定义的,表示数组和集合的成员变量"
open="循环开始时候开始字符"
close="循环的时候的结束的字符"
separator="集合成员之间的分隔符"
-->
<select id="selectUserForeachInteger" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user where id in
<foreach collection="list" item="myId" open="(" close=")" separator=",">
#{myId}
</foreach>
</select>
<!-- Foreach List<User>
collection="接口中参数的数据类型,如果是数组使用array,如果是集合,是List"
item="自定义的,表示数组和集合的成员变量"
open="循环开始时候开始字符"
close="循环的时候的结束的字符"
separator="集合成员之间的分隔符"
#{user.id}:循环对象的某个属性值
-->
<select id="selectUserForeachUser" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user where id in
<foreach collection="list" item="user" open="(" close=")" separator=",">
#{user.id}
</foreach>
</select>
</mapper>
1.3 测试方法
class UserManagerDaoImplTest {
//mybatis动态sql
@Test
void selectUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
User user = new User();
user.setUsername("admin");
user.setId(0);
List<User> userList = mapper.selectUserIf(user);
for (User users : userList) {
System.out.println(users);
}
}
@Test
void selectUserWhere() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
User user = new User();
user.setUsername("");
user.setId(2);
List<User> userList = mapper.selectUserWhere(user);
for (User users : userList) {
System.out.println(users);
}
}
@Test
void selectUserForeachInteger() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
List<User> userList = mapper.selectUserForeachInteger(list);
for (User user : userList) {
System.out.println(user);
}
}
@Test
void selectUserForeachUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<User> userList = new ArrayList<User>();
User userOne = new User();
userOne.setId(1);
userList.add(userOne);
User userTwo = new User();
userOne.setId(2);
userList.add(userTwo);
List<User> userLists = mapper.selectUserForeachUser(userList);
for (User user : userList) {
System.out.println(user);
}
}
}
9.代码片段(sql语句重复使用)
1.先定义 <sql id="自定义名称唯一"> sql语句, 表名,字段等 </sql>
2.再使用, <include refid="id的值" />
1.1 dao接口
/**
* sql 语句重复使用
* @param studentList 传入一个int List集合
* @return
*/
public List <User> sqlRepeat(List<User> studentList);
1.2 dao.xml配置文件
<!-- 自定义sql 语句片段 -->
<sql id="userSql" >
select id,username,password,email,phone from t_user where id in
</sql>
<select id="sqlRepeat" resultType="com.mybatis.bean.User">
<include refid="userSql"></include>
<foreach collection="list" item="user" open="(" close=")" separator=",">
#{user.id}
</foreach>
</select>
1.3 测试方法
//重复使用sql
@Test
void sqlRepeat() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
List<User> userList = new ArrayList<User>();
User userOne = new User();
userOne.setId(1);
userList.add(userOne);
User userTwo = new User();
userOne.setId(2);
userList.add(userTwo);
List<User> userLists = mapper.selectUserForeachUser(userList);
for (User user : userList) {
System.out.println(user);
}
}
10.mybatis配置文件中,使用配置文件的方式获取连接
1.mybatis.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>
<!-- 使用读取配置文件的方式 从类路径跟开始找文件-->
<properties resource="jdbc.properties"/>
<environments default="localhost">
<environment id="localhost">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库的驱动类名-->
<property name="driver" value="${jdbc.driver}"/>
<!--连接数据库的url字符串-->
<property name="url" value="${jdbc.url}"/>
<!--访问数据库的用户名-->
<property name="username" value="${jdbc.user}"/>
<!--密码-->
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<mapper resource="com\mybatis\dao\UserManagerDao.xml"/>
</mappers>
</configuration>
2.配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
#连接数据库的URL
jdbc.url=jdbc:mysql://localhost/book_ctiy?serverTimezone=GMT%2B8
#用户名
jdbc.user=root
#密码
jdbc.password=2732195202
mapper文件映射的2中方式
<!-- sql mapper(sql映射文件)的位置-->
<mappers>
<!-- 一个mapper标签指定一个文件的位置。 从类路径开始的路径信息。 target/clasess(类路径) -->
<mapper resource="com\mybatis\dao\UserManagerDao.xml"/>
<!--
mapper文件所在的包名,这个包中的所有文件都将会一次性加载给mybatis
要求:1.mapper文件名称和接口文件名一样,区分大小写
2.mapper文件名称和接口文件需要在同一目录
-->
<package name="com.mybatis.dao"/>
</mappers>
11.mybatis分页查询
1.pom.xml中导入依赖
<!-- 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version> 5.1.10</version>
</dependency>
2.在mybatis配置文件中配置插件environments标签之前
<!--配置分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3.dao接口方法
/**
* 使用pageHelper 分页查询数据
* @return
*/
public List<User> selectAll();
4.dao.xml配置文件
<!--分页查询-->
<select id="selectAll" resultType="com.mybatis.bean.User">
select id,username,password,email,phone from t_user
</select>
5.测试方法
//分页查询
@Test
void selectAll() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserManagerDao mapper = sqlSession.getMapper(UserManagerDao.class);
// pageNum:从第几页开始 pageSize:一页中有多少条数据
PageHelper.startPage(1,3);
List<User> userList = mapper.selectAll();
List<User> userLists = mapper.selectUserForeachUser(userList);
for (User user : userList) {
System.out.println(user);
}
}
扩展资料
<!-- settings是 MyBatis 中全局的调整设置,它们会改变 MyBatis 的运行时行为,应谨慎设置 -->
<settings>
<!-- 该配置影响的所有映射器中配置的缓存的全局开关。默认值true -->
<setting name="cacheEnabled" value="true"/>
<!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认值false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 是否允许单一语句返回多结果集(需要兼容驱动)。 默认值true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。默认值true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 默认值false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 -->
<!-- 默认值PARTIAL -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<!-- 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。默认SIMPLE -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 设置超时时间,它决定驱动等待数据库响应的秒数。 -->
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<!-- 允许在嵌套语句中使用分页(RowBounds)默认值False -->
<setting name="safeRowBoundsEnabled" value="false"/>
<!-- 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 默认false -->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!-- MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。
默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。
若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 -->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!-- 指定哪个对象的方法触发一次延迟加载。 -->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
更多推荐
所有评论(0)