创建maven项目
这步不用说,注意不要引入任何依赖和框架,这里只是为了研究mybatis
引入依赖如下
<dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency></dependencies>
编写实体类
假设已经存在数据库
package com.wangzhi.pojo;public class User {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +'}';}}
编写核心配置文件
这里的核心配置和我们自定义框架的前期是一样的,只不过配置文件的根要注意
下面是SqlMapperConfig.xml的配置<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--指定当前使用的环境--><environments default="dev"><!--可以配置多个,比如说开发环境、测试环境、生产环境--><environment id="dev"><!--表示使用JDBC的事务--><transactionManager type="JDBC"/><!--表示使用mybatis的连接池--><dataSource type="POOLED"><!--配置数据库连接信息,我这里使用的是mysql8--><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql:///zdy_mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true"/><property name="username" value="root"/><property name="password" value="nrblwbb7"/></dataSource></environment></environments><mappers><mapper resource="UserMapper.xml"/></mappers></configuration>UserMapper.xml的内容如下:<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="user"><select id="selectAll" resultType="com.wangzhi.pojo.User">SELECT * FROM user</select></mapper>
编写测试类进行测试
上面的流程基本配置和所有的准备工作已经完成,接下来测试类的编写
public class test {@Testpublic void testQuery() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapperConfig.xml");SqlSession sqlSession = new SqlSessionFactoryBuilder().build(resourceAsStream).openSession();List<User> users = sqlSession.selectList("user.selectAll");users.forEach(System.out::println);sqlSession.close();}}
接下来,将CUD也测试一下
<insert id="insertUser" parameterType="com.wangzhi.pojo.User">INSERT INTO user VALUES (#{id}, #{name})</insert><update id="updateUser" parameterType="com.wangzhi.pojo.User">UPDATE user SET name = #{name} WHERE id = #{id}</update><delete id="deleteUser" parameterType="java.lang.Integer">DELETE FROM user WHERE id = #{id}</delete>测试类@Testpublic void testInsert() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapperConfig.xml");SqlSession sqlSession = new SqlSessionFactoryBuilder().build(resourceAsStream).openSession();User user = new User();user.setId(2);user.setName("芊芊");sqlSession.insert("user.insertUser", user);sqlSession.commit();sqlSession.close();}@Testpublic void testUpdate() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapperConfig.xml");SqlSession sqlSession = new SqlSessionFactoryBuilder().build(resourceAsStream).openSession();User user = new User();user.setId(2);user.setName("芊儿");sqlSession.update("user.updateUser", user);sqlSession.commit();sqlSession.close();}@Testpublic void testDelete() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapperConfig.xml");SqlSession sqlSession = new SqlSessionFactoryBuilder().build(resourceAsStream).openSession();sqlSession.delete("user.deleteUser", 1);sqlSession.commit();sqlSession.close();}
注意于查询不相同的地方在于增删改必须要显示提交事务,否则操作不会保存在数据库中。
传统Dao的开发方式和代理开发方式,这个也在自定义框架里面设计,无论是传统开发方式还是代理开发方式,接口的存在是必须的,区别在于传统开发方式需要有实现类,由实现类去进行操作。代理开发方式是接口于sqlMapper直接映射,利用反射等技术来进行实现。
传统开发方式:
public interface UserMapper {List<User> findAll() throws IOException;List<User> selectAll();}public class UserMapperImpl implements UserMapper {@Overridepublic List<User> findAll() throws IOException {// 加载配置文件,将配置文件转为字节输入流InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapperConfig.xml");// 解析配置文件,创建SqlSessionFactory工厂,生产会话对象,会隐式开始事务,构造方法传入true会隐式提交事务SqlSession sqlSession = new SqlSessionFactoryBuilder().build(resourceAsStream).openSession();// 调用数据库方法,selectList、selectOne、update、delete、insert,如果在创建会话对象的时候没有传入true,需要显式提交事务List<User> users = sqlSession.selectList("user.selectAll");sqlSession.close();return users;}@Overridepublic List<User> selectAll() {return null;}}
其实传统开发就是将我们前面的测试类移动到实现类中就可以,代理开发方式我们需要一些约束,也就是将接口于xml进行映射,能产生关联,具体在四个地方:
- xml的namespace,必须是接口所在的路径
- xml中操作标签的id,要与接口的方法对应
- xml的操作标签的parameterType要与方法的参数的类型相同
- xml的操作标签的resultType要与方法的返回值类型相同
具体的代码如下:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.wangzhi.dao.UserMapper"><select id="selectAll" resultType="com.wangzhi.pojo.User">SELECT * FROM user</select></mapper>// 接口public interface UserMapper {List<User> selectAll();}// 测试@Testpublic void testProxyQuery() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapperConfig.xml");SqlSession sqlSession = new SqlSessionFactoryBuilder().build(resourceAsStream).openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> all = mapper.selectAll();all.forEach(System.out::println);}
