目录
1 SqlSession的介绍
SqlSession中封装了对数据库的操作,比如:更新、删除、查询等。通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是由SqlSessionFactoryBuilder来创建的。
1.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的作用是创建SqlSessionFacoty,SqlSessionFacoty创建了之后就不需要SqlSessionFactoryBuilder了,由于SqlSession是通过SqlSessionFactory生产,所以一般是将SqlSessionFactoryBuilder当成一个工具类使用,需要创建sqlSessionFactory时就new一个 SqlSessionFactoryBuilder,和Spring整合后由Spring以单例方式管理sqlSessionFactory。
1.2 SqlSessionFactory
SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作,默认使用DefaultSqlSession实现类。
2 MaBatis对Dao层的开发方式
2.1 不使用Mapper动态代理开发
编写dao层接口
public interface UserDao {
//根据id查询用户
public User getUserById(Integer id);
}
编写dao层接口实现类
public class UserDaoImpl implements UserDao {
//sqlSession 工厂
private SqlSessionFactory ssf;
//通过构造器给ssf赋值
public UserDaoImpl(SqlSessionFactory ssf) {
super();
this.ssf = ssf;
}
@Override
public User getUserById(Integer id) {
//生产一个sqlSession
SqlSession session = ssf.openSession();
User user session.selectOne("UserMapper.selectUserById",id);
session.close();
return user;
}
}
编写测试方法
public class UserDaoTest {
//sqlSession 工厂
private static SqlSessionFactory ssf;
static {
String resource = "sqlMapConfig.xml";
InputStream in;
try {
in = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
ssf = ssfb.build(in);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void DaoTest() {
UserDao dao = new UserDaoImpl(ssf);
User user = dao.getUserById(1);
System.out.println(user);
}
}
不使用Mapper动态代理开发可以从代码中看到一些问题,每次我们调用SqlSession都要完成打开session、调用session完成与数据库的交互、关闭session,这三步,这些都是重复的代码。
2.2 使用Mapper动态代理开发
首先想使用Mapper动态代理开发必须遵循四大原则加一个注意:
- 接口方法名需要与mapper.xml的要调用的sql语句的id一致
- 接口的形参类型需要与mapper.xml中的parameterType一致
- 接口的返回值需要与mapper.xml中的resultType一致
- mapper.xml中的namespace要与接口的全包名一致
注意:mapper动态代理开发中,根据返回值类型自动选择方法
UserMapper接口(mybatis提出mapper接口,相当于dao接口,mapper接口的命名方式建议为表名加Mapper)
public interface UserMapper {
//通过id查询一个用户
public User selectUserById(Integer id);
}
UserMapper映射文件(mapper映射文件的命名方式建议表名加Mapper.xml,namespace指定为mapper接口的全限定名)
<!-- mapper.xml中的namespace要与接口的全包名一致 -->
<mapper namespace="com.xiezhenyu.mapper.UserMapper">
<!-- 查找用户 -->
<select id="selectUserById" parameterType="Integer" resultType="user">
select * from user where u_id = #{id}
</select>
</mapper>
将mapper.xml在SqlMapConfing.xml中进行注册
<mappers>
<package name="com.xiezhenyu.mapper"/>
</mappers>
编写测试方法
@Test
public void Test1() throws IOException {
String resource = "sqlMapConfig.xml";
//读取配置文件
InputStream in = Resources.getResourceAsStream(resource);
//需要sqlSessionFactoryBulider
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
//创建sqlSessionFactory
SqlSessionFactory ssf = ssfb.build(in);
//生产一个sqlSession
SqlSession session = ssf.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
}
结果:
User [u_id=1, u_username=老王, u_password=123, u_sex=1, u_createTime=null, u_cid=1]
总结:使用Mapper代理进行开发
优点:可以使我们只需要关注UserMapper.java接口中的方法,它的实现类由Mapper自动为我们生成,带来了很大的方便。
缺点:如果UserMapper.java接口中的方法调用的statement中返回是多条记录,而mapper.java方法的返回值为JavaBean对象,此时代理对象通过selectOne调用,但由于返回的是多条记录所以会报错。