Mybatis使用之开发进阶(一)

本文将介绍如何使用mybatis进行Dao层开发,并由原始到使用进阶

首先了解几个类(对象)

SqlSessionFactoryBuilder

通过SqlSessionFactoryBuilder创建会话工厂
将SqlSessionFactoryBuilder当成一个工具类使用,不需要使用单例管理SqlSessionFactoryBuilder。
在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory

通过SqlSessionFactory创建SQLSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例,整个项目只有一个实例)
将来mybatis和Spring整合后,使用单例模式去管理SqlSessionFactory。

SqlSession

SqlSession是一个面向用户(程序员)接口
SqlSession提供了很多操作数据库的方法,
selectOne:返回单个对象,根据主键来查询
selectList:返回1个或者多个对象。
SqlSession是线程不安全,在SqlSession实现类中除了有接口中方法(操作数据库的方法),还有数据域属性。
SqlSession最佳应用场合是在方法体内,定义成局部变量使用。

准备工作:1)mybatis工具类

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("sqlMapconfig.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSession() {
        return sqlSessionFactory.openSession();
    }

    public static void close(SqlSession sqlSession) {
        if (sqlSession != null) {
            sqlSession.close();
            sqlSession = null;
        }
    }
}

2)实体类:与数据库user表字段一致

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 + '\'' + '}';
    }
}

原始DAO开发方法(DAO接口和DAO实现类)

mybatis入门请看
  • 目录结构:
    Mybatis使用之开发进阶(一)_第1张图片
  • 先写接口:
public interface UserDao {
    User getUserById(int id);
}
  • 实现接口:
public class UserDaoImpl implements UserDao {
    @Override
    public User getUserById(int id) {
        SqlSession sqlSession = MyBatisUtil.getSession();
        User user = sqlSession.selectOne("user.findUserById",1);
        return user;
    }
}
  • mybatis:xml实现(对数据哭的操作):UserMapper.xml



    

  • mybatis配置文件:sqlMapconfig.xml



    
        
            
            
                
                
                
                
            
        
    
    
        
    

  • 测试
public class demo {
    
    @Test
    public void fun1() {
        UserDao userDao = new UserDaoImpl();
        User u = userDao.getUserById( 1 );
        System.out.println(u);
    }
}

存在的问题

  • (1)dao接口实现类方法中,存在大量模板代码(重复),设想能否将这项代码抽取出来,大大减少程序员的工作量。
    AOP思想;代理模式
  • (2)调用SQLSession方法的时候,传入的变量类型Object,即使变量类型传入错误,在编译阶段也不报错,不利于程序的开发。

进阶-Mapper代理开发方法(只需要写Mapper接口(相当于DAO接口))

使用该方法,程序员要干的事情
程序员只需要编写Mapper接口(就相当于DAO),mybatis可以自动生成Mapper接口实现类对象。但是:要像自动生成实现类对象,需要遵循一些规范。

  • (1)Mapper接口和Mapper.xml放在同一个目录下。同名。
  • (2)Mapper.xml中namespace的值等于Mapper接口的全路径
  • (3)statementId,parameterType、ResultType和接口名字、入参类型、返回值类型要一致。
    Mybatis使用之开发进阶(一)_第2张图片

代码实现

  • 目录结构
    Mybatis使用之开发进阶(一)_第3张图片

编辑UserMapper接口

public interface UserMapper {
    User findUserById(int id);
}

修改UserMapper.xml



 //为上面接口的路径
    

测试:

public class Demo01 {
    @Test
    public void fun01(){
        SqlSession session = MyBatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.findUserById(26);
        System.out.println(user);
    }
}

小结

使用mapper代替了Dao层
配置文件暂时不用修改

下面将进行sqlMapconfig.xml修改(进阶)

  • 准备文件:db.properties(存放数据库信息)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis01?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
  • 修改sqlMapconfig.xml



     //从db.properties中读取信息

     //给是实体类定义别名
    	//方式一:一个个修改别名
        
        //方式二:直接扫描包下的所有实体(推荐)
        
    
	
    
        
            
            
                 //从db.properties中读取信息
                
                
                
            
        
    

//映射修改
    
    	//方式一:通过resource加载
        
        //方式二:通过Mapper接口加载
        
        //方式三:批量加载(推荐)
        
    

修改UserMapper.xml



 //为UserMapper接口的路径
    

小结

使用Mapper开发常见问题
  • (1)代理内部selectOne和selectList怎么区别的
    根据接口的返回值来区别的。
    如果返回值是bean对象,selectOne来实现。
    如果返回值是集合对象,selectList来实现。
  • (2)Mapper接口方法只能是一个参数
    系统是否不利于扩展维护。
    系统框架中,DAO层的代码是被业务层公用的
    即使Mapper接口只有一个参数,可以使用包装类型的bean满足不同业务方法的需求。

输入映射和输出映射(进阶)

输入映射

Mybatis支持输入哪些类型
简单类型、bean,HashMap
需求:查询用户列表:已经下过订单男性用户,那么传入的参数包含用户信息(User)和订单信息(Order)

  • 准备工作新建bean作为传入参数
public class UserQueryVo {
    //用户信息
    private User user;

    private List ids = new ArrayList(  );


    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }


    public List getIds() {
        return ids;
    }

    public void setIds(List ids) {
        this.ids = ids;
    }
}
  • 修改UserMapper.xml

输出映射

resultType
(1)支持的类型
基本类型、bean(== 会按照字段名进行匹配==)、hashMap
(2)输出是bean和bean列表问题
不管是输出是单个bean,还是bean列表,在Mapper.xml中resultType都是一样的,只是在Mapper接口中返回值类型不一样。
(3)使用条件
使用resultType进行输出映射的时候,只要查询出来的列名和bean的属性名一致,该列才可以映射成功。
只要查询出来的列名和属性名有一个能对应的上,就会创建bean对象。
如果查询出来的列名和属性名没有一个能对应上,就不会创建bean对象。

  • 修改UserMapper.xml 输出映射 (使用resultMap自定义输出映射)
 //type使用别名
        
        
        
        
        
        
    
    

动态SQL(进阶)

If和where

SQL 片段

Foreach

需求(1):更新用户,前端修改了什么,SQL语句就包含哪些列
Update user set username=? where uid = ?
Update user set username=?,sex=? where uid = ?
Java 代码进行判断。
If(username ==null){
拼接SQL语句
}
需求(2):根据用户名和性别查询用户列表,
如果传递了用户名和性别,2个都作为条件
如果传递了用户名,没有传递性别,用户名作为条件
一个参数都没有传递,就没有条件
需求(3):找出用户ID在集合中List的用户
Select * from user where id in (1,2,3,4 )

  • 修改UserMapper.xml

    
        
        
        
        
        
        
    
    
    
        
            and username like "%"#{user.username}"%"
        
        
            and sex = #{user.sex}
        
    
    

    

你可能感兴趣的:(Mybatis使用之开发进阶(一))