mybatis从头学到jio(一)
@Select("select * from Student where SID=#{sid}")
public Student getStudentBySID(int sid);
Preparing: select * from Student where SID=?
Parameters: 2(Integer)
#{}处理方式类似于preparedStatement参数的操作将占位符替换为 ?,使用的参数必须提供了getter,将SQL语句和参数值分开传到服务器.
优点:不存在SQL注入的问题
@Select("select * from Student where SID=${SID}")
public Student getStudentBySID(Student student);
Preparing: select * from Student where SID=1
Parameters:
${}类似于jdbc中statement直接将参数拼接到SQL语句之中
缺点:存在SQL注入的问题
Tip:typeAliases在mybatis-config.xml中配置(主配置文件)
<typeAliases>
<typeAlias type="com.tulun.MybatisDemo.Student" alias="student"/>
<package name="com.tulun.pojo"/>
typeAliases>
业务场景:极大的简化了配置文件的编写,当工作量比较大的时候可以配置resultType和parameterType Windows中别名可以不关注大小写。
<select id="selectStudent" resultType="com.bean.student">
select * from student where 1=1
<if test="Sage != 0">
and Sage = #{Sage}
if>
select>
使用log4j.properties可以看见一下结果
假如传两个参数 :select * from Student where 1=1 and Sage = #{Sage} and Ssex = #{Ssex}
假如传一个参数:select * from Student where 1=1 and Sage = #{Sage}
## debug 级别
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd-HH\:mm\:ss,SSS} [%t] [%c] [%p] - %m%n
log4j.logger.com.mybatis=DEBUG /
##输出sql 语句
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
trim标签作用取出SQL中多余And关键字,逗号,使用在where或者set
<select id="updateStudent" resultType="com.conn.student">
update student
<trim prefix="set" suffixOverrides=",">
<if test="Sage != null">
Sage = #{Sage},
if>
<if test="name != null">
Sname = #{name},
if>
trim>
where SID = #{SID}
select>
属性 | 描述 |
---|---|
prefix | 给SQL拼接前缀 |
suffix | 给SQL拼接后缀 |
prefixOverrids | 剔除SQL语句前缀字符 |
suffixOverrids | 剔除SQL语句后缀字符 |
<select id="findStudent1" resultType="com.bean.student">
select * from student
<where>
Sname = #{name}
where>
select>
省去了多余的1 = 1的条件
<select id="findStudent1" resultType="com.bean.student">
select * from student
<where>
<if test="list != null">
<foreach collection="list" separator="," close=")" open="and SID in(" item="id">
#{id}
foreach>
if>
where>
select>
属性 | 描述 |
---|---|
collection | 所要遍历集合的名称 |
separator | 集合之中分割符 |
close | 结束的字符 |
open | 开始的字符 |
item | 集合之中的单个字符名称 |
collection可以使用与List、Map、数组等等
模糊匹配一共有三种方式
<select id="studentByName" resultType="com.conn.student">
select *from student where Sname like #{name}
select>
<select id="studentByName" parameterType="java.lang.String" resultType="com.conn.student">
select *from student where Sname like concat('%',concat(#{name},'%'))
select>
<select id="studentByName" resultType="com.conn.student">
<bind name="s" value="'%'+name+'%'"/>
select *from student where Sname like #{s}
select>
mybatis中一级缓存是不需要任何的配置,是sqlsession级别的查询
执行同一个SQL语句第一次查询对应的信息,当第二次查询的时候优先去缓存区查询对应的结果
这个图片可以看到第一次进行了SQL查询,第二次直接在缓存区查询
二级缓存是mapper级别的,默认的是关闭的需要手动的开启
主配置文件配置
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
映射文件配置
<cache>cache>
association:用于映射关联查询单个对象的信息
<mapper namespace="com.dao.ordersDao">
<resultMap id="OrderUserResultMap" type="com.bean.orders" >
<id column="id" property="id"/>
<result column="user_id" property="user_id"/>
<result column="number" property="number"/>
<result column="date" property="date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
<result column="note" property="note"/>
<association property="user" columnPrefix="u_" javaType="com.bean.user">
<result column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
association>
resultMap>
<select id="findAll" resultMap="OrderUserResultMap">
select o.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.user_id = u.id
select>
mapper>
这里需要注意当SQL语句太长换行的时候在前一段末尾或下一段前面加一个空格因为在拼接字符串的时候会将两个关键词拼接在一起
使用extends关键词简化xml配置的编写
<resultMap id="orderResultMap" type="com.bean.orders">
<id column="id" property="id"/>
<result column="user_id" property="user_id"/>
<result column="number" property="number"/>
<result column="date" property="date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
<result column="note" property="note"/>
resultMap>
<resultMap id="userResultMap" type="com.bean.user">
<result column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
resultMap>
<resultMap id="OrderUserResultMap" type="com.bean.orders" extends="orderResultMap">
<association property="user" columnPrefix="u_" javaType="com.bean.user" resultMap="userResultMap">association>
resultMap>
这里需要注意:当xml配置映射关系比较多的时候使用extends关键词可以极大节省开发时间,也可以是代码变得简洁起来,通俗说哪里需要用到直接可以使用extends关键词使用
使用collection可以将用户一对多订单映射到集合之中
<resultMap id="userMap" type="com.bean.user" extends="userResultMap">
<collection property="orders" columnPrefix="order_" ofType="com.bean.orders" resultMap="orderResultMap">collection>
resultMap>
<sql id="selectId">
u.id,
u.username,
u.sex,
u.address,
o.id order_id,
o.user_id order_user_id,
o.number order_number,
o.createtime order_createtime,
o.note order_note
sql>
<select id="findStudentIds" parameterType="int" resultMap="userMap">
select <include refid="selectId"/>
from user u ,orders o where u.id=o.user_id and u.id=#{uid};
select>
开启延时加载
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
<mapper namespace="com.dao.ordersDao">
<resultMap id="orderWithUserMap" type="com.bean.orders" extends="orderResultMap">
<association property="user" javaType="com.bean.user" column="user_id" select="com.dao.userDao.findStudentIds">association>
resultMap>
<select id="findAll" resultMap="orderWithUserMap">
SELECT * FROM orders
select>
mapper>
这里需要注意select关联查询的已存在的方法的全路径
association中的column是接口的参数
<mapper namespace="com.dao.userDao">
<select id="findStudentIds" parameterType="java.lang.Integer" resultType="com.bean.user">
SELECT * FROM user WHERE id = #{id}
select>
mapper>
<mappers>
<mapper resource="mappers/order.xml">mapper>
<mapper resource="mappers/user.xml">mapper>
mappers>
这里一定需要注意在配置文件之中需要两个映射文件都需要加载并且在同一个mappers标签之下。我在这个错误浪费了好多的时间,还是自己不细心。
图中拿到user_id三天记录两个1一个10分成两次去数据库查找实现了懒加载。
直接装载在方法上面
优点:比较简单
缺点:SQL语句的改变就需要重新编译
注解 作用
>标签 | 作用 |
---|---|
@Intsert | 实现新增 |
@Update | 实现更新 |
@Delete | 实现删除 |
@Select | 实现查询 |
@Results | 实现结果集封装 |
@ResultMap | 实现引用 @Results 定义的封装 |
@One | 实现一对一结果集封装 |
@Many | 实现一对多结果集封装 |
public interface StudentMapper2 {
@Select("select * from Student")
public Student getStudentBySID();
}
@update("update student set Sname=#{name} where SID=#{SID}")
public void updateStudent(@Param("name") String Sname,@Param("SID") int SID)
@Insert("insert into Student(SID,Sname,Sage,Ssex) values(#{SID},#{name},#{Sage},#{Ssex})")
public int insertStudent(Student student);
@Delete("delete form student where SID={SID}")
public void deleteStudent(int SID);
@Results(id = "result",value = {
@Result(column = "SID",property = "SID"),
@Result(column = "Sname",property = "name"),
@Result(column = "Sage",property = "Sage"),
@Result(column = "Ssex",property = "Ssex"),
@Result(column = "score",property = "SID",one = @One(select = "com.dao.studentDao.StudentScore",fetchType = FetchType.EAGER)
})
需要注意的是one表示的是一对一,many表示一对多是使用,fetchtype加载类型,立即加载为EAGER
以上是我对mybatis的学习如果有错误的地方欢迎大佬指正