目录
2.1、创建Maven项目,在Maven中加入mybatis依赖,mysql驱动依赖:
[2.1.1、 完整的POM文件如下:](#2.1.1、 完整的POM文件如下:)
2.1.2、Mybatis项目compile编译后classes目录下缺少.xml文件的问题总结:
2.3、创建表对应的实体类:student类,用来保存表中的每一行数据:
[2.5、创建这个表对应的sql映射文件,一个表一个sql映射文件 --- 用来写sql语句的:](#2.5、创建这个表对应的sql映射文件,一个表一个sql映射文件 --- 用来写sql语句的:)
[2.7、编写测试代码,使用mybatis --- 通过Mybatis访问数据库:](#2.7、编写测试代码,使用mybatis --- 通过Mybatis访问数据库:)
3.1、Resources:Mybatis中的一个类,负责读取主配置文件
[3.2、SqlSessionFactoryBuilder : 创建SqlSessionFactory对象](#3.2、SqlSessionFactoryBuilder : 创建SqlSessionFactory对象)
3.3、SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中,有一个就够用了
一、Mybatis查询数据库功能
- 创建Maven项目,在Maven中加入mybatis依赖,mysql驱动依赖
- 创建一张student表
- 创建表对应的实体类:student类,用来保存表中的每一行数据
- 创建持久层的DAO接口,用来定义操作数据库的方法
- 创建这个表对应的sql映射文件,一个表一个sql映射文件 ---用来写sql语句的
- 创建mybatis的主配置文件: 一个项目就一个mybatis的主配置文件,主配置文件提供了数据库的连接信息和sql映射文件的位置信息
- 编写测试代码,使用mybatis --- 通过Mybatis访问数据库
二、Mybatis查询数据库功能实现
2.1、创建Maven项目,在Maven中加入mybatis依赖,mysql驱动依赖:
XML
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
2.1.1、 完整的POM文件如下:
XML
<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>com.lifang</groupId>
<artifactId>mybatis02-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mybatis02-demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.conf</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>lib</directory>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</resources>
</build>
</project>
2.1.2、Mybatis项目compile编译后classes目录下缺少.xml文件的问题总结:
http://t.csdnimg.cn/RcolD 看我这篇博客
2.2、创建一张student表:
XML
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1001, '李四', 'lisi@qq.com', 20);
INSERT INTO `student` VALUES (1002, '张三', 'zhangsan@qq.com', 23);
SET FOREIGN_KEY_CHECKS = 1;
2.3、创建表对应的实体类:student类,用来保存表中的每一行数据:
2.4、创建持久层的DAO接口,用来定义操作数据库的方法:
java
public interface StudentDao {
//查询Student表中的所有数据:
public List<Student> selectStudents();
}
定义一个List集合,List集合中的每一个对象是一个学生,list集合中放的是student对象, ++++这个selectStudents()方法对应的是一个SQL语句的执行,SQL语句++++ 写在SQL映射的文件里面。
2.5、创建这个表对应的sql映射文件,一个表一个sql映射文件 ---用来写sql语句的:
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="com.lifang.dao.StudentDao">
<!--
<select>: 表示查询操作, 标签中必须是 select 语句
1、id: sql 语句的自定义名称,表示要执行的 sql 语句
推荐使用 dao 接口中的方法名称,
2、resultType: 查询语句的返回结果数据类型,sql语句执行完之后得到了ResultSet查询结果集,
遍历这个ResultSet得到的java对象的类型;使用类的全限定类名
-->
<select id="selectStudents" resultType="com.lifang.domain.Student">
select id,name,email,age from student
<!--要执行的 sql 语句
我们mybatis执行这条sql语句,会用我们的每一行记录来创建出一个studen对象,
并且把这些值赋值给这个对象的属性
-->
</select>
<!--插入操作-->
<insert id="insertStudent">
insert into student(id,name,email,age) values(#{id},#{name},#{email},#{age})
</insert>
<!--更新操作-->
<update>
</update>
<!--删除操作-->
<delete>
</delete>
</mapper>
2.6、创建mybatis的主配置文件:
++一个项目就一个Mybatis的主配置文件,主配置文件提供了数据库的配置信息和sql映射文件的位置信息。++
1、创建主配置文件:名称为 mybatis.xml
2、支持中文的 url:
jdbc:mysql://localhost:3306/sys?useUnicode=true\&characterEncoding=UTF-8
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>
<!--
settings:控制Mybatis的全局行为
-->
<settings>
<!--设置Mybatis输出日志,
可以在控制台输出执行的 sql 语句和参数(日志)-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!--
环境标签,配置mybatis环境,里面是数据库的配置信息,
可以写多个environment,
environments的default对应environment的id,
id可以自己起名,default写哪个id,则哪个environment生效
-->
<environments default="dev">
<!--id:数据源的名称-->
<environment id="dev">
<!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
<transactionManager type="JDBC"/>
<!--数据源 dataSource:
创建数据库 Connection 对象
type: POOLED 使用数据库的连接池
-->
<dataSource type="POOLED">
<!--连接数据库的四个要素-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/sys?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--SQL映射文件的位置信息-->
<mapper resource="com/lifang/dao/StudentDao.xml"/>
</mappers>
</configuration>
2.7、编写测试代码,使用mybatis --- 通过Mybatis访问数据库:
java
@org.junit.Test
public void test01(){
//定义mybatis主配置文件的名称,从target/classes类路径下开始的
String config = "mybatis.xml";
InputStream in = null;
try {
//读取配置文件
in = Resources.getResourceAsStream(config);
} catch (IOException e) {
throw new RuntimeException(e);
}
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
//sqlSession.getMapper(接口名.class);
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectStudents();
students.forEach(student -> System.out.println(student));
sqlSession.close();
}
2.7.1、测试结果如下:
2.8、注意事项:sqlSession.commit()
如果你openSession()没有设置自动提交,并且你没有在insert、delete、update之后提交事务sqlSession.commit(),那么会出现回滚的情况,数据库里也并不会有变更:
插入操作,id始终是自增的,回滚了之后,会从1008开始:
三、Mybatis中主要的类的介绍
3.1、Resources:Mybatis中的一个类,负责读取主配置文件
InputStream in = Resources.getResourceAsStream("mybatis.xml");
3.2、SqlSessionFactoryBuilder : 创建SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
3.3、SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中,有一个就够用了
SqlSessionFactory: 接口, 接口实现类: DefaultSqlSessionFactory
SlqSessionFactory作用:
获取SqlSession对象 Sqlsession sqlsession = factory.openSession();
3.4、openSession()方法说明:
1.openSession():无参数的话,默认获取的是非自动提交事务的SqlSession对象
2.openSession(boolean): openSession(true) 获取自动提交事务的SqlSession对象
openSession(false) 非自动提交事务的SqlSession对象
使用要求:如果没有设置自动提交事务的话,需要在insert、delete、update后手动提交事务:
sqlSession.commit();
3.5、SqlSession:
SqlSession接口:定义了操作数据的方法,例如selectOne()、selectList()、insert()、update()、delete()、commit()、rollback()、getMapper()
SqlSession接口的实现类DefaultSqlSession
使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象,在执行完sql语句后,需要关闭它,执行SqlSessioon.close(),这样能保证它的使用是线程安全的。
四、弊端---传统的Dao实现方式:
4.1、重复的类我们用工具把它包装起来:
java
public class MybatisUtils {
private static SqlSessionFactory factory = null;
static{
String config = "mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if(factory != null){
//非自动提交事务
sqlSession = factory.openSession();
}
return sqlSession;
}
}
4.2、StudentDao接口:
java
public interface StudentDao {
//查询Student表中的所有数据:
public List<Student> selectStudents();
public int insertStudent(Student student);
}
4.3、StudentDaoImpl实现类:
java
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.lifang.dao.StudentDao.selectStudents";
List<Student> students = sqlSession.selectList(sqlId);
sqlSession.close();
return students;
}
@Override
public int insertStudent(Student student) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.lifang.dao.StudentDao.insertStudent";
int nums = sqlSession.insert(sqlId,student);
sqlSession.commit();
sqlSession.close();
return nums;
}
}
4.4、Sql映射文件:
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="com.lifang.dao.StudentDao">
<!--
<select>: 表示查询操作, 标签中必须是 select 语句
1、id: sql语句自定义的名称,唯一值,要求使用dao接口的方法名
2、resultType: 结果类型,查询语句查询后得到ResultSet查询结果集,遍历这个查询结果集
得到的java对象的类型,推荐使用类的全限定名称
-->
<select id = "selectStudents" resultType="com.lifang.domain.Student">
select id,name,email,age from student order by id
</select>
<!--插入操作-->
<insert id="insertStudent">
insert into student(id,name,email,age) values(#{id},#{name},#{email},#{age})
</insert>
<!--更新操作
<update> </update>
-->
<!--删除操作
<delete> </delete>
-->
</mapper>
4.5、测试代码:
java
@org.junit.Test
public void test02(){
StudentDao dao = new StudentDaoImpl();
List<Student> students = dao.selectStudents();
int nums = dao.insertStudent(new Student(1006,77,"小新","xiaoXin@qq.com"));
System.out.println("===========分界线===========");
System.out.println("===========分界线===========");
students.forEach(student -> System.out.println(student));
System.out.println("===========分界线===========");
System.out.println("===========分界线===========");
System.out.println("插入成功条数:" + nums);
}
4.6、测试结果:
五、动态代理
5.1、使用动态代理条件分析:
java
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectStudents();
students.forEach(student -> System.out.println(student));
sqlSession.close();
StudentDao dao = new StudentDaoImpl();
List<Student> students = dao.selectStudents();
//StudentDaoImpl手动实现类:
public List<Student> selectStudents() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.lifang.dao.StudentDao.selectStudents";
List<Student> students = sqlSession.selectList(sqlId);
sqlSession.close();
return students;
}
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectStudents();
1、dao对象,类型是StudentDao,全限定名称是:com.lifang.dao.StudentDao,全限定名称 和 sql映射文件中的namespace 是一样的。
2、方法名称,selectStudents ,这个方法就是 mapper文件中的 id值
3、通过dao 中方法的返回值也可以确定MyBatis 要调用的sqlsession方法:
- 如果返回值是List ,调用的是sqlSession.selectList()方法。
- 如果返回值 int ,或者非list,看mapper文件中的标签是<insert>,<update> 就会调用 SqlSession的insert、update等方法
mybatis的动态代理: mybatis 根据 dao的方法调用,获取执行sql语句的信息,mybatis 根据你的dao 接口,创建出一个dao 接口的实现类,并创建这个类的对象,完成SqlSession调用方法,访问数据库。++****这个Dao接口的实现类不需要你写了,mybatis会根据你的dao接口,把这个dao实现类在内部创建出来,你只需要提供Dao接口和Sql映射文件就可以了。++
去掉 Dao****接口实现类: