1.SqlSession使用范围
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是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
- SqlSession最佳应用场合在方法体内,定义成局部变量使用。
2.原始dao开发方法(程序员需要写dao接口和dao实现类)
目录结构如下:建一个dao包,建一个test包作为测试的根目录(右键mark derictory as test resources root )
- 定义接口UserDao
package com.chinglee.mybatis.dao;
import com.chinglee.mybatis.pojo.User;
public interface UserDao {
public User findUserById(int id);
public void insertUser(User user);
public void deleteUser(int id);
}
- 接口的实现类UserDaoImpl
package com.chinglee.mybatis.dao;
import com.chinglee.mybatis.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class UserDaoImpl implements UserDao {
SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory=sqlSessionFactory;
}
@Override
public User findUserById(int id) {
SqlSession sqlSession=sqlSessionFactory.openSession();
User user=sqlSession.selectOne("user.findUserById",id);
//释放资源
sqlSession.close();
return user;
}
@Override
public void insertUser(User user) {
SqlSession sqlSession=sqlSessionFactory.openSession();
sqlSession.insert("user.insertUser",user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void deleteUser(int id) {
SqlSession sqlSession=sqlSessionFactory.openSession();
sqlSession.delete("user.deleteUser",id);
sqlSession.commit();
sqlSession.close();
}
}
- 建一个测试类:UserDaoImplTest
package com.chinglee.mybatie.daotest;
import com.chinglee.mybatis.dao.UserDao;
import com.chinglee.mybatis.dao.UserDaoImpl;
import com.chinglee.mybatis.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
/**
* Created by Administrator on 2017/10/20 0020.
*/
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
//此方法是在执行test方法之前执行
@Before
public void setUp() throws Exception {
String resource="SqlMapConfig.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserById() throws Exception {
//创建UserDao对象
UserDao userDao=new UserDaoImpl( sqlSessionFactory);
//调用UserDao的方法
User user=userDao.findUserById(1);
System.out.println(user);
}
@Test
public void insertUser() throws Exception {
//创建UserDao对象
UserDao userDao=new UserDaoImpl( sqlSessionFactory);
//调用UserDao的方法
User user=new User();
user.setUsername("王小军");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("河南郑州");
userDao.insertUser(user);
}
@Test
public void deleteUser() throws Exception {
//创建UserDao对象
UserDao userDao=new UserDaoImpl( sqlSessionFactory);
userDao.deleteUser(30);
}
}
-
总结原始DAO开发存在问题:
- dao接口实现类存在大量的模板,设想能否将代码提取出来,减轻程序员工作量。
- 调用sqlsession方法时将statement的id硬编码了
- 调用sqlsession方法传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,编译阶段不报错,不利于开发。
3. mapper代理方法
-
程序员编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
-
程序员只需要写mapper接口(相当于dao接口)
开发规范:
1) 在mapper.xml中namespace等于mapper接口地址
把user.xml复制到mapper里,重命名为UserMapper
把UserDao.java复制到mapper里,重命名UserMapper.java
2)mapper.java接口中方法名和mapper.xml中statement的id一致
3)mapper.java接口中方法的输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4)mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
-
在SqlMapConfig中加载映射文件
<!--加载映射文件-->
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
-
总结
以上开发规范主要是对以下代码进行统一生成
User user=sqlSession.selectOne("user.findUserById",id);
sqlSession.insert("user.insertUser",user);
sqlSession.delete("user.deleteUser",id);
-
使用mapper代理实现源码:
- UserMapper.java
package com.chinglee.mybatis.mapper;
import com.chinglee.mybatis.pojo.User;
import java.util.List;
public interface UserMapper {
public User findUserById(int id);
public void insertUser(User user);
public void deleteUser(Integer id);
public List<User> findUserByName(String name);
}
-
UserMapper.xml
除了namespace改变其余相同。
- UserMapperTest.java
package com.chinglee.mybatie.daotest;
import com.chinglee.mybatis.mapper.UserMapper;
import com.chinglee.mybatis.pojo.User;
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 java.io.InputStream;
import java.util.List;
/**
* Created by Administrator on 2017/10/21 0021.
*/
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource="SqlMapConfig.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserById() throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
User user=userMapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void insertUser() throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
User user=new User();
user.setUsername("小李子");
user.setAddress("北京");
user.setSex("1");
userMapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser() throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
userMapper.deleteUser(29);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testFindUserByName(){
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
List<User> userList= userMapper.findUserByName("小明");
sqlSession.close();
System.out.print(userList);
}
}