MyBatis:
是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。使用简单的XML或注解用于配置和原始映射,将接口和java的pojos映射成数据库中的记录。
执行流程:
1、加载配置
2、SQL解析
3、SQL执行
4、结果映射
开发流程:
1、导包
2、建表
3、创建配置
4、新建实体
5、编写映射文件
6、注册映射文件
7、编写测试类
全局配置文件的基本结构(mybatis-config.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- <properties>
<property name="jdbc.driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbc.url" value="jdbc:oracle:thin:@localhost:1521:jredu"/>
<property name="jdbc.username" value="wl"/>
<property name="jdbc.password" value="Jredu12345"/>
</properties> -->
<properties resource="jdbc.properties"/>
<!--
settings包含很多重要的设置项
setting:用来设置每一个设置项
name:设置项名
value:设置项取值
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<!-- 解析类的别名 -->
<!-- <typeAlias alias="U" type="com.jredu.entity.User"/> -->
<!-- 扫描包下的所有类文件,这个包下的所有类都是简写 -->
<!-- 别名默认为类名的小写或大写 -->
<package name="com.jredu.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pwd}" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 找寻对应的xml文件 -->
<!-- <mapper resource="com/jredu/dao/UserDao.xml"/> -->
<!-- 找寻接口文件,自动匹配对应的xml文件 -->
<!-- <mapper class="com.jredu.dao.UserDao"/> -->
<!-- 找寻磁盘目录下的对应xml文件 -->
<!-- <mapper url="file:///D:\workspaces\myeclipse\MyBatis\src\com\jredu\dao\UserDao.xml" /> -->
<!-- 扫描包下的所有xml文件,该包下的所有映射都会匹配 -->
<package name="com.jredu.dao"/>
</mappers>
</configuration>
创建接口:
public interface CommentDao {
Comment selectCommentByID(int Id);
List<Comment> selectCommentByUserID(int userId);
List<Comment> selectAllComment();
int updateComment(Comment comment);
int insertComment(Comment comment);
int deleteComment(int id);
}
创建SQL映射文件:
<?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">
<mapper namespace="com.jredu.dao.CommentDao">
<resultMap type="Comment" id="comment1">
<id property="id" column="id"/>
<result property="content" column="content"/>
<result property="userid" column="user_id"/>
</resultMap>
<!--查询实现 -->
<!--id:对应方法名,resultType:返回结果类型,list<User>也是返回User -->
<select id="selectAllComment" resultType="Comment">
select * from m_Comment
</select>
<select id="selectCommentByID" resultMap="comment1">
select * from m_Comment where id=#{id}
</select>
<select id="selectCommentByUserID" resultType="Comment">
select * from m_Comment where user_id=#{user_id}
</select>
<insert id="insertComment" parameterType="Comment">
insert into m_Comment values(sqe_comment.nextval,#{userid},#{content})
</insert>
<update id="updateComment" parameterType="Comment">
update m_Comment set user_id=#{user_id},content=#{content} where id=#{id}
</update>
<delete id="deleteComment" parameterType="int" >
delete from m_Comment where id=#{id}
</delete>
</mapper>
方法参数个数问题:单个参数:mybatis不会做特殊处理,
#{参数名/任意名}:取出参数值。
多个参数:mybatis会做特殊处理。
多个参数会被封装成 一个map,
key:param1...paramN,或者参数的索引也可以
value:传入的参数值
#{}就是从map中获取指定的key的值;
异常:
org.apache.ibatis.binding.BindingException:
Parameter 'id' not found.
Available parameters are [1, 0, param1, param2]
操作:
方法:public Employee getEmpByIdAndLastName(Integer id,String lastName);
取值:#{id},#{lastName}
【命名参数】:明确指定封装参数时map的key;@Param("id")
多个参数会被封装成 一个map,
key:使用@Param注解指定的值
value:参数值
#{指定的key}取出对应的参数值
POJO:
如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;
#{属性名}:取出传入的pojo的属性值
Map:
如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map
#{key}:取出map中对应的值
TO:
如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO(Transfer Object)数据传输对象
Page{
int index;
int size;
}
========================思考================================
public Employee getEmp(@Param("id")Integer id,String lastName);
取值:id==>#{id/param1} lastName==>#{param2}
public Employee getEmp(Integer id,@Param("e")Employee emp);
取值:id==>#{param1} lastName===>#{param2.lastName/e.lastName}
##特别注意:如果是Collection(List、Set)类型或者是数组,
也会特殊处理。也是把传入的list或者数组封装在map中。
key:Collection(collection),如果是List还可以使用这个key(list)
数组(array)
public Employee getEmpById(List<Integer> ids);
取值:取出第一个id的值: #{list[0]}
public interface UserDao {
/**
* 登陆,包含两个键值对 name,pwd
* @param map
* @return
*/
List<User> selectUser5(Map<String, Object> map);
List<User> selectUser7(Map<String, Object> map);
List<User> selectUser2(int addressId,int num);
List<User> selectUser4(Map<String, Object> map);
List<User> selectUser3(Map<String, Object> map);
List<User> selectUserByCase(String le,int id);
User login(Map<String, String> map);
User login2(@Param("name")String name,@Param("pwd")String pwd);
User selectUserByID(int id);
List<User> selectAllUser();
int updateUser(User user);
int insertUser(User user);
int deleteUser(int id);
int updateUser2(User user);
}
<select id="selectUserByCase" resultMap="user3" >
select * from m_user where (name like '%'||#{0}||'%' )and (id < #{1})
</select>
<select id="selectUser2" resultMap="user2" >
select * from m_user where address_id=#{0} and
(select count(*) from m_comment where
user_id=(select id from m_user where address_id = #{0})
)>#{1}
</select>
<select id="login" parameterType="Map" resultMap="user3">
select * from m_user where name=#{name} and pwd=#{pwd}
</select>
<!-- <select id="login2" resultMap="user3">
select * from m_user where name=#{0} and pwd=#{1}
</select> -->
<!-- <select id="login2" resultMap="user3">
select * from m_user where name=#{param1} and pwd=#{param2}
</select> -->
一对一,一对多的处理方式:
<resultMap type="User" id="user1">
<!--property实体类中的属性 column数据库中的列,可以识别名 -->
<!-- 级联属性:多表查询时将查询列名称与实体类属性绑定 -->
<!--select u.id id,u.name name,u.pwd pwd,u.address_id addressid,a.province province,a.city city,a.area area
from m_user u,m_address a where u.id=#{id} and u.address_id = a.id -->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="pwd" column="pwd"/>
<result property="address.id" column="addressid"/>
<result property="address.province" column="province"/>
<result property="address.city" column="city"/>
<result property="address.area" column="area"/>
</resultMap>
<resultMap type="User" id="user2" >
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="pwd" column="pwd"/>
<!--第一种方式 -->
<!--1对1 关系指定 -->
<!-- <association property="address" javaType="Address">
<id property="id" column="addressid"/>
<result property="province" column="province"/>
<result property="city" column="city"/>
<result property="area" column="area"/>
</association> -->
<!--第二种方式 -->
<association property="address" select="com.jredu.dao.AddressDao.selectAddressByID" column="address_id"></association>
</resultMap>
<resultMap type="User" id="user3" >
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="pwd" column="pwd"/>
<association property="address" select="com.jredu.dao.AddressDao.selectAddressByID" column="address_id"></association>
<collection property="comments" column="id" select="com.jredu.dao.CommentDao.selectCommentByUserID"></collection>
</resultMap>
<select id="selectUserByID" parameterType="int" resultMap="user3">
select * from m_user u where u.id=#{id}
</select>
<!-- <select id="selectUserByID" parameterType="int" resultMap="user2">
select u.id id,u.name name,u.pwd pwd,u.address_id addressid,a.province province,a.city city,a.area area
from m_user u,m_address a where u.id=#{id} and u.address_id = a.id
</select> -->
动态sql查询: <select id="selectUser3" resultMap="user3" >
select * from m_user where 1=1
<if test="id>0">
and id=#{id}
</if>
<if test="name !=null">
and name=#{name}
</if>
<if test="pwd !=null">
and pwd=#{pwd}
</if>
<if test="addressid >0">
and address_id=#{addressid}
</if>
</select>
<select id="selectUser4" resultMap="user3" >
select * from m_user where 1=1
<choose>
<when test ="by=='name'">
and name=#{name}
</when>
<when test ="by=='pwd'">
and pwd=#{pwd}
</when>
<otherwise>
and id=#{id}
</otherwise>
</choose>
</select>
<!--把第一个and去掉变成where -->
<select id="selectUser5" resultMap="user3" >
select * from m_user
<where>
<if test="name!=null">
and name=#{name}
</if>
<if test="pwd!=null">
and pwd=#{pwd}
</if>
</where>
</select>
<update id="updateUser2" parameterType="User">
update m_user
<set>
<if test="name !=null">
name=#{name},
</if>
<if test="pwd !=null">
pwd=#{pwd},
</if>
<if test="address !=null">
address_id=#{address.id}
</if>
</set>
<where>
id=#{id}
</where>
</update>
<select id="selectUser7" resultMap="user3" >
select * from m_user
<where>
id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
缓存机制:
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。
MyBatis系统中默认定义了两级缓存。
一级缓存和二级缓存。
–1、默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。
–2、二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
–3、为了提高扩展性。MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存