使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。
根据用户id查询一个用户信息。
1.1、SqlSessionFactoryBuilder
-
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
-
将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管SqlSessionFactoryBuilder。在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
1.2、SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。mybatis和spring整合后,使用单例模式管理sqlSessionFactory。
1.3、SqlSession
-
SqlSession是一个面向用户(程序员)的接口。
-
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。
-
SqlSession是线程不安全的,因此是不能被共享的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
-
SqlSession每次使用完成后需要正确关闭,这个关闭操作是必须的。
二、原始dao开发
思路
程序员需要写dao接口和dao实现类。
需要向dao创建SqlSession
- 和上一篇中的用法操作一样
- 映射配置文件user.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">
<!--user表字段--> <sql id="sqlColumnsForUserTable"> id,username,sex,birthday,address </sql> <!-- 根据id获取用户信息 --> <select id="findUserById" resultType="com.jdy.mybatis2020.bean.User"> select <include refid="sqlColumnsForUserTable"/> from user where id = #{id}; </select> </mapper>
- Dao接口
public interface UserDao { /** * 根据Id获取用户信息 * @param id * @return */ public User findUserById(String id); }
- Dao实现类
public class UserDaoImpl implements UserDao { // 需要向dao实现类中注入SqlSessionFactory // 这里通过构造方法注入 private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(Integer id) { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("user.findUserById", id); // 释放资源 sqlSession.close(); return user; } }
- 测试
public class Test_00 { public static final String RESOURCE = "mybatis-config/mybatis-config_01.xml"; private SqlSessionFactory sqlSessionFactory; @Before public void createFactory(){ sqlSessionFactory = SqlSessionFactoryUtil.createFactory(RESOURCE); } @Test public void test_Method04() { UserDao userDao = new UserDaoImpl(sqlSessionFactory); User user = userDao.findUserById("1"); System.out.println("user = " + user); } }
Dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
调用sqlsession方法时将statement的id硬编码了,
程序员只需要mapper接口(相当于dao接口)
思路(遵循mapper代理开发规范)
程序员还需要编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。 开发规范:
3.1、Mapper开发规范
-
在mapper.xml中namespace等于mapper接口地址。
-
mapper.java接口中的方法名和mapper.xml中statement的id一致。
-
mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
-
mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
3.2、案例演示
-
新建映射配置文件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="com.jdy.mybatis2020.dao.intf.UserMapperDao"> <!--user表字段--> <sql id="sqlColumnsForUserTable"> id,username,sex,birthday,address </sql> <!-- 根据id获取用户信息 --> <select id="findUserById" resultType="com.jdy.mybatis2020.bean.User"> select <include refid="sqlColumnsForUserTable"/> from user where id = #{id}; </select> </mapper>
- 在mybatis-config_01.xml加载userMapper.xml
<!--加载映射配置文件--> <mappers> <mapper resource="sqlmap/userMapper.xml"/> </mappers>
- 新建Dao接口UserMapperDao
public interface UserMapperDao { /** * 根据Id获取用户信息 * @param id * @return */ public User findUserById(String id); }
- 测试
public class Test_00 { public static final String RESOURCE = "mybatis-config/mybatis-config_01.xml"; private SqlSessionFactory sqlSessionFactory; @Before public void createFactory(){ sqlSessionFactory = SqlSessionFactoryUtil.createFactory(RESOURCE); } @Test public void test_Method05() { SqlSession sqlSession = null; try { sqlSession = sqlSessionFactory.openSession(); UserMapperDao mapper = sqlSession.getMapper(UserMapperDao.class); User user = mapper.findUserById("2"); System.out.println(user); } catch (Exception e) { e.printStackTrace(); } finally { if (sqlSession != null) { sqlSession.close(); } } } }
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
namespace