• mybatis&代理开发&配置


    原始Dao开发的问题

    原始Dao开发中存在以下问题:
        Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
        调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。


    Mapper动态代理方式

    开发规范
    Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。


    Mapper接口开发需要遵循以下规范:
     - 1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
     - 2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 
     - 3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
     - 4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同


    具体代码

    1.Mapper.xml(映射文件)
    定义mapper映射文件UserMapper.xml
        <?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">
        <!-- namespace:命名空间,用于隔离sql -->
        <!-- 还有一个很重要的作用,使用动态代理开发DAO,1. namespace必须和Mapper接口类路径一致 -->
        <mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
    	<!-- 根据用户id查询用户 -->
    	<!-- 2. id必须和Mapper接口方法名一致 -->
    	<!-- 3. parameterType必须和接口方法参数类型一致 -->
    	<!-- 4. resultType必须和接口方法返回值类型一致 -->
    	<select id="queryUserById" parameterType="int"
    		resultType="cn.itcast.mybatis.pojo.User">
    		select * from user where id = #{id}
    	</select>
    
    
    	<!-- 根据用户名查询用户 -->
    	<select id="queryUserByUsername" parameterType="string"
    		resultType="cn.itcast.mybatis.pojo.User">
    		select * from user where username like '%${value}%'
    	</select>
    
    
    	<!-- 保存用户 -->
    	<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
    		<selectKey keyProperty="id" keyColumn="id" order="AFTER"
    			resultType="int">
    			select last_insert_id()
    		</selectKey>
    		insert into user(username,birthday,sex,address) values
    		(#{username},#{birthday},#{sex},#{address});
    	</insert>
        </mapper>
    2.UserMapper(接口文件)
    创建UserMapper接口代码如下:
        public interface UserMapper {
    	/**
    	 * 根据id查询
    	 * 
    	 * @param id
    	 * @return
    	 */
    	User queryUserById(int id);
    
    
    	/**
    	 * 根据用户名查询用户
    	 * 
    	 * @param username
    	 * @return
    	 */
    	List<User> queryUserByUsername(String username);
    
    
    	/**
    	 * 保存用户
    	 * 
    	 * @param user
    	 */
    	void saveUser(User user);
        }
    3.在SqlmapperConfig.xml中
    修改SqlMapConfig.xml文件,添加以下所示的内容:
    	<!-- 加载映射文件 -->
    	<mappers>
    		<mapper resource="UserMapper.xml" />
    	</mappers>
    4.编写测试:
        public class UserMapperTest {
    	private SqlSessionFactory sqlSessionFactory;
    
    
    	@Before
    	public void init() throws Exception {
    		// 创建SqlSessionFactoryBuilder
    		SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    		// 加载SqlMapConfig.xml配置文件
    		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    		// 创建SqlsessionFactory
    		this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    	}
    
    
    	@Test
    	public void testQueryUserById() {
    		// 获取sqlSession,和spring整合后由spring管理
    		SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
    
    		// 从sqlSession中获取Mapper接口的代理对象
    		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    		// 执行查询方法
    		User user = userMapper.queryUserById(1);
    		System.out.println(user);
    
    
    		// 和spring整合后由spring管理
    		sqlSession.close();
    	}
    
    
    	@Test
    	public void testQueryUserByUsername() {
    		// 获取sqlSession,和spring整合后由spring管理
    		SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
    
    		// 从sqlSession中获取Mapper接口的代理对象
    		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    		// 执行查询方法
    		List<User> list = userMapper.queryUserByUsername("张");
    		for (User user : list) {
    			System.out.println(user);
    		}
    
    
    		// 和spring整合后由spring管理
    		sqlSession.close();
    	}
    
    
    	@Test
    	public void testSaveUser() {
    		// 获取sqlSession,和spring整合后由spring管理
    		SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
    
    		// 从sqlSession中获取Mapper接口的代理对象
    		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    		// 创建保存对象
    		User user = new User();
    		user.setUsername("刘备");
    		user.setBirthday(new Date());
    		user.setSex("1");
    		user.setAddress("蜀国");
    		// 执行查询方法
    		userMapper.saveUser(user);
    		System.out.println(user);
    
    
    
    
    		// 和spring整合后由spring管理
    		sqlSession.commit();
    		sqlSession.close();
    	}
        }

    动态代理SqlSession和配置

    selectOne和selectList
        动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。


    SqlMapConfig.xml中配置的内容和顺序如下:
    properties(属性)
    settings(全局配置参数)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境集合属性对象)
    environment(环境子属性对象)
    transactionManager(事务管理)
    dataSource(数据源)
    mappers(映射器)


    namespace
        mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。


    可以SqlMapperConfig.xml引用properties配置

    db.properties配置文件内容如下:
        jdbc.driver=com.mysql.jdbc.Driver
        jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
        jdbc.username=root
        jdbc.password=root
    SqlMapperConfig.xml使用
        <!-- 是用resource属性加载外部配置文件 -->
    	<properties resource="db.properties">
    		<!-- 在properties内部用property定义属性 -->
    		<!-- 如果外部配置文件有该属性,则内部定义属性被外部属性覆盖 -->
    		<property name="jdbc.username" value="root123" />
    		<property name="jdbc.password" value="root123" />
    	</properties>
    
    
        <!-- 数据库连接池 -->
    	<dataSource type="POOLED">
    		<property name="driver" value="${jdbc.driver}" />
    		<property name="url" value="${jdbc.url}" />
    		<property name="username" value="${jdbc.username}" />
    		<property name="password" value="${jdbc.password}" />
    	</dataSource>
    MyBatis 将按照下面的顺序来加载属性:
    在 properties 元素体内定义的属性首先被读取。 
    然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性


    别名和自定义别名

    ![mybatis的别名支持.png][1]
    在SqlMapConfig.xml中配置自定义别名(在mapper.xml配置文件中,就可以使用设置的别名了):
        <typeAliases>
    	<!-- 单个别名定义 -->
    		<typeAlias alias="user" type="cn.itcast.mybatis.pojo.User" />
    		<!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
    		<package name="cn.itcast.mybatis.pojo" />
    		<package name="其它包" />
        </typeAliases>

    mapper映射器配置

    Mapper配置的几种方法:
    <mapper resource=" " />
        使用相对于类路径的资源(现在的使用方式)
        如:<mapper resource="sqlmap/User.xml" />


    <mapper class=" " />
        使用mapper接口类路径
        如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>


    注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。


    <package name=""/>
    注册指定包下的所有mapper接口
        如:<package name="cn.itcast.mybatis.mapper"/>
        注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
  • 相关阅读:
    [LuoguP2161] 会场预约
    [LuoguP1198] 最大数
    [LuoguP1484] 种树
    [LuoguP1801] 黑匣子
    [LuoguP1196]银河英雄传说
    [LuoguP1345] 奶牛的电信Telecowmunication
    [LuoguP1119]灾后重建
    【笔记】一元函数微分学
    【复习】Listening and Reading Comprehension
    【笔记】一元函数的不定积分
  • 原文地址:https://www.cnblogs.com/sybk/p/10004725.html
Copyright © 2020-2023  润新知