认识mybatis - 环境搭建及入门案例
Mybatis框架概述
mybatis是一个优秀的持久层框架,内部封装了JDBC,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接,创建statement等繁杂的过程。
mybatis通过xml文件或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。
采用ORM(Object Relational Mapping,对象关系映射)思想解决了实体和数据库映射的问题,对jdbc进行封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。
为了更好掌握框架运行的内部过程,并且有更好的体验,下面我们将从自定义mybatis框架来开始学习框架,此时我们将会体验框架由无到有的过程体验,也能够更好的综合前面阶段所学的基础。
1、mybatis的ORM思想:
Object Relational Mapping 对象关系映射。
- 对象:指面向对象
- 关系:指关系型数据库
- 映射:java到MySQL的映射,开发者可以以面向对象的思想来管理数据库
2、Mybatis的核心接口和类:
任何一个工具或者框架一定都是会和java程序对接的,这两个怎么去对接呢,一定通过某一个对象来对接,mybatis中这个连接着就是SqlSession,然后SqlSession创建时要通过SqlSessionFactory新建一个builder,再通过builder来调用build方法可以获得一个SqlSessionFactory,通过工厂对象的OpenSession方法来产生SqlSession,目的是拿到SqlSession而获取SqlSession是通过SqlSessionBuilder和SqlSessionFactory来形成的,开发时都是通过调用SqlSession各种各样的方法和接口来完成相对应的开发。
3、mybatis主要有两种开发方式
使用原生接口
Mapper代理实现自定义接口
无论是哪种方式都是通过SqlSession的方法来完成的!
零、如何使用mybatis?
下面进行项目准备工作,我们将会使用原生接口和Mapper代理实现自定义接口两种方式。
完成后的项目目录见后面↓↓↓
1.新建maven工程
新建maven工程使用Maven的默认配置就好,不需要create from achetype;以下为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>com.southwind</groupId> <artifactId>aimybatis</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> <!--什么是lombok?https://www.zhihu.com/question/42348457--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> </dependency> </dependencies> <!--支持把xml配置文件放在resources以外的地方,不加这些AccountMapper.xml读取不到--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build> </project>
2.在数据库中创建表t_account:
CREATE TABLE t_account( id INT PRIMARY KEY auto_increment, username VARCHAR(11), password VARCHAR(11), age INT )
3.新建数据表对应的实体类Account:
package com.southwind.entity; public class Account { private int id; private String username; private String password; private int age; 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; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Account() { } public Account(int id, String username, String password, int age) { this.id = id; this.username = username; this.password = password; this.age = age; } }
准备工作完成!!!
一、使用原生接口的开发方式进行实践:
1.创建mybatis配置文件:
创建mybatis配置文件,文件名可以自定义,这里起名mybatisConfig.xml:
- mappers标签内注册了我们稍后创建的AcccountMapper.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> <!-- 配置mybatis运行环境:和哪个数据库连接(甚至可以配置多个),不过我们暂时不需要! --> <environments default="development"> <!-- 这个default就是设置默认连接下面哪个数据库 --> <environment id="development"> <!-- 配置jdbc事务管理 --> <transactionManager type="JDBC"></transactionManager> <!--POOLED配置JDBC数据源连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--注册AcccountMapper.xml--> <!--这时候文件之间不能用'.'了,要用'/',因为后面写的是文件全名,带后缀的!后缀需要加'.'呀,所以要进行区分!!!--> <mappers> <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper> </mappers> </configuration>
2.创建Mapper配置文件:
Mybatis框架需要开发者自定义SQL语句,写在Mapper.xml文件中,实际开发中,会为每个实体类创建对应的Mapper.xml,定义该管理对象数据的SQL。
- 这里AccountMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.southwind.mapper.AccountMapper"> <!-- mybatis框架加载配置文件时去找的路径,所以写成mapper文件的全路径,不用写xml后缀--> <!-- 传一个Account类型的参数 --> <!--取出Account对象中的username,password等等对象,通过#{}符号--> <insert id="save" parameterType="com.southwind.entity.Account"> insert into t_account(username,password,age)values(#{username},#{password},#{age}) </insert> </mapper>
- namespace通常设置为文件所在包+文件名的形式,不是必须的,但我们推荐这样写
- insert标签表示执行添加操作,对应的select标签表示执行查询操作
- select标签表示执行查询操作
- update标签表示执行更新操作
- delete标签表示执行删除操作
- id是实际调用mybatis方法时需要用到的参数,parameterType是要调用对应方法时,参数的数据类型。
3.调用mybatis的原生接口来执行添加操作,而后运行:
package com.southwind; import com.southwind.entity.Account; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; public class Test0 { public static void main(String[] args){ //加载mybatis配置文件:用类加载器把mybatis配置文件传过来,然后读成一个流 InputStream inputStream = Test0.class.getClassLoader().getResourceAsStream("mybatisConfig.xml"); //有了数据流之后创建对应的核心接口和类 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); String statement = "com.southwind.mapper.AccountMapper.save"; Account account = new Account(1,"张三","123123",22); sqlSession.insert(statement,account); sqlSession.commit(); } }
运行结果:
再看数据库:
这样就插入成功啦!!!
PS:项目目录如下:
二、使用Mapper代理来实现自定义接口
刚刚我们将使用了原生接口的开发方式进行实践:
然而还有一种更方便的方式,下面我们来尝试一下:
使用Mapper代理来实现自定义接口,只需要做好这两件事:
- 自定义接口,定义相关业务方法
- 编写与方法相对应的Mapper.xml
1.自定义接口
package com.southwind.repository; import com.southwind.entity.Account; import java.util.List; public interface AccountReposity { public int save(Account account); public int update(Account account); public int deleteById(int id); public List<Account> findAll(); public Account findById(int id); }
2.创建接口对应的Mapper.xml,定义接口方法对应的SQL语句
statement标签会根据SQL执行的业务来选择insert、delete、update、select。
mybatis根据框架自动创建接口的实现类,实现类的代理对象。
规则:
- Mapper.xml中namespace的值为接口的全类名
- Mapper.xml中statement的id为接口的对应的方法名
- Mapper.xml中statement的parameterType和接口中对应的参数类型一致
- Mapper.xml中statement的resultType和接口中对应方法的返回值类型一致。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 写对应接口全类名 --> <mapper namespace="com.southwind.repository.AccountReposity"> <insert id="save" parameterType="com.southwind.entity.Account"> insert into t_account(username,password,age)values(#{username},#{password},#{age}) </insert> <update id="update" parameterType="com.southwind.entity.Account"> update t_account set username = #{username}, password = #{password}, age = #{age}; </update> <delete id="deleteById" parameterType="int"> delete from t_account where id = #{id} </delete> <select id="findAll" resultType="com.southwind.entity.Account"> select * from t_account </select> <select id="findById" parameterType="int" resultType="com.southwind.entity.Account"> select * from t_account where id = #{id} </select> </mapper>
3.在mybatisConfig.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> <!-- 配置mybatis运行环境:和哪个数据库连接(甚至可以配置多个),不过我们暂时不需要! --> <environments default="development"> <!-- 这个default就是设置默认连接下面哪个数据库 --> <environment id="development"> <!-- 配置jdbc事务管理 --> <transactionManager type="JDBC"></transactionManager> <!--POOLED配置JDBC数据源连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--注册AcccountMapper.xml--> <!--这时候文件之间不能用'.'了,要用'/',因为后面写的是文件全名,带后缀的!后缀需要加'.'呀,所以要进行区分!!!--> <mappers> <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper> <mapper resource="com/southwind/repository/AccountRepository.xml"></mapper> </mappers> </configuration>
4.测试
package com.southwind; import com.southwind.entity.Account; import com.southwind.repository.AccountRepository; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.InputStream; import java.util.List; public class Test12 { @Test public void CaoZuo(){ InputStream inputStream = Test12.class.getClassLoader().getResourceAsStream("mybatisConfig.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); AccountRepository accountRepository = sqlSession.getMapper(AccountRepository.class); //查询所有对象 // List<Account> list = accountRepository.findAll(); // for (Account account:list){ // System.out.println(account); // } // sqlSession.close(); //添加对象 // Account account = new Account(5, "李四", "saorui", 12); // accountRepository.save(account); // sqlSession.commit(); //通过id查询对象 // Account account = accountRepository.findById(3); // System.out.println(account); // sqlSession.close(); //修改对象 // Account account = accountRepository.findById(3); // System.out.println(account); // account.setId(9); // account.setUsername("赵大波"); // account.setPassword("pupupu"); // account.setAge(48); // int result = accountRepository.update(account); // sqlSession.commit(); // System.out.println(result); // sqlSession.close(); //通过id删除对象 int result = accountRepository.deleteById(3); System.out.println(result); sqlSession.commit(); sqlSession.close(); } }均完成了相关操作,成功!!
PS:项目目录可以这样写:
初识mybatis,小伙伴们加油~~~