mybatis再学习

1、mybatis是一个持久层框架,支持定制化sql,高级映射,避免了所有的jdbc代码和手动设置参数以及获取结果集,mybatis使用xml文件或者注解来配置和映射数据库,将接口和java的POJOs映射成数据库中的记录

2、使用mybatis,只要导入mybatis-3.4.4.jar,如果是连接mysql,再导入mysql-connector-java.jar。

3、mybatis需要有属于自身的配置文件,configuration.xml

<configuration>配置
<environments>环境s
<environment>环境
<dataSource>数据源
<transactionManager>事务管理器
<properties>属性
<setting>设置
<typeAliases>类型别名
<typeHandlers>类型处理器
<plugins>插件
<mappers>映射器
!!在conf.xml文件中,各个标签都需要按照特定的顺序写,不然就会报错
settings>typeAliase>plugins>environments>mappers


(1)environment主要用于配置dataSource,和transactionManager
//类型使用JDBC的事务管理器,如果选择了MANAGED,几乎等于无事务
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
//类型如果使用UNPOOLED,就是不使用连接池的意思
<dataSource type="POOLED">
//数据源的配置选项其实就是连接池的配置
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="poolMaximumActiveConnections " value="最大活动连接数"/>
<property name="poolMaximumIdleConnections " value="最大空闲连接数"/>
</dataSource>

(2)mappers用于声明各个映射器的各项属性
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>相对路径文件名,只有这种方式成功,其余都报错呀,这是为何?
<mapper url="file:///var/mappers/AuthorMapper.xml"/>绝对路径文件名
<mapper class="org.mybatis.builder.AuthorMapper"/>完全限定类名
<package name="org.mybatis.builder"/>声明包
</mappers>

(3)setting调整mybatis的运行时的行为
里面有很多选项,但是每一个需要用到,所以全部保持默认

(4)typeAliases:为类那个长长的完全限定名设置一个简称
在conf.xml设置的别名在mapper文件中都可以使用
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<package name="mapper"/>这个包中javabean,使用首字母小写作为简称,也可以在类前面使用@Alias("简称")自定义
</typeAliases>

4、具体的mapper文件,mapper.xml用于自定义sql语句和结果集对于java类的映射

<mapper>设置该mapper文件所对应的mapper接口所在的路径
<cache>
<cache-ref>
<resultMap>结果集
<sql>sql语句,用于对sql语句的复用
<insert>
<update>
<delete>
<select>

(1)select,对应查询语句
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
id:唯一标识名
parameterType:设置传进来的参数的类型,就等价于pstmt.setInt(1,x);,不设置也可以,因为mybatis可以根据TypeHandler推断出具体传入语句的参数

**parameterType也可以直接传进来一个复杂的对象

resultType:设置结果集映射成哪种类型,可以是任意java对象
resultMap:外部resultMap引用,,与resultType不可同时使用

!!!mybatis3中参数设置不能使用#{id},要使用#{arg0},#{arg1}形式
(2)insert update delete
在添加新行的时候,如果数据库是支持自动添加主键的,可以设置useGeneratedKeys="true"和keyPropertty="id(主键)",就可以实现主键自动添加
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>
**parameterType也可以直接传进来一个复杂的对象
<insert id="insertUser" parameterType="User">
insert into users (id, username, password)
values (#{id}, #{username}, #{password})
</insert>
User会被查找,从中找到相对应的元素,传入预处理语句的参数中

(3)sql:用来定义可重用的sql代码段
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/></include>
from some_table t1
</select>
alias会使用t1代替

(4)ResultMap其实用于解决结果集映射问题
如果一个select语句的resultType设置为一个具体java类,那么mybatis会在幕后自动帮你创建一个ResultMap,帮你基于属性名映射列到javabean的属性上,如果列名,没有精确匹配,那么那些不匹配的字段就不会赋值,可以使用如下方法进行隐式转换:
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
那么后台就会根据你设置的这些别名来匹配java类的属性

你也可以显式的设置ResultMap,只需要声明名字不一样的字段
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
:
<id>标示这个javabean对象的唯一性,不一定是主键,property对应java类中属性,column对用库中的列
<result>就是普通的字段
!!resultMap中,只有那些java类和数据库名字不一样的字段才需要匹配,一样的可以忽略


为什么就算java类中的属性是private的,也可以通过resultMap映射???
<constructor>配置里的元素顺序一定要跟构造函数的参数顺序一样
<resultMap id="1" type="Persons">
<constructor>
<idArg column="列名" javaType="int"/>对应主键id,javaType中的值还是mybatis需要用来辨别的,所以这个应该注意别名对应的实际类型,基础类型的别名都是前面加下划线int类型的别名是_int,Integer的别名才是int
<arg column="列名" javaType="String"/>对应普通参数
</constructor>
</resultMap>

(5)动态sql

* 当city这个属性被传进来才会增加这个city判断,如果if不满足sql查询会失败
select * from Persons where
<if test="city!= null"/>city=s#{city}

*把where也变成一个标签就可以智能添加where子句了,只有当判断条件至少满足一个才会增加where子句
select * from Persons
<where>
<if test="city!= null"/>city=s#{city}
</where>
(set)也可以有类似的操作

*让判断子句也能实现类似java的switch功能,传进哪个值调哪个
select * from persons
<where>
<choose>
<when test="city!=null">city=#{city}</when>
<otherwise>adress='asd'</otherwise>当没有满足项时调用这个
</choose>
</where>

*trim用于格式化set,或者where
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>
perfix就是前缀的意思,prefixoverride是前缀覆盖的意思,去掉第一个AND或者OR

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>
perfix还是前缀,suffix是后缀的意思,suffixoverride是后缀覆盖,去掉最后一个逗号,

*动态运用in子句(in子句用于匹配多个值 select * from person where city in(x1,x2))
select * from person where city in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
如果传进来的是一个数组,index是当前迭代此数,item是本次迭代获取的元素
如果传进来的是键值类型的集合,index就是键,item就是值
collection就是传进来的东西,collection表示如何来得到这个集合,如果传入的直接为一个List,那么collection值就为list,如果直接传入的为一个array不可变数组,那么collection值就为array,如果传入的为一个dto,比如dto里面的array变量名为idLists,那么collection的值就为idLists。
open是前缀,close是后缀,separator是分隔符

posted @ 2017-10-25 17:06  神芝  阅读(133)  评论(0编辑  收藏  举报