创建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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
编写核心配置文件
这里的核心配置和我们自定义框架的前期是一样的,只不过配置文件的根要注意
下面是SqlMapperConfig.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>
<!--指定当前使用的环境-->
<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 mapper
PUBLIC "-//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 {
@Test
public 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>
测试类
@Test
public 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();
}
@Test
public 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();
}
@Test
public 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 {
@Override
public 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;
}
@Override
public List<User> selectAll() {
return null;
}
}
其实传统开发就是将我们前面的测试类移动到实现类中就可以,代理开发方式我们需要一些约束,也就是将接口于xml进行映射,能产生关联,具体在四个地方:
- xml的namespace,必须是接口所在的路径
- xml中操作标签的id,要与接口的方法对应
- xml的操作标签的parameterType要与方法的参数的类型相同
- xml的操作标签的resultType要与方法的返回值类型相同
具体的代码如下:
<?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.wangzhi.dao.UserMapper">
<select id="selectAll" resultType="com.wangzhi.pojo.User">
SELECT * FROM user
</select>
</mapper>
// 接口
public interface UserMapper {
List<User> selectAll();
}
// 测试
@Test
public 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);
}