我们只需要编写DAO接口和mapper.xml文件即可,DAO接口实现对象由mybatis自动生成代理对象。

如:

9d3b5cafebc8e2ccb0f7ee57241033fb.png



一、为什么不使用原始的DAO方式开发呢?


1、dao的实现类中存在重复代码,整个mybatis操作的过程代码模板重复(先创建sqlsession、调

sqlsession的方法、关闭sqlsession

2、dao的实现类中存在硬编码,调用sqlsession方法时将statementid硬编码。

如:

c0255b865145972bc81b23ecfe658c3e.png



二、mapper代理方式开发规范,或者说,开发规则?必须要遵守人家的规定:


2.1 规范:


1mapper.xmlnamespace指定为mapper接口的全限定名(就是指类的全路径)

27c4b8af73ceb19cd48fba60459f984e.png



此步骤目的:通过mapper.xmlmapper.java进行关联。

 

2mapper.xmlstatementid就是mapper.java中方法名

 5ea01404f68325d4706d1d15b7e48198.png

3mapper.xmlstatementparameterTypemapper.java中方法输入参数类型一致

 

4mapper.xmlstatementresultTypemapper.java中方法返回值类型一致.


2.2 什么是statement?


2eb2787079e9641d97d0e3f1f2d0dc0d.png



三、mapper.xml文件介绍(如UserMapper.xml文件)


mapper映射文件的命名方式建议:表名 + Mapper.xml


namespace指定为mapper接口的全限定名


UserMapper.xml放在classpath mapper目录下。


如文件内容:

<?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语句进行隔离,方便管理 ,mapper开发dao方式,使用namespace有特殊作用 -->
<!-- com.xingej.mybatis.mapper.UserMapper 这种方式,就是 全限定名 -->
<mapper namespace="com.xingej.mybatis.mapper.UserMapper">
	<!-- 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,
	封装为MappedStatement对象 mapper.xml以statement为单位管理sql语句 -->
	<!-- 根据id查询用户信息 -->
	<!-- id:唯一标识 一个statement #{}:表示 一个占位符,如果#{}中传入简单类型的参数,#{}中的名称随意 parameterType:输入 
		参数的类型,通过#{}接收parameterType输入 的参数 resultType:输出结果 类型,不管返回是多条还是单条,指定单条记录映射的pojo类型 -->
	<select id="findUserById" parameterType="int" resultType="user">
		SELECT
		* FROM USER WHERE id= #{id}

	</select>

	<!-- 根据用户名称查询用户信息,可能返回多条 ${}:表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。 ${}方式的缺点:不能防止sql的注入;select 
		* from user where name like 'xiaoming' or '1=1' 这条语句,始终成立,后面的' or '1= 就是sql注入; 
		有的时候,软件在交付的时候,会进行sql注入的校验。 -->
	<select id="findUserByName" parameterType="java.lang.String"
		resultType="com.xingej.mybatis.po.User">
		select * from user where username like '%${value}%'
	</select>

	<!-- 添加用户 parameterType:输入 参数的类型,User对象 包括 username,birthday,sex,address 
		#{}接收pojo数据,可以使用OGNL解析出pojo的属性值 #{username}表示从parameterType中获取pojo的属性值 selectKey:用于进行主键返回,定义了获取主键值的sql 
		order:设置selectKey中sql执行的顺序,相对于insert语句来说 keyProperty:将主键值设置到哪个属性 resultType:select 
		LAST_INSERT_ID()的结果 类型 -->
	<insert id="insertUser" parameterType="com.xingej.mybatis.po.User">
		<selectKey keyProperty="id" order="AFTER" resultType="int">
			select
			LAST_INSERT_ID()
		</selectKey>

		INSERT INTO USER(username,birthday,sex,address)
		VALUES(#{username},#{birthday},#{sex},#{address})
	</insert>

	<!-- mysql的uuid生成主键 -->
	<!-- <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> 
		<selectKey keyProperty="id" order="BEFORE" resultType="string"> select uuid() 
		</selectKey> INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address}) 
		</insert> -->

	<!-- oracle 在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 
		的id属性 -->
	<!-- <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> 
		<selectKey keyProperty="id" order="BEFORE" resultType="int"> select 序列.nextval() 
		from dual </selectKey> INSERT INTO USER(id,username,birthday,sex,address) 
		VALUES(#{id},#{username},#{birthday},#{sex},#{address}) </insert> -->

	<!-- 用户删除 -->
	<delete id="deleteUser" parameterType="int">
		delete from user where id=#{id}
	</delete>
	<!-- 用户更新 要求:传入的user对象中包括 id属性值 -->
	<update id="updateUser" parameterType="com.xingej.mybatis.po.User">
		update user set
		username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
		where id=#{id}
	</update>

	<!-- 自定义查询条件,查询用户信息 parameterType:指定包装类型
	%${userCustom.username}%:userCustom是userQueryVo中的属性,通过OGNL获取属性的值
	
	 -->
	<select id="findUserList" parameterType="userQueryVo"
		resultType="user">
	select * from user where username like '%${userCustom.username}%'
	</select>


</mapper>



四、mapper接口 说明:


mybatis提出了mapper接口,相当 dao 接口。

mapper接口的命名方式建议:表名+Mapper

例子:

public interface UserMapper {
    // 根据ID来查询用户信息
    public User findUserById(int id);

    // 根据用户名称来查询用户信息
    public List<User> findUserByName(String userName);

    //
    public List<User> findUserList(UserQueryVo userQueryVo);

    public void insertUser(User user);

    public void deleteUser(int id);

    public void updateUser(User user);
}


4.1 将mapper.xml在SqlMapConfig.xml中加载(也就是注册)


在SqlMapConfig.xml中添加mappers标签,如下所示:

	<mappers>
		<!-- 通过resources一弄mapper的映射文件 -->
		<mapper resource="sqlMap/User.xml" />
		<!-- 注册 -->
		<mapper resource="mapper/UserMapper.xml" />
	</mappers>


4.2 mapper接口返回单个对象和集合对象

  

   不管查询记录是单条还是多条,在 statementresultType定义一致,都是单条记录映射的pojo类型。

mapper接口方法返回值:

      如果是返回的单个对象,返回值类型是pojo类型,生成的代理对象内部通过selectOne获取记录,

      如果返回值类型是集合对象,生成的代理对象内部通过selectList获取记录。

如:

public interface UserMapper {
    // 根据ID来查询用户信息,返回单个对象
    public User findUserById(int id);

    // 根据用户名称来查询用户信息,返回集合对象
    public List<User> findUserByName(String userName);

}


五、SqlMapConfig.xml文件介绍


5.1 SqlMapConfig.xml中配置的内容和顺序如下: 


properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)


5.1.1 properties属性定义?


就是把一些通用的属性值配置在属性文件中,加载到mybatis运行环境内。

如:创建db.properties配置数据库连接参数。 

db.properties文件的内容如下:

#这里定义的属性,是用在SqlMapConfig.xml里的properties属性里
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

通过properties属性,就可以将db.properties文件加载到SqlMapConfig.xml里,如下所示:

2b9f82dff06bc5d23a576c27b04102a6.png


注意: MyBatis 将按照下面的顺序来加载属性:

  • properties 元素体内定义的属性首先被读取。

  • 然后会读取properties元素中resource url 加载的属性,它会覆盖已读取的同名属性。

  • 最后读取parameterType传递的属性,它会覆盖已读取的同名属性。

 

建议使用properties,不要在properties中定义属性,只引用定义的properties文件中属性,并且properties文件中定义的key要有一些特殊的规则。


5.1.2 settings全局参数配置


mybatis运行时可以调整一些全局参数(相当于软件的运行参数),参考:mybatis-settings.xlsx

根据使用需求进行参数配置。

注意:小心配置,配置参数会影响mybatis的执行。

 

ibatis的全局配性能的运行,mybatis没有这些性能参数,由mybatis自动调节。置参数中包括很多的性能参数(最大线程数,最大待时间。。。),通过调整这些性能参数使ibatis达到高


5.1.3 typeAliases 指定别名(常用)


可以将parameterTyperesultType中指定的类型通过别名引用

在SqlMapConfig.xml文件里自定义别名,在mapper.xml文件使用。

定义:

2ed5201c5d91587638ddcac479075ea0.png

使用:

    fc2ede7d85192dc7b9e8a084a74ce251.png


5.1.4 mappers 参数说明:


    作用:就是加载/注册mapper.xml文件的

操作的文件:SqlMapConfig.xml

目前,这里有三种方式注册,如下图说说:

4c91113ad505d6bc63e7f86f3434c0cf.png


六、参考例子:


   定义UserMapper接口:

 

package com.xingej.mybatis.mapper;

import java.util.List;

import com.xingej.mybatis.po.User;
import com.xingej.mybatis.po.UserQueryVo;

public interface UserMapper {
    // 根据ID来查询用户信息,返回单个对象
    public User findUserById(int id);

    // 根据用户名称来查询用户信息,返回集合对象
    public List<User> findUserByName(String userName);

    //
    public List<User> findUserList(UserQueryVo userQueryVo);

    public void insertUser(User user);

    public void deleteUser(int id);

    public void updateUser(User user);
}


进行测试:

package com.xingej.mybatis.mapper;

import java.io.InputStream;
import java.util.Date;
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 com.xingej.mybatis.po.User;
import com.xingej.mybatis.po.UserCustom;
import com.xingej.mybatis.po.UserQueryVo;

public class UserMapperTest {
    // 先创建一个会话工厂
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        // 配置文件(SqlMapConfig.xml)
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    // 根据用户ID来查询用户信息
    @Test
    public void testFindUserById() {
        // 创建一个session
        SqlSession session = sqlSessionFactory.openSession();

        UserMapper userMapper = session.getMapper(UserMapper.class);

        User user = userMapper.findUserById(1);

        System.out.println("----mapper方式-----:\n" + user);
    }

    // 根据用户名称来查询用户信息
    @Test
    public void testFindUserByUserName() {
        // 创建一个session
        SqlSession session = sqlSessionFactory.openSession();

        UserMapper userMapper = session.getMapper(UserMapper.class);

        List<User> userList = userMapper.findUserByName("小明");

        System.out.println("----mapper方式-----:\n" + userList.get(0).getUsername());
    }

    // 插入用户信息
    @Test
    public void testInsertUser() {
        // 创建一个session
        SqlSession session = sqlSessionFactory.openSession();

        // 产生代理对象
        UserMapper userMapper = session.getMapper(UserMapper.class);

        User user = new User();

        user.setAddress("北京");
        user.setBirthday(new Date());
        user.setSex("1");
        user.setUsername("燕青");

        userMapper.insertUser(user);
        session.commit();

        System.out.println("----mapper方式-----:\n");
    }

    // 删除用户
    @Test
    public void testDeleteUser() {
        // 创建一个session
        SqlSession session = sqlSessionFactory.openSession();

        UserMapper userMapper = session.getMapper(UserMapper.class);

        userMapper.deleteUser(1);

        session.commit();
    }

    // 更新用户
    @Test
    public void testUpdateUser() {
        // 创建一个session
        SqlSession session = sqlSessionFactory.openSession();

        UserMapper userMapper = session.getMapper(UserMapper.class);

        User user = new User();

        user.setAddress("北京");
        user.setBirthday(new Date());
        user.setSex("1");
        user.setUsername("燕青");
        user.setId(1);

        userMapper.updateUser(user);
        session.commit();
    }

    // 通过包装的类型,查询用户的信息
    @Test
    public void testFindUserList() {
        // 创建一个session
        SqlSession session = sqlSessionFactory.openSession();

        UserMapper userMapper = session.getMapper(UserMapper.class);

        UserQueryVo userQueryVo = new UserQueryVo();

        UserCustom userCustom = new UserCustom();
        userCustom.setUsername("小");
        userQueryVo.setUserCustom(userCustom);

        List<User> userList = userMapper.findUserList(userQueryVo);

        session.close();

        System.out.println("----->:\t" + userList.size());

    }

}


代码已提交到git上:

https://github.com/xej520/xingej-mybatis