一、注意规范
注意:(1).XXXmapper.xml 文件中的 namespace 等于mapper 接口地址
(2).XXXmapper.java 接口中的方法输入参数和 mapper.xml 中statement的parameterType指定的 类型一致。
(3) .mapper.java 接口中的方法的返回值类型和mapper.xml中statement的resultType指定的类型一致
二、配置文件及标签介绍
1. properties 介绍
可以将数据连接单独配置在 db.properties 中改善硬编码,其他配置文件引用该文件。内容示例:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=root
2.核心配置 SqlMapConfig.xml 标签介绍
标签种类:
1. properties(属性)
<!-- 加载数据库文件db.properties -->
<properties resource="db.properties">
<!--
properties中还可以配置一些属性名和属性值,此处的优先加载
读取完此标签内再读取其他文件。如果有同名属性,则会被读取文件中的覆盖
-->
<!-- <property name="driver" value=""/> -->
</properties>
2. settings(全局配置参数): 可以调整一些运行参数:开启二级缓存、开启延迟加载等。会影响mybatis的运动行为
3. typeAiases(类型别名):指定输入输出类型较不方便,可以针对 parameterType、resourceType 指定的类型定义一些别名
3.1 默认支持的别名
别名 | _byte | _long | _short | _int | _integer | _double | _float | _boolean | string | byte |
类型 | byte | long | short | int | int | doouble | float | boolean | String | Byte |
别名 | long | short | int | integer | double | float | boolean | data | decimal | bigdecimal |
类型 | Long | Short | Integer | Integer | Double | Float | Boolean | Data | BigDecimal | BigDecimal |
3.2 自定义别名
<!-- 针对单个别名定义 type:类型的路径; alias:别名 --> <typeAliases> <typeAlias type="com.mybatis.entity.User" alias="user"/> </typeAliases> <select id="findUserById" parameterType="int" resultType="user" > select * from t_user where id=#{id} </select> <!-- 批量别名的定义: package:指定包名,mybatis会自动扫描包中的pojo类,自动定义别名,别名就是类名(首字母大写或小写都可以) --> <typeAliases> <package name="com.mybatis.entity"/> <package name="其它包"/> </typeAliases>
4. typeHandlers(类型处理器):完成 jdbc 类型和 java 类型的转换
5. objectFactory(对象工厂)
6. plugins(插件)
7. environments(环境集合属性对象)mappers(映射器)
7.1 environment (环境子属性对象)
7.2 transactionManager(事务管理)
7.3 datasource(数据源)
<!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理,事务控制由mybatis管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池,由mybatis管理--> <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> </environment> </environments>
8.mapper(映射器)
<!-- 加载映射文件 --> <mappers> <!-- 通过resource方法一次加载一个映射文件 --> <mapper resource="sqlmap/User.xml"/> <mapper resource="mapper/UserMapper.xml"/> <!-- 通过mapper接口加载单个映射配置文件 需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 --> <mapper class="com.mybatis.mapper.UserMapper"/> <!-- 批量加载映射配置文件,mybatis自动扫描包下面的mapper接口进行加载 需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中; 上边规范的前提是:使用的是mapper代理方法; --> <package name="com.mybatis.mapper"/> </mappers>
三、输入、输出 映射
1.输入映射:通过 parameterType 指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型
如需要查询的条件较复杂,可以使用自定义的包装类型 pojo ,将复杂的查询条件包含进去
1.1 复杂的包装类 UserQueryVo 示例
public class UserQueryVo { //这里包装其它的查询条件 //用户查询条件 private UserCustom userCustom; public UserCustom getUserCustom() { return userCustom; } public void setUserCustom(UserCustom userCustom) { this.userCustom = userCustom; } }
1.2 再复杂一下 UserCustom.java 示例
public class UserCustom extends User{ //可以扩展用户的信息 }
1.3 配置文件 UserMapper.xml 定义综合查询示例
<!-- 模拟包装类型组合查询 #{userCustom.sex}:取出pojo包装对象中性别值 ${userCustom.username}:取出pojo对象中姓名值 --> <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" resultType="com.mybatis.entity.UserCustom"> where sex=#{userCustom.sex} and username LIKE ‘%${userCustom.username}%‘ </select>
1.4 UserMapper.java 示例
public interface UserMapper { // 用户信息综合查询 public List<UserCustom> findUserList(UserQueryVo userQueryVo); }
1.5 Junit 测试代码
1 ackage com.mybatis.dao.test; 2 3 import java.io.InputStream; 4 import java.util.Date; 5 import java.util.List; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 import org.junit.Before; 12 import org.junit.Test; 13 14 import com.mybatis.entity.User; 15 import com.mybatis.entity.UserCustom; 16 import com.mybatis.entity.UserQueryVo; 17 import com.mybatis.mapper.UserMapper; 18 19 public class UserMapperTest { 20 21 private SqlSessionFactory sqlSessionFactory; 22 23 // 此方法是在执行findUserByIdTest之前执行 24 @Before 25 public void setUp() throws Exception { 26 String resource = "SqlMapConfig.xml"; 27 InputStream inputStream = Resources.getResourceAsStream(resource); 28 // 创建SqlSessionFcatory 29 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 } 31 32 @Test 33 public void testFindUserList() { 34 SqlSession sqlSession = sqlSessionFactory.openSession(); 35 //创造查询条件 36 UserQueryVo userQueryVo = new UserQueryVo(); 37 UserCustom userCustom = new UserCustom(); 38 userCustom.setSex("2"); 39 userCustom.setUsername("小"); 40 userQueryVo.setUserCustom(userCustom); 41 // 创建Usermapper对象,mybatis自动生成mapper代理对象 42 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 43 List<UserCustom>list=mapper.findUserList(userQueryVo); 44 System.out.println(list); 45 sqlSession.commit(); 46 sqlSession.close(); 47 } 48 }
2.输出映射:只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功
(如果查询出来的列名和 pojo 中属性名只要有一个一致,就会创建 pojo 对象,只有全部不一样才会不创建对象)
2.1 输出简单类型:只有输出的结果只有一行一列才可以使用
2.1.1 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"> <!-- 用户信息综合查询总数 parameterType:指定输入类型,和findUserList一致。 resultType:输出结果类型. --> <mapper namespace="com.mybatis.mapper.UserMapper"> <select id="findUserCount" parameterType="com.mybatis.entity.UserQueryVo" resultType="int"> select count(*) from t_user where sex=#{userCustom.sex} and username like ‘%${userCustom.username}%‘ </select> </mapper>
2.1.2 UserMapper.java
public interface UserMapper { //用户信息综合查询总数 public int findUserCount(UserQueryVo userQueryVo); }
2.1.3 junit 测试
1 package com.mybatis.dao.test; 2 3 import java.io.InputStream; 4 import java.util.Date; 5 import java.util.List; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 import org.junit.Before; 12 import org.junit.Test; 13 14 import com.mybatis.entity.User; 15 import com.mybatis.entity.UserCustom; 16 import com.mybatis.entity.UserQueryVo; 17 import com.mybatis.mapper.UserMapper; 18 19 public class UserMapperTest { 20 21 private SqlSessionFactory sqlSessionFactory; 22 23 // 此方法是在执行findUserByIdTest之前执行 24 @Before 25 public void setUp() throws Exception { 26 String resource = "SqlMapConfig.xml"; 27 InputStream inputStream = Resources.getResourceAsStream(resource); 28 // 创建SqlSessionFcatory 29 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 } 31 32 @Test 33 public void findUserCountTest() { 34 SqlSession sqlSession = sqlSessionFactory.openSession(); 35 //创造查询条件 36 UserQueryVo userQueryVo = new UserQueryVo(); 37 UserCustom userCustom = new UserCustom(); 38 userCustom.setSex("2"); 39 userCustom.setUsername("小"); 40 userQueryVo.setUserCustom(userCustom); 41 // 创建Usermapper对象,mybatis自动生成mapper代理对象 42 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 43 int count=mapper.findUserCount(userQueryVo); 44 System.out.println(count); 45 sqlSession.commit(); 46 sqlSession.close(); 47 } 48 }
2.2 输出 pojo 对象和 pojo 列表:单个或列表,在 mapperType 类型是一样的,在 mapper.java 中返回值不一样
2.2.1 方法返回值区别示例
public interface UserMapper { /** 根据ID查询用户信息 */ // 返回单个 public User findUserById(int id); /** 根据用户名称模糊查询用户信息 */ // 返回列表 public List<User> findUserByName(String username); }
2.2.2 使用 resoultMap 作为输出映射类型
定义 resoultMap
<?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进行分类化的管理,理解为sql隔离 注意:使用mapper代理开发时,namespace有特殊作用,namespace等于mapper接口地址 --> <!-- 用户信息综合查询总数 parameterType:指定输入类型,和findUserList一致。 resultType:输出结果类型. --> <mapper namespace="com.mybatis.mapper.UserMapper"> <!-- 定义resultMap select id id_,username username_ from t_user和User类中的属性作为一个映射关系 type:resultMap最终映射的java对象类型,可以使用别名; id:对resultMap的唯一标识 --> <resultMap type="user" id="userResultMap"> <!--id表示查询结果中的唯一标识, column:查询出来的列名 property:type指定的pojo类型中的属性名 最终resultMap对column和property作一个映射关系(对应关系) --> <id column="id_" property="id"/> <!--result:表示对普通列名的映射, column:查询出来的列名 property:type指定的pojo类型中的属性名 最终resultMap对column和property作一个映射关系(对应关系) --> <result column="username_" property="username"/> </resultMap> </mapper>
使用 resoultMap
<!-- 使用resultMap作为输出映射 resultMap:指定定义的resultMap的id,如果这个resultMap在其它的mapper.xml文件中,前边需要添加namespace命名空间 --> <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap" > select id id_,username username_ from t_user where id=#{id} </select>
UserMapper.java示例
public interface UserMapper { /** 根据ID查询用户信息,使用resultMap进行输出 */ public User findUserByIdResultMap(int id); }
Junit 测试示例
1 package com.mybatis.dao.test; 2 3 import java.io.InputStream; 4 import java.util.Date; 5 import java.util.List; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 import org.junit.Before; 12 import org.junit.Test; 13 14 import com.mybatis.entity.User; 15 import com.mybatis.entity.UserCustom; 16 import com.mybatis.entity.UserQueryVo; 17 import com.mybatis.mapper.UserMapper; 18 19 public class UserMapperTest { 20 21 private SqlSessionFactory sqlSessionFactory; 22 23 // 此方法是在执行findUserByIdTest之前执行 24 @Before 25 public void setUp() throws Exception { 26 String resource = "SqlMapConfig.xml"; 27 InputStream inputStream = Resources.getResourceAsStream(resource); 28 // 创建SqlSessionFcatory 29 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 } 31 32 @Test 33 public void testFindUserByIdResultMap() { 34 SqlSession sqlSession = sqlSessionFactory.openSession(); 35 // 创建Usermapper对象,mybatis自动生成mapper代理对象 36 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 37 User user = mapper.findUserByIdResultMap(1); 38 System.out.println(user); 39 sqlSession.close(); 40 } 41 }
2.3 用 resultType 进行输出映射时,只有查询出来的列名和 pojo 中的属性名一致,该列才可以映射成功。如果不一致,可以通过定义一个 resultType 对列名和 pojo 属性名之间作为一个映射关系
四、
1.动态SQL:mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对SQL进行拼接、组装
UserMapper.xml、Junit测试代码示例:
1 <!-- 用户信息综合查询 2 #{userCustom.sex}:取出pojo包装对象中性别值 3 ${userCustom.username}:取出pojo对象中用户名称 4 --> 5 <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" 6 resultType="com.mybatis.entity.UserCustom"> 7 select * from t_user 8 <!-- 动态sql查询:where可以自动去掉第一个and --> 9 <where> 10 <if test="userCustom!=null"> 11 <if test="userCustom.sex!=null and userCustom.sex!=‘‘ "> 12 and sex=#{userCustom.sex} 13 </if> 14 <if test="userCustom.username!=null and userCustom.username!=‘‘ "> 15 and username=#{userCustom.username} 16 </if> 17 </if> 18 </where> 19 <!-- where sex=#{userCustom.sex} and username LIKE ‘%${userCustom.username}%‘ --> 20 </select>
1 @Test 2 public void testFindUserList() { 3 SqlSession sqlSession = sqlSessionFactory.openSession(); 4 //创造查询条件 5 UserQueryVo userQueryVo = new UserQueryVo(); 6 UserCustom userCustom = new UserCustom(); 7 // userCustom.setSex("2"); 8 //这里使用动态sql,如果不设置某个值,条件不会拼接sql中 9 userCustom.setUsername("小"); 10 userQueryVo.setUserCustom(userCustom); 11 // 创建Usermapper对象,mybatis自动生成mapper代理对象 12 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 13 List<UserCustom>list=mapper.findUserList(userQueryVo); 14 //测试动态sql,属性的非空判断测试 15 // List<UserCustom>list=mapper.findUserList(null); 16 System.out.println(list); 17 sqlSession.commit(); 18 sqlSession.close(); 19 }
2. SQL片段:抽取动态sql,组成一个sql片段,方便重复调用
2.1 定义sql片段
<!-- 定义sql片段,Id是唯一标识 建议:是基于单表来定义sql片段,这样的话sql片段的可重用性才高,在sql片段中不要包含where --> <sql id="query_user_where" > <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!=‘‘ "> and sex=#{userCustom.sex} </if> <if test="userCustom.username!=null and userCustom.username!=‘‘ "> and username=#{userCustom.username} </if> </if> </sql>
2.2 在 mapper.xml 中定义的 statement 中引用sql片段
<!-- 用户信息综合查询 #{userCustom.sex}:取出pojo包装对象中性别值 ${userCustom.username}:取出pojo对象中用户名称 --> <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" resultType="com.mybatis.entity.UserCustom"> select * from t_user <!-- 动态sql查询:where可以自动去掉第一个and --> <where> <!-- 引用sql片段的id,如果refid指定的不在本mapper.xml中,需要前边加namespace --> <include refid="query_user_where"></include> <!-- 这里可以引用其它的sql片段 --> </where> </select>
3. foreach:向 sql 传递数组或 list 时,mybatis 使用 foreach 解析
3.1 传入多个id的
1 package com.mybatis.entity; 2 3 import java.util.List; 4 5 /** 6 * 7 * @ClassName: UserQueryVo 8 * @Description: TODO(包装类型) 9 * @author warcaft 10 * 11 */ 12 public class UserQueryVo { 13 14 public List<Integer> ids; 15 16 public List<Integer> getIds() { 17 return ids; 18 } 19 20 public void setIds(List<Integer> ids) { 21 this.ids = ids; 22 } 23 }
3.2 mapper.xml :实现两条不同sql示例
1 <!-- 实现下边的sql拼接 2 select * from t_user where id=1 OR id=2 OR id=3 3 --> 4 <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo" 5 resultType="com.mybatis.entity.User"> 6 select * from t_user 7 <where> 8 <if test="ids!=null"> 9 <!-- 使用foreach遍历ids 10 collection:指定输入对象的集合属性 11 item:每个遍历生成对象中 12 open:开始遍历时拼接的串 13 close:技术遍历时拼接的串 14 separator:遍历的两个对象中需要拼接的串 15 --> 16 <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or"> 17 id=#{user_id} 18 </foreach> 19 </if> 20 </where> 21 </select>
1 <!-- 实现下边的sql拼接 2 select * from t_user whereid in(1,2,3) 3 --> 4 5 <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo" 6 resultType="com.mybatis.entity.User"> 7 select * from t_user 8 <where> 9 <if test="ids!=null"> 10 <!-- 11 使用foreach遍历ids 12 collection:指定输入对象的集合属性 13 item:每个遍历生成对象中 14 open:开始遍历时拼接的串 15 close:技术遍历时拼接的串 16 separator:遍历的两个对象中需要拼接的串 17 --> 18 <!-- 实现“ select * from t_user where id in(1,2,3)”拼接 --> 19 <foreach collection="ids" item="user_id" open="AND id in (" close=")" separator=","> 20 id=#{user_id} 21 </foreach> 22 </if> 23 </where> 24 </select>
3.3 UserMapper.java 示例
1 public interface UserMapper { 2 //ids查询用户数据 3 public List<User> findUserByIds(UserQueryVo userQueryVo); 4 }
3.4 Junit 测试代码示例
1 @Test 2 public void findUserByIdsTest() { 3 SqlSession sqlSession = sqlSessionFactory.openSession(); 4 // 创建Usermapper对象,mybatis自动生成mapper代理对象 5 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 6 //创造查询条件 7 UserQueryVo userQueryVo = new UserQueryVo(); 8 //传入多个id 9 List<Integer> ids=new ArrayList<Integer>(); 10 ids.add(1); 11 ids.add(2); 12 ids.add(3); 13 //将ids通过userQueryVo传入statement中 14 userQueryVo.setIds(ids); 15 //调用userMapper的代码 16 List<UserCustom> userList= mapper.findUserList(userQueryVo); 17 System.out.println(userList); 18 sqlSession.close(); 19 }
最后:这两篇随笔参考和引用了传智播客的资料和代码,尤其是(二),写的时候比较匆忙。写这两篇仅仅是为了便于自己以后查阅而已。