zoukankan      html  css  js  c++  java
  • mybatis入门--mapper代理方式开发

             不使用代理开发

             之前,我们说了如何搭建mybatis框架以及我们使用mybatis进行简单的增删改查.现在,我们一起来构建一个dao层的完整代码.并用@test来模拟service层对dao层进行一下调用.

             其实构建很简单,跟我们之前的差不多.如果不是为了演示其中的弊端,我甚至都懒得再写这些东西了.我们这次用UserDao为大家演示.

             首先是导包、创建log4j.properties文件、创建sqlMapConfig.xml文件、创建User类、创建User.xml文件、将User.xml文件配置daosqlMapConfig.xml文件的过程我就不说了。不清楚的可以去看之前的博客。

              先是创建一个dao的包,然后创建UserDao的接口,然后创建一个UserDaoImpl的实现类去实现UserDao的接口。为了便于说明问题这里的UserDao中写两个方法。其中,UserDao接口中的代码是这样的:

    package cn.itcast.dao;
    
    import java.util.List;
    
    import cn.itcast.pojo.User;
    
    public interface UserDao {
    
    	public User findUserById(Integer id);
    	
    	public List<User> findUserByUserName(String userName);
    }
    

             UserDaoImpl类的代码如下:

    package cn.itcast.dao;
    
    import java.util.List;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    
    import cn.itcast.pojo.User;
    
    public class UserDaoImpl implements UserDao {
    	
    	private SqlSessionFactory factory;
    	
    	//通过构造方法, 工厂由外部初始化好传入这里
    	public UserDaoImpl(SqlSessionFactory factory) {
    		this.factory = factory;
    	}
    
    	@Override
    	public User findUserById(Integer id) {
    		//创建会话, 会话是线程不安全的, 所以它的最佳使用范围在方法体内
    		SqlSession openSession = factory.openSession();
    		User user = openSession.selectOne("test.findUserById", id);
    		return user;
    	}
    
    	@Override
    	public List<User> findUserByUserName(String userName) {
    		//创建会话, 会话是线程不安全的, 所以它的最佳使用范围在方法体内
    		SqlSession openSession = factory.openSession();
    		List<User> list = openSession.selectList("test.findUserByUserName", userName);
    		return list;
    	}
    
    }
    

             调用UserDaoImpl的类在调用的时候代码类似于下面的测试代码:

    package cn.itcast;
    
    import java.io.InputStream;
    import java.util.List;
    
    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 cn.itcast.dao.UserDao;
    import cn.itcast.dao.UserDaoImpl;
    import cn.itcast.pojo.User;
    
    public class UserDaoTest {
    	
    	private SqlSessionFactory factory;
    	
    	@Before //@Before注解作用就是在执行@Test前执行
    	public void init() throws Exception{
    		String resource = "SqlMapConfig.xml";
    		//通过流将核心配置文件读入
    		InputStream inputStream = Resources.getResourceAsStream(resource);
    		//通过核心配置文件输入流, 创建会话工厂
    		factory = new SqlSessionFactoryBuilder().build(inputStream);
    	}
    
    	@Test
    	public void testFindUserById() throws Exception {
    		//实例化UserDao
    		UserDao userDao = new UserDaoImpl(factory);
    		
    		User user = userDao.findUserById(1);
    		
    		System.out.println(user);
    	}
    	
    	@Test
    	public void testFindUserByUserName() throws Exception {
    		//实例化UserDao
    		UserDao userDao = new UserDaoImpl(factory);
    		
    		List<User> list = userDao.findUserByUserName("王");
    		System.out.println(list);
    	}
    }

             不使用代理开发的弊端及使用代理开发的好处

             通过上面的演示,相信有的同学已经发现了,我们的UserDaoImpl类中有很多代码看起来让人感觉很不舒服,如下图所示,方框中的代码看起来有很多都是重复的,而且剩下的代码基本就是一个构造方法。

       

             为了解决上图中的问题,mybatis提供了一个代理类,可以让我们不再用写mybatis类的代码。这样做可以让我们不再用自己写dao层接口的实现类,不过对我们的pojo的配置文件有一些要求。接下来为大家演示如何使用代理(mapper代理)来开发我们的Userapper。

             使用代理开发应该如何配置

             为了可以使用我们的mapper代理,我们需要将我们的pojo的配置文件做一些要求。首先就是我们的nameSpace属性。这里我们必须将我们的namespace中的值配置成我们的接口的全路径。然后就是每条sql语句对应的是一个接口中的方法。映射文件中的sql语句的id位置必须配置为接口中的方法名。输入类型对应的是接口中的输入类型,输出类型对应的是接口中的输出类型。接口和配置文件的代码如下:

             接口:

    package cn.itcast.mapper;
    
    import java.util.List;
    
    import cn.itcast.pojo.QueryVo;
    import cn.itcast.pojo.User;
    
    public interface UserMapper {
    
    	public User findUserById(Integer id);
    	
    	public List<User> findUserByUserName(String userName);
    	
    	public List<User> findUserByVo (QueryVo vo);
    	
    	public Integer findUserCount();
    	
    	public List<User> findUserByUserNameAdnSex(User user );
    }
    

            映射文件:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!-- 
    	mybatis动态代理方式开发规范:
    		1) 映射文件中的namespace必须等于接口的全路径名称
    		2) 映射文件中sql语句的id必须等于接口中方法的方法名
    		3) 映射文件中传入参数parameterType指定的类型必须等于接口方法的传入参数类型
    		4) 映射文件中返回的结果集类型必须等于接口方法的返回值类型
     -->
    <mapper namespace="cn.itcast.mapper.UserMapper">
    	
    	<select id="findUserById" parameterType="int" resultType="cn.itcast.pojo.User">
    		SELECT * FROM user where id=#{id}
    	</select>
    	
    	<select id="findUserByUserName" parameterType="string" resultType="cn.itcast.pojo.User">
    		SELECT * FROM user where username like '%${value}%'
    	</select>
    	<select id="findUserByVo" parameterType="cn.itcast.pojo.QueryVo" resultType="cn.itcast.pojo.User">
    		select * from user where username like'%${user.username}%' and sex =#{user.sex}
    	</select>
    	<select id="findUserCount" parameterType="cn.itcast.pojo.QueryVo" resultType="int">
    		select count(id) from user 
    	</select>
    	<select id="findUserByUserNameAdnSex" parameterType="cn.itcast.pojo.User" resultType="cn.itcast.pojo.User">
    		select * from user
    		<where>
    			<if test="username != null and username != ''">
    				and username  like'%${username}%' 
    			</if>
    			<if test="sex != null and sex != ''">
    				and sex =#{sex}
    			</if>
    		
    		</where>
    	</select>
    </mapper>

             因为不再有具体的实体类了,所以service层需要调用我们的代理类的对象,那么如何获得代理对象呢?在会话session中有个方法getMapper。在这个方法中,我们把我们的接口类型的字节码对象传入,然后获得接口的实现类的对象。通过操作这个对象的方法,实现对数据库的增删改查,代码如下:

    package cn.itcast;
    
    import static org.junit.Assert.*;
    
    import java.io.InputStream;
    import java.util.List;
    
    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 cn.itcast.mapper.UserMapper;
    import cn.itcast.pojo.QueryVo;
    import cn.itcast.pojo.User;
    
    public class UserMapperTest {
    
    	private SqlSessionFactory factory;
    	
    	@Before //@Before注解作用就是在执行@Test前执行
    	public void init() throws Exception{
    		String resource = "SqlMapConfig.xml";
    		//通过流将核心配置文件读入
    		InputStream inputStream = Resources.getResourceAsStream(resource);
    		//通过核心配置文件输入流, 创建会话工厂
    		factory = new SqlSessionFactoryBuilder().build(inputStream);
    	}
    	
    	@Test
    	public void testFindUserById() throws Exception {
    		//通过工厂创建会话
    		SqlSession openSession = factory.openSession();
    		//通过会话的getMapper方法来实例化 接口
    		UserMapper mapper = openSession.getMapper(UserMapper.class);
    		
    		User user = mapper.findUserById(1);
    		System.out.println(user);
    	}
    	
    	@Test
    	public void testFindUserByUserName() throws Exception {
    		//通过工厂创建会话
    		SqlSession openSession = factory.openSession();
    		//通过会话的getMapper方法来实例化 接口
    		UserMapper mapper = openSession.getMapper(UserMapper.class);
    		
    		List<User> list = mapper.findUserByUserName("王");
    		
    		System.out.println(list);
    	}
    	
    	@Test
    	public void testFindUserCount() throws Exception {
    		//通过工厂创建会话
    		SqlSession openSession = factory.openSession();
    		//通过会话的getMapper方法来实例化 接口
    		UserMapper mapper = openSession.getMapper(UserMapper.class);
    		
    		 Integer count = mapper.findUserCount();
    		
    		System.out.println(count);
    	}
    	
    	@Test
    	public void testfindUserByVo() throws Exception {
    		//通过工厂创建会话
    		SqlSession openSession = factory.openSession();
    		//通过会话的getMapper方法来实例化 接口
    		UserMapper mapper = openSession.getMapper(UserMapper.class);
    		
    		QueryVo vo = new QueryVo();
    		
    	
    		User user= new User();
    		//user.setUsername("张");
    		user.setSex("1");
    		
    		
    		vo.setUser(user);
    		
    		List<User> list = mapper.findUserByVo(vo);
    		
    		System.out.println(list);
    	}
    	@Test
    	public void testFindUserByUserNameAdnSex() throws Exception {
    		//通过工厂创建会话
    		SqlSession openSession = factory.openSession();
    		//通过会话的getMapper方法来实例化 接口
    		UserMapper mapper = openSession.getMapper(UserMapper.class);
    		User user= new User();
    		//user.setUsername("张");
    		//user.setSex("1");
    		
    		
    	
    		
    		List<User> list = mapper.findUserByUserNameAdnSex(user);
    		
    		System.out.println(list);
    	}
    	
    	
    	
    }




  • 相关阅读:
    61. 最长不含重复字符的子字符串
    60. 礼物的最大价值 (未理解)
    59. 把数字翻译成字符串
    58. 把数组排成最小的数
    57. 数字序列中某一位的数字 (不懂)
    spring data jpa 官方文档
    idea 编译报错 源发行版 1.8 需要目标发行版 1.8
    idea maven 依赖报错 invalid classes root
    solr
    spring boot 官方文档
  • 原文地址:https://www.cnblogs.com/liyasong/p/mybatis_mapper.html
Copyright © 2011-2022 走看看