mybatis学习笔记(day2)
mybatis学习day2
SqlSession
位于sqlsessionfactory中 是 会话工厂的一部分 我们可以创建一个seesion来进行提交、回滚操作。
SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。
SqlSession
SqlSession是一个面向用户(程序员)的接口。SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。
SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
SqlSession最佳应用场合在方法体内,定义成局部变量使用。
我们还记得mybatis的启动流程:
1.通过Resources处理得到一个字节流或者字符流的处理类
2.通过SqlSessionFactoryBuilder构建一个SqlSessionFactory
3.通过SqlSessionFactory得到SqlSession
4.通过SqlSession执行相关Mapper文件的sql语句
原始Dao层
UserDaoImpl
[code]
package dao.Impl;import dao.UserDao;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import po.User;import java.util.List;public class UserDaoImpl implements UserDao { // 需要向dao实现类中注入SqlSessionFactory // 这里通过构造方法注入 private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory){ this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne(“test.findUserById”,id); //释放资源 sqlSession.close(); return user; } @Override public List
[/code]
UserDao 接口
[code]
package dao;import po.User;import java.util.List;public interface UserDao { //根据id查询用户信息 public User findUserById(int id) throws Exception; //根据用户名列查询用户列表 public List
[/code]
注意:我改动了一些东西
相比于Day1 :
我将sqlmap改成Mapper层了 方便以后的学习和理解
记得将SqlMapConfig.xml中的注册改动一下
总结原始Dao层开发的问题
1.dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
2.调用sqlsession方法时将statement的id硬编码了
3.调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
Mapper代理方法
程序员只需要mapper接口(相当 于dao接口)
程序员还需要编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
开发规范
- 在mapper.xml中namespace等于mapper接口地址
[code]
[/code]
- mapper.java接口中的方法名和mapper.xml中statement的id一致
- mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
- mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
[code]
[/code]
[code]
//根据id查询用户信息public User findUserById(int id) throws Exception;
[/code]
总结:以上开发规范主要是对下边的代码进行统一生成:
[code]
User user = sqlSession.selectOne(“test.findUserById”, id);sqlSession.insert(“test.insertUser”, user);
[/code]
代码
UserMapper.xml
[code]
[/code]
mapper 文件夹下的 UserMapper (注意:该名字要和xml同名要不然找不到)
[code]
package mapper;import po.User;import java.util.List;public interface UserMapper { //根据id查询用户信息 public User findUserById(int id) throws Exception; //根据用户名列查询用户列表 public List
[/code]
Test类
[code]
import mapper.UserMapper;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import po.User;import java.io.InputStream;public class UserMapperTest { private SqlSessionFactory sqlSessionFactory; //注解Before是在执行本类所有测试方法之前先调用这个方法 @Before public void setup() throws Exception{ //创建SqlSessionFactory String resource=”SqlMapConfig.xml”; //将配置文件加载成流 InputStream inputStream = Resources.getResourceAsStream(resource); //创建会话工厂,传入mybatis配置文件的信息 sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindUserById() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); //创建UserMapper代理对象 UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //调用userMapper的方法 User user=userMapper.findUserById(1); System.out.println(user.getUsername()); }}
[/code]
一些问题
- 代理对象内部调用
selectOne或selectList- 如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
- 如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
- mapper接口方法参数只能有一个是否影响系统开发
mapper接口方法参数只能有一个,系统是否不利于扩展维护?系统框架中,dao层的代码是被业务层公用的。即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型、map…等,service方法中建议不要使用包装类型(不利于业务层的可扩展)。
- 在使用mybatis的selectList方法时,如果数据库的东西没东西返回,则不会为null 而是为空,而selectOne方法则会返回null
总结:数据库表字段如果有唯一约束,在mybatis中使用selectOne方法;
数据库表字段如果没有唯一约束,即使在业务逻辑上此字段时唯一的,但还是建议使用selectList方法。
如果数据库字段有唯一约束,那么你再添加相同的数据,则无法添加成功,但如果没有唯一约束,程序上可能出现并发,添加到数据库可以成功,但再次查询时会因为返回多条数据而导致程序出现问题。






