通过SqlSessionFactoryBuilder创建会话工厂
将SqlSessionFactoryBuilder当成一个工具类使用,不需要使用单例管理SqlSessionFactoryBuilder。
在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
通过SqlSessionFactory创建SQLSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例,整个项目只有一个实例)
将来mybatis和Spring整合后,使用单例模式去管理SqlSessionFactory。
SqlSession是一个面向用户(程序员)接口
SqlSession提供了很多操作数据库的方法,
selectOne:返回单个对象,根据主键来查询
selectList:返回1个或者多个对象。
SqlSession是线程不安全,在SqlSession实现类中除了有接口中方法(操作数据库的方法),还有数据域属性。
SqlSession最佳应用场合是在方法体内,定义成局部变量使用。
public interface UserDao {
/**
* 得到用户通过id
* @param id
* @return
*/
public User getUserById(Integer id);
}
public class UserDaoImpl implements UserDao {
//在创建DAO的时候,需要传递工厂
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User getUserById(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
User ser = sqlSession.selectOne("user.findUserById",id);
return ser;
}
}
package com.hyx2.dao_first.pojo;
import java.util.Date;
public class User {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
public User() {
}
public User(String username, String sex, Date birthday, String address) {
this.username = username;
this.sex = sex;
this.birthday = birthday;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}';
}
}
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis01?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123
import UserDao;
import impl.UserDaoImpl;
import 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.IOException;
import java.io.InputStream;
public class Demo01 {
private SqlSessionFactory sqlSessionFactory;
@Before
public void fun0() throws IOException {
InputStream inputStream = Resources.getResourceAsStream( "hyx2_first_sqlMapconfig.xml" );
//通过配置创建会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build( inputStream );
}
@Test
public void fun(){
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User userById = userDao.getUserById(1);
System.out.println(userById);
}
}
(1)dao接口实现类方法中,存在大量模板代码(重复),设想能否将这项代码抽取出来,大大减少程序员的工作量。
AOP思想;代理模式
(2)调用SQLSession方法的时候,传入的变量类型Object,即使变量类型传入错误,在编译阶段也不报错,不利于程序的开发。
程序员只需要编写Mapper接口(就相当于DAO),mybatis可以自动生成Mapper接口实现类对象。但是:要像自动生成实现类对象,需要遵循一些规范。
(1)Mapper接口和Mapper.xml放在同一个目录下。同名。
(2)Mapper.xml中namespace的值等于Mapper接口的全路径
(3)statementId,parameterType、ResultType和接口名字、入参类型、返回值类型要一致。
package mapper;
import pojo.User;
public interface UserMapper {
/**
* 找到用户通过id
*/
public User findUserById(Integer id);
}
package test;
import mapper.UserMapper;
import 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.IOException;
import java.io.InputStream;
public class Dmo01 {
private SqlSessionFactory sqlSessionFactory;
@Before
public void fun0() throws IOException {
InputStream inputStream = Resources.getResourceAsStream( "hyx2_two_sqlMapconfig.xml" );
//通过配置创建会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build( inputStream );
}
@Test
public void fun(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User userById = mapper.findUserById(1);
System.out.println(userById);
}
}
根据接口的返回值来区别的。
如果返回值是POJO对象,selectOne来实现。
如果返回值是结合对象,selectList来实现。
系统是否不利于扩展维护。
系统框架中,DAO层的代码是被业务层公用的
即使Mapper接口只有一个参数,可以使用包装类型的POJO满足不同业务方法的需求。