1 mybatis的配置详解 (主配置文件 mybatis-config.xml )
properties: 用于配置属性信息
settings : 用于配置mybatis 的运行时方式
typesAliases : 用于配置类别名
typeHandlers : 用于配置类型处理器
plugins : 用于配置拦截器,拦截sql语句的执行
environments : 用于配置数据源信息,连接池,事务等属性
mappers : 配置映射文件
1) properties: 用于配置属性信息
这些属性信息,可以配置在典型的属性文件中,也可以写在 properties 标签对中
mybatis-config.xml:
<properties resource="mydbconfig.properties" >
<property name="db.password" value="root" />
</properties>
//外部配置:(以外部配置优先)
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
2) settings 用于配置mybatis 的运行时方式
<settings>
<setting name="cacheEnabled" value="true" /> //是不是开启缓存
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="false" />
<setting name="autoMappingBehavior" value="PARTIAL" />
<setting name="defaultExecutorType" value="SIMPLE" />
<setting name="defaultStatementTimeout" value="25" />
<setting name="safeRowBoundsEnabled" value="false" />
<setting name="mapUnderscoreToCamelCase" value="false" />
<setting name="localCacheScope" value="SESSION" />
<setting name="jdbcTypeForNull" value="OTHER" />
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
</settings>
3) typesAliases 用于配置类别名
<typeAliases>
// 单个别名
<typeAlias type="com.UserInfo" alias="userInfo"/>
// 批量别名
<package name="com.beans" />
</typeAliases>
测试:
1 单个别名:
UserInfoMapper.xml:
<insert id="add_user" parameterType="UserInfo" >
运行 Test。 正常没问题。
若是 alias="XXX" 在运行就会出错了
2 批量别名
把实体类放到 com.beans包下
<package name="com.beans" />
UserInfoMapper.xml:
<insert id="add_user" parameterType="UserInfo" >
4) plugins : 用于配置拦截器,拦截sql语句的执行 略
5) environments : 用于配置数据源信息,连接池,事务等属性
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
6) mappers 用于引入配置文件
<mappers>
<mapper resource="mapping/UserInfoMapper.xml" />
</mappers>
配置文件的引入,有几种方式
1、基于类路径的方式
<mappers>
<mapper resource="mapping/UserInfoMapper.xml" />
...
</mappers>
2、可以用全路径引入
<mappers>
<mapper resource="c:/config/mapping/UserInfoMapper.xml" />
<mapper resource="file:///config/mapping/UserInfoMapper.xml" /> <!-- 三个/ 代表客户机的config目录 -->
...
</mappers>
3、可以使用类名,包名的形式 //映射文件和类名相同,而且要放在同一个包下
<mappers>
<mapper class= "com.mapper.UserInfoMapper" />
...
</mappers>
4、使用mappr的方式批量加载
<mappers>
<package name="com.mapper"/> 批量加载 com.mapper 下的所有映射文件
</mappers>
2 输入输出映射对应的类型 ( parameterType 和 resultType )
例子:
select * from userinfo where id=#{id}
1) parameterType 输入参数类型
主要有以下几种:
简单类型 ,比如上面的int
pojo 比如 parameterType="UserInfo" >
包装类型的pojo
Map
例子:登录 使用pojo的方式传参
UserInfoMapper:
UserInfo getLoginUser(UserInfo user);
UserInfoMapper.xml:
<select id="getLoginUser" parameterType="userInfo" resultType="userInfo" >
select * from userInfo where userName=#{userName} and password=#{password}
</select>
Test:
InputStream in=Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
SqlSession session=factory.openSession();
UserInfoMapper mapper=session.getMapper(UserInfoMapper.class);
UserInfo u=new UserInfo();
u.setUserName("hehe");
u.setPassword("hehe");
UserInfo userResult=mapper.getLoginUser(u); //用pojo的方式传入参数
System.out.println(userResult);
session.close()
例子:登录 使用map方式传参
UserInfoMapper:
UserInfo getLoginUser(Map<Object,Object> map);
UserInfoMapper.xml:(Map -> HashMap)
<select id="getLoginUser" parameterType="map" resultType="userInfo" >
select * from userInfo where userName=#{userName} and password=#{password}
</select>
Test:
InputStream in=Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
SqlSession session=factory.openSession();
UserInfoMapper mapper=session.getMapper(UserInfoMapper.class);
Map<Object,Object> map=new HashMap<Object,Object>(); //使用map进行传参
map.put("userName", "hehe");
map.put("password", "hehe");
UserInfo userResult=mapper.getLoginUser(map);
System.out.println(userResult);
session.close();
例子:包装类型的pojo
map.put("userName", new School().getschoolName());
select * from userInfo where userName=#{school.schoolName} and password=#{password}
2) 输出参数 它的类型配置有两个
resultType
resultMap
下面的写法,会出问题,被as后的字段查不出来,结果全是null
UserInfoMapper.xml:
<select id="getLoginUser" parameterType="map" resultType="userInfo" >
select id,userName as uname,password as pwd,school as sc from userInfo where userName=#{userName} and password=#{password}
</select>
处理方式示例:
<select id="getLoginUser" parameterType="map" resultMap="userResultMap"> //声明 resultMap
select id,userName as uname,password as pwd,school as sc from userInfo where userName=#{userName} and password=#{password}
</select>
<resultMap id="userResultMap" type="userInfo" >
<id property="id" column="id" /> //userinfo表中的主键是 id,对应的 列是 id
<result property="userName" column="uname" />
<result property="password" column="pwd" />
<result property="school" column="sc" />
</resultMap>
这个 resultMap可以写在其他的配置文件中,引用的时候要加namespace属性
3 mybatis 动态 sql
if
choose(when otherwrise)
trim
where
set
foreach
1)if
例子 多条件查询(不是模糊查询)
UserInfoMapper.xml:
<select id="get_userlist" resultType="UserInfo" parameterType="map" >
select * from userInfo where 1=1
<if test="userName!=null and userName!='' ">
and userName=#{userName}
</if>
<if test="school!=null and school!='' ">
and school=#{school}
</if>
</select>
Test:
InputStream in=Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
SqlSession session=factory.openSession();
UserInfoMapper mapper=session.getMapper(UserInfoMapper.class);
Map<Object,Object> map=new HashMap<Object,Object>();
map.put("userName","张三");
map.put("school", "");
List<UserInfo> userList= mapper.get_userlist(map);
for (UserInfo userInfo : userList) {
System.out.println(userInfo);
}
2) choose(when otherwrise)
<select id="dynamicChooseTest" parameterType="UserInfo" resultType="UserInfo">
select * from userInfo where 1 = 1
<choose>
<when test="userName != null">
and userName = #{userName}
</when>
<when test="note != null">
and note = #{note}
</when>
<otherwise>
and password = "password"
</otherwise>
</choose>
</select>
3) trim 有点类似于replace效果
prefix:前缀覆盖并增加其内容
suffix:后缀覆盖并增加其内容
prefixOverrides:前缀判断的条件
suffixOverrides:后缀判断的条件
例一:
<select>
select * from user
<trim prefix="WHERE" prefixoverride="AND |OR" >
<if test="name != null and name.length()>0">
AND name=#{name}
</if>
<if test="gender != null and gender.length()>0">
AND gender=#{gender}
</if>
</trim>
</select>
假如说name和gender的值都不为null的话打印的SQL为:
select * from user where ▲ name = 'xx' and gender = 'xx'
在▲的地方是不存在第一个and的,上面两个属性的意思如下:
prefix:前缀
prefixoverride:去掉第一个and或者是or
例二:
<update>
update user
<trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">
<if test="name != null and name.length()>0">
name=#{name} ,
</if>
<if test="gender != null and gender.length()>0">
gender=#{gender} ,
</if>
</trim>
</update>
假如说name和 gender 的值都不为null的话打印的SQL为:
update user set name='xx' , gender='xx' ▲ where id='x'
在 ▲ 的地方不存在逗号,而且自动加了一个set前缀和where后缀,上面三个属性的意义如下,其中prefix意义如上:
suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样)
suffix:后缀
4) foreach
它可以在sql语句中迭代一个集合 它的主要属性有
item : 指的是集合中每个元素进迭代的时候的别名
index : 给一个名字,表示在迭代的过程中,每次迭代到的位置
open : 该语句以什么开始 比如 "("
close : 该语句以什么结束 比如 ")"
separator : 迭代的时候,用什么符号做分隔符,比如 ","
collection
-- 如果传入的参数是单参数且是list集合,则 collection属性就是list
-- 如果传入的参数是单参数且是数组,则 collection属性就是array
-- 如果传入的参数是多个的时候,这时要把这些参数拼成一个map,所以这时候collection属性值
就是传入的list 或 array 对象自已封装在map里的key
UserInfoMapper.xml:
<select id="get_userListForEach" resultType="userInfo" parameterType="list">
select * from userInfo where id in
<foreach collection="list" item="userId" open="(" close=")" separator="," >
#{userId}
</foreach>
</select>
Test:
public static void main(String[] args) {
InputStream in=Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
SqlSession session=factory.openSession();
UserInfoMapper mapper=session.getMapper(UserInfoMapper.class);
List<Integer> idList=new ArrayList<Integer>();
idList.add(9);
idList.add(10);
idList.add(13);
idList.add(199995);
List<UserInfo> userList=mapper.get_userListForEach(idList);
for (UserInfo u : userList) {
System.out.println(u);
}
session.close();
}
5) where
<select id="get_userlist" resultType="UserInfo" parameterType="map" >
select * from userInfo
<where>
<if test="userName!=null and userName!='' ">
and userName=#{userName}
</if>
<if test="school!=null and school!='' ">
and school=#{school}
</if>
</where>
</select>
附 sql片段
<sql id="sql1"> //声明一个sql片段
<if test="userName!=null and userName!='' ">
and userName=#{userName}
</if>
<if test="school!=null and school!='' ">
and school=#{school}
</if>
</sql>
<select id="get_userlist" resultType="UserInfo" parameterType="map" >
select * from userInfo
<where>
<include refid="sql1" /> // 引用了sql片段
</where>
//and ...(也是可以的)
</select>
<select id="getUserCount" resultType="int" parameterType="map">
select count(*) from userInfo
<where>
<include refid="sql1" />
</where>
</select>
注意: sql片段 尽量不要带上 <where> , 尽量在单表上操作
Test:
public static void main(String[] args) {
InputStream in=Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
SqlSession session=factory.openSession();
UserInfoMapper mapper=session.getMapper(UserInfoMapper.class);
Map<Object,Object> map=new HashMap<Object,Object>();
map.put("userName", "admininstrator");
map.put("school", "农大");
List<UserInfo> userList=mapper.get_userlist(map);
for (UserInfo u : userList) {
System.out.println(u);
}
int count=mapper.getUserCount(map);
System.out.println("数据总数:"+count);
session.close();
}
6) set
set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的主要是在包含的语句前输出一个set,
然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。
有了set元素我们就可以动态的更新那些修改了的字段
<update id="dynamicSetTest" parameterType="UserInfo">
update t_user
<set>
<if test="title != null">
title = #{title},
</if>
<if test="content != null">
content = #{content},
</if>
<if test="owner != null">
owner = #{owner}
</if>
</set>
where id = #{id}
</update>