总结一下在mybatis中使用的操作数据库方式: 具体实现可参考我的博客:https://blog.csdn.net/yuli_nine/article/details/79842643
步骤:
1、创建一个接口,接口中编写增删改查的方法 2、创建一个映射xxxMapper.xml文件,主要在<mapper>标签中填写namespace="包名.接口" 接口方法名等于id的名称 接口方法的参数类型与xml文件中parameterType匹配 接口方法的返回值与xml文件中resultType匹配 3.在mybatis配置文件中 增加映射<mapper resource="mapper/xxxMapper.xml" /> 4.使用mybatis的自己api解析xml文件 InputStream inputStream = Resources.getResourceAsStream("配置文件路径"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 构建出SqlSessionFactory,用于生产SqlSession 5.使用sqlsession来做增删改查 接口类型 jdk动态代理对象=sqlSession.getMapper(接口类型.class); 返回类型 返回对象数据=jdk动态代理对象.目标方法(); 6.调用session.commit()提交事务 7.调用session.close()关闭会话
<resultMap> 解决数据库的列名字与实体类中变量出现不同名,会出现不匹配的错误。 <!-- type指向实体类,如果在配置文件中增加了typeAliases标签可以在type中填写实体别名 id="resultMap别名做别名调用" --> <!-- property="实体类属性" column="数据库列" --> <resultMap type="User" id="user_map"> <!-- 主键 --> <id property="id" column="id"/> <!-- 非主键 --> <result property="name" column="username"/> </resultMap>
动态sql语句(主要负责拼装sql语句): include标签: 在数据库的使用中,查询的时候时候不要使用*号, *是表示所有,对效率都有非常大的影响,所以使用<include>标签 <include refid="select_user"> id, username, userpassword, address </include>
if标签: <!-- if标签是条件判断成立才会连接sql条件 --> <select id="findAllUsers_if" resultMap="user_map" parameterType="User"> <include refid="select_user"></include> where address='北京' <if test="name != null"> and username =#{name} </if> </select>
choose和when标签: choose标签按顺序判断其内部when(相当于if)标签中的test条件出否成立,如果有一个成立,则 choose 结束。 当 choose 中所有 when 的条件都不满则时,则执行 otherwise(相当于else) 中的sql <select id="findAllUsers_choose" resultMap="user_map" parameterType="java.util.Map"> <include refid="select_user"></include> where address='北京' and username =#{uname} <choose> <when test="uname !=null"> </when> <otherwise> and userpassword like '%%' </otherwise> </choose> </select>
Mybatis中#和$的区别? 1.#相当于对数据加上双引号,$相当于对直接显示数据 2.#对数据加上了双引号,如:order by #user_id解析成sql时值为order by "id" $将传入的数据直接显示生成在sql中。如:order by $user_id解析成的sql为order by id。 3.#方式能够很大程度防止sql注入。$方式无法防止sql注入。 4.$方式一般用于传入数据库对象,例如传入表名. 5.一般能用#的就别用$
where标签: where标签if的条件第一个不成立,第二成立 and address=#{uaddress}。 如果mybatis检测到where之后的判断不成立则去除and关键字,如果if条件都不成立 where关键会去掉 。 <select id="findAllUsers_where" resultMap="user_map" parameterType="java.util.Map"> <include refid="select_user"></include> <where> <if test="uname !=null"> username=#{uname} </if> <if test="uaddress !=null"> and address=#{uaddress} </if> </where> </select>
set标签: 第一个if条件成立,第二条件不成立,会自动去掉后面的逗号。 如果两个条件都不成立,set不会出现,但是会报异常,sql语法异常;至少有一个条件要成立。 <update id="updateUser_set" parameterType="java.util.Map"> update t_user <set> <if test="uname!=null">username=#{uname},</if> <if test="upwd!=null">userpassword=#{upwd}</if> </set> where id=#{uid} </update>
trim标签: 用trim 替换每个条件判断标签如set,prefix="SET" 前缀为set。 suffixOverrides="," 后缀覆盖,第一个if成立, 第二 if不成立会去掉后面的逗号 至少有一个if要成立,否者会语法异常。
后缀覆盖: <select id="findAllUsers_trim1" resultMap="user_map" parameterType="java.util.Map"> <include refid="select_user"></include> <trim prefix="WHERE" prefixOverrides="AND|OR"> <if test="uname !=null">username=#{uname} </if> <if test="uaddress !=null">and address=#{uaddress}</if> </trim> </select>
前缀覆盖(前缀是去掉前面and): <select id="findAllUsers_trim1" resultMap="user_map" parameterType="java.util.Map"> <include refid="select_user"></include> <trim prefix="WHERE" prefixOverrides="AND|OR"> <if test="uname !=null">username=#{uname}</if> <if test="uaddress !=null">and address=#{uaddress}</if> </trim> </select>
只用两种情况:一对一关联,一对多关联
一对一关联 association
<resultMap type="User" id="userMap"> <id property="id" column="uid"/> <result property="name" column="username"/> <result property="password" column="userpassword"/> <result property="address" column="address"/> <association property="group" javaType="Group"> <id property="id" column="gid"/> <result property="name" column="groupname"/> <result property="loc" column="grouploc"/> </association> </resultMap> <select id="findUserById_association" parameterType="java.lang.Integer" resultMap="userMap"> select u.id uid,u.username,u.userpassword,u.address,g.id gid,g.groupname,g.grouploc from (select * from t_user where id=#{id})u left join t_group g on u.group_id=g.id </select>
一对多关联 collection
<resultMap type="User" id="userMap"> <id property="id" column="uid"/> <result property="name" column="username"/> <result property="password" column="userpassword"/> <result property="address" column="address"/> </resultMap> <resultMap type="Group" id="groupMap"> <id property="id" column="gid"/> <result property="name" column="groupname"/> <result property="loc" column="grouploc"/> <collection property="users" ofType="User" javaType="java.util.List" resultMap="tempUserMap"> </collection> </resultMap> <select id="findUserById_association" parameterType="java.lang.Integer" resultMap="userMap"> select u.id uid,u.username,u.userpassword,u.address,g.id gid,g.groupname,g.grouploc from (select * from t_user where id=#{id})u left join t_group g on u.group_id=g.id </select>
1.一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session flush或close之后,改Session中的所有Cache就讲清空。 2.二级缓存:二级缓存与一级缓存机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper,并且可自定义存储源,如Ehcache.作用域为namespace是指对改namespace对应的配置文件中所有的select操作结果都缓存,这样不同线程之间就可以共用二级缓存。在mapper配置文件中使用<cache>标签启动二级缓存。 3.对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespace)的进行C/U/D操作后,默认该作用域下所有select中的缓存将被clear。