MyBatis学习
什么是MyBatis
他是一个持久层框架。可以实现对数据库的操作,可以看作是JDBC的高级版,解决JDBC的缺点。
能做什么
1)、注册驱动
2)、创建数据库的连接对象Connection、Statement、ResultSet
3)、执行sql语句,返回ResultSet
4)、处理ResultSet、把结果集中的数据转换为java对象,把java对象装进list集合中
5)、关闭数据库连接
6)、实现代码和sql语句的解耦。sql语句被单独提出来放在xml文件中
初次使用
首先找一份MyBatis的中文官方文档看一遍,就能大概做一遍
首先创建一个mysql表test_01,列名自己设。
创建一个maven工程导入日志功能依赖、单元测试依赖junit、mysql驱动依赖、最重要的还有MyBatis依赖
<?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>MyBatis01</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--加上这一段是为了防止写在包下的xml文件没有被加载到具体执行文件中--> 在实际运行中不加这一段就不会把写在包下的xml文件加载进入实际运行的target目录中,测试就会报错
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
创建一个实体类,属性和数据表的列名一致,有参、无参、get、set、toString方法
创建一个Dao,创建一个方法用来做对数据库的操作
创建完毕后,首先在main-->>resource目录下创建一个mybatis配置文件,名字随便。里面主要写连接数据库的配置和指定一个MyBatis的mapper文件【里面主要存着sql语句,一般放在Dao包里,跟所属的Dao名字前缀一样。】
在MyBatisConfig.xml中
里面写的是连接Mysql的相关配置和对属性进行赋值,这一点很方便,让我觉得只要保证mysql驱动版本对的上,然后再保证属性值对的上,就能成功连接数据库,没有以前那么多命名、获取链接一些问题。
在写URL时会需要一些参数用到连字符&,但是xml文件中不支持,这时可以用html实体中代表这些特殊符号的替代字符串将想要串联的参数串联起来,【就是特殊符号如果出错就百度html实体,把特殊符号里换成html实体字符串】
除了配置JDBC连接的配置外,还有一个mapper 标签里面写的是存放sql语句的xml文件的相对路径,mapper标签属性值使用斜线划分的,就是在main目录下的路径这个文件一般跟Dao方法在一个包里面,名字尽量相似一点。
<?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.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3308/mybatis?characterEncoding=utf8&useSSL=true&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/xlw/testMyBatis/dao/TestUserSql.xml"/>
</mappers>
</configuration>
在TestUserSql.xml文件中
这里里面,mapper标签后面的 namespace是命名空间【namespace的值里面用点号划分】,让它指向你的Dao方法,在里面通过调用<select>、<update>、<delete>、<insert>这些标签在标签里面写的 id名字一般跟Dao中执行这个sql操作的方法名一样,ResultType是希望查询后的结果返回的值的类型 而且在标签对之间的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="com.xlw.testMyBatis.dao.TestUserDao">
<select id="SelectUserById" resultType="com.xlw.testMyBatis.bean.TestUser">
select * from test_01 where test_id = 1
</select>
</mapper>
类型别名<来自官方文档>
类型别名是你的好帮手。使用它们,你就可以不用输入类的全限定名了。比如:
<!-- mybatis-config.xml 中 -->
<typeAlias type="com.someapp.model.User" alias="User"/>
<!-- SQL 映射 XML 中 -->
<select id="selectUsers" resultType="User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
然后就是单元测试
首先创建一个字符串,它的值是MyBatis的配置文件的名字。
使用Resources.getResourceAsStream获取到配置文件中的内容,并用inputStream对象接收。
然后用SqlSessionFactory的实现类SqlSessionFactoryBuilder().build(inputStream)将获取到的配置文件内容解析加载。
调用sqlSessionFactory.openSession创建一个SqlSession对象。
下面定义的String字符串是实际上执行的Dao中的方法,就是拼接字符串,不拼直接写也行。
用SqlSessionFactory中的selectOne方法把定义的字符串放进去,输出一下,并关闭sqlsession对象
这一套流程是固定的,能改的就是那两字符串输出内容。多用用就会了,后面会有更简洁的方法
@Test
public void test01() throws IOException {
String resource = "MyBatisConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
String sqlId = "com.xlw.testMyBatis.dao.TestUserDao"+"."+"SelectUserById";
TestUser testUser = sqlSession.selectOne(sqlId);
System.out.println(testUser);
sqlSession.close();
}
MyBatis---使用占位符
在保存着sql语句的xml配置文件中,进行操作数据库时,有时需要查询多个值,不能一直去更改数据,就可以使用占位符 #{自己看的懂得代称} 然后再通过调用方法时传入这个操作条件代表的值就可以省下功夫【一个参数时占位符随便叫,两个就要用@Param注解在参数和占位符之间建立映射】
在xml文件中
<!--查询-->
<select id="SelectUserById" resultType="com.xlw.testMyBatis.bean.TestUser">
select * from test_01 where test_id = #{test_id}
</select>
MyBatis---在MyBatis中添加日志
a)、在pom.xml文件中导入依赖
之后就能在控制台中看见运行的具体过程和一些日志
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
b)、修改配置文件
在MyBatis的配置文件中添加以下内容,就可以在输出下面看见日志
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
MyBatis---事务提交
在保存sql的配置文件中使用insert、update、delete都需要进行提交事务,才能实现对数据库的修改,否则尽管可以在输出中看见sql执行成功,但是实际上没有对数据库做出任何修改。 在控制台输出中我们通过日志发现 Setting autocommit to false ,即MyBatis中的自动提交事务默认是关闭的,需要自己调用commit方法手动提交
在sql.xml文件中
<!--添加-->
<insert id="AddUser">
insert into test_01 values (null,"寒江孤影","江湖故人","[email protected]")
</insert>
在测试类中
@Test
public void test02() throws IOException {
String resource = "MyBatisConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
String sqlId = "com.xlw.testMyBatis.dao.TestUserDao" + "." + "AddUser";
int i = sqlSession.insert(sqlId);
System.out.println(i);
// 在MyBatis中提交事务默认是手动提交,只执行sql语句不提交事务是无法完成添加insert、删除delete、修改update操作的
// 这个方法就是手动提交事务
sqlSession.commit();
sqlSession.close();
}
insert操作使用占位符
在上面进行insert操作时,没有使用占位符,为了省去修改操作,就可以使用占位符进行填充,在实际使用时再对占位符进行填充
<!--添加-->
<insert id="AddUser">
insert into test_01 values (null,#{test_name},#{test_password},#{test_email})
</insert>
在测试方法中
新建一个Object类型的对象,使用对应数据库表的实体类对象作为这个对象,调用对应的set方法设置对应的值。然后MyBatis在执行时会执行占位符中属性对应的get方法,将值拿出来放在那个占位符对应的位置,建议属性和占位符中名字要一样。
@Test
public void test02() throws IOException {
String resource = "MyBatisConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
String sqlId = "com.xlw.testMyBatis.dao.TestUserDao" + "." + "AddUser";
TestUser testUser = new TestUser();
testUser.setTest_name("水果捞");
testUser.setTest_password("123abc");
testUser.setTest_email("[email protected]");
int i = sqlSession.insert(sqlId,testUser);
System.out.println(i);
// 在MyBatis中提交事务默认是手动提交,只执行sql语句不提交事务是无法完成添加insert、删除delete、修改update操作的
// 这个方法就是手动提交事务
sqlSession.commit();
sqlSession.close();
}
使用时可能出现的问题
有时候会出现对应的sql.xml和配置文件不能被编译到具体执行的文件夹target下,解决办法
1、删了target重新编译
2、清除IDEA的缓存并重启IDEA
3、使用maven窗口提供的clean,再compile,跟第一种方式差不多,这个优雅点
4、点击Build重新编译本项目
自动提交事务
在SqlSession中可以发现有很多OpenSession方法,其中有一个SqlSession openSession(boolean var1);的方法。在调用OpenSession方法时添加参数true,就能将事务提交改为自动提交。
MyBatis---SqlSession和他的实现类DefaultSqlSession
在SqlSession中提供了方法来完成对数据库的操作。首先使用sqlSessionFactory的方法OpenSession获取到sqlSession对象,在调用这些方法。
多用就记住了
//它的作用就只是解析配置文件
Stri