一次只修改一条语句 成功返回 1
一次修改两条及以上语句 成功返回 -1
1、新增用户id的返回值
<insert id="save" parameterType="User">
<selectKey KeyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id();
selectKey >
insert into User(xxx,xxx,xxx)values(#{xxx},#{xxx},#{xxx});
insert>
2、参数 parameterType(输入类型)
3、返回 resultType(返回类型)
为了对应数据库字段和实体类对象的属性名匹配,有两种做法,一种是直接修改xml中的字段或用别名的方法,推荐第二种,在xml前面定义好resultMap,方便开发效率。
<resultMap id="userMap" type="User">
<id column="id" property="userId">id>
<result column="username" property="userName" >result>
<result column="sex" property="userSex" >result>
<result column="address" property="userAddress" >result>
resultMap>
这样在下面的各类操作中,就可以方便使用。类似加入 ----> resultMap=“userMap”
4、properties标签,URL,URI
可以在标签内部配置连接数据库的信息。也可以通过属性引用外部配置文件信息。
resource属性:
用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下。但是注意配置的value保持一致。
url属性:
URL:Uniform Resource Locator 统一资源定位符。它是可以唯一标志一个资源的位置。
写法:
http://localhost:8080/mybatis/demo1Servlet
协议 主机 端口 URI
URI:Uniform Resource Identifier 统一资源标识符。它是在应用中可以唯一定位一个资源的。
5、typeAliases和package标签
typeAliases:
使用typeAliases配置别名,它只能配置domain中类的别名。
其中 type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就不再区分大小写。
<typeAliases>
<typeAlias type="实体类全限定类名" alias="别名">typeAliases>
typeAliases>
package:
用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写。
<package name="包名">package>
1、if标签
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
select * from user where 1 = 1
<if test="userName != null">
and username = #{userName}
if>
select>
2、where标签
其实就是将上面if标签的 where 1 = 1换成 where标签
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
select * from user
<where>
<if test="userName != null">
and username = #{userName}
if>
where>
select>
3、trim标签
trim标签属性:
prefix:
给sql语句拼接的前缀
suffix:
给sql语句拼接的后缀
prefixOverrides:
去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
suffixOverrides:
除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
详情见trim标签详解
4、foreach标签
select * from user where id in(xx,yy,zz);
foreach标签属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表语句的结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
注意:一般开发中,使用item和sperator即可。不建议使用open和close。
<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
select * from user
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="id" sperator=",">
#{id}
foreach>
if>
where>
select>
5、include标签
使用mybatis 的include标签达到SQL片段达到代码复用的目的
<sql id="UserSQL">
SELECT * FROM t_user
sql>
<select id="findAll" resultType="User">
<include refid="UserSQL">include>
select>
示例:
用户和账户——一个用户有多个账户,一个账户只能属于一个用户(多个用户也可以属于同一个用户)
1、一对一:一个账户只能属于一个用户
//通过外键查询两个表的信息
select * from account a,user u
where a.id = u.uid;
方法一(不推荐):定义一个AccountUser类,让其继承Account,然后将User中需要的字段添加到新生成的类中。
方法二:利用Mybatis的关联,association标签
将非主表添加到主表的类中(示例:将User对象添加到Account对象中去,生成get和set方法),之后在主表的Dao层中编写resultMap去实现一对一关系。
<resultMap id="accountUserMap" type="account">
<id column="aid" property="id">id>
<result column="uid" property="uid">result>
<result column="money" property="money">result>
<association column="uid" property="User">
<id column="id" property="id">id>
<result column="username" property="usename">result>
<result column="address" property="address">result>
<result column="sex" property="sex">result>
<result column="birthday" property="birthday">result>
association>
resultMap >
2、一对多:一个用户有多个账户
select * from user u left join account a on u.id = a.uid
方法与一对一类似,这里将User做为主对象,将account对象放入User中,生成对应的get和set
然后在主表的Dao中编写resultMap实现一对多,之后使用
<resultMap id="userAccountMap" type="user">
<id column="id" property="id">id>
<result column="username" property="usename">result>
<result column="address" property="address">result>
<result column="sex" property="sex">result>
<result column="birthday" property="birthday">result>
<association property="account" ofType="account">
<id column="aid" property="aid">id>
<result column="uid" property="uid">result>
<result column="money" property="money">result>
association>
resultMap >
3、多对多:角色赋予多个用户,用户可以有多个角色
//查询所有角色,同时获取角色的所赋予的用户,即user中只有id为41和45的数据
select u.*,r.* from role r
left join user_role ur on r.id = ur.id
left join user u on u.id = ur.uid;
数据库实现多对多,需要使用中间表,中间表中包含各自的主键,在中间表中是外键。
方法就是在两个实体类中,类似一对多的形式,包含对方的一个集合。
注意:collection和association区别
<resultMap id="roleMap" type="role">
<id column="id" property="roleId">id>
<result column="role_name" property="roleName">result>
<result column="role_desc" property="roleDesc">result>
<collection property="users" ofType="user">
<id column="id" property="id">id>
<result column="username" property="usename">result>
<result column="address" property="address">result>
<result column="sex" property="sex">result>
<result column="birthday" property="birthday">result>
collection>
resultMap >
用户可以有多个角色同理,修改相关sql和resultMap即可。
一、Mybatis环境搭建
mybatis部分实现:
需求 使用Mybatis查询所有用户,封装到List集合
0.创建数据库和数据表
CREATE DATABASE mybatis;
USE mybatis;
CREATE TABLE t_user(
uid int PRIMARY KEY auto_increment,
username varchar(40),
sex varchar(10),
birtday date,
address varchar(40)
);
INSERT INTO 't_user' VALUES (null,'zs','男','2000-08-01','北京');
INSERT INTO 't_user' VALUES (null,'ls','女','2000-08-01','上海');
INSERT INTO 't_user' VALUES (null,'ww','男','2000-08-01','深圳');
1.创建Maven工程,导入坐标(jar包)
2.创建User
3.创建UserDao接口
4.创建UserDao映射文件
<mapper namespace="com.study.dao.UserDao">
<select id="findAll" resultType="com.study.bean.User" >
select * from t_user
select>
mapper>
5.创建核心配置文件SqlMapConfig.xml
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/study/dao/Userdao.xml"/>
mappers>
configuration>
出现问题:
//异常
java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more than one time
解决:在数据库驱动的url后加上serverTimezone=UTC参数
jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=UTC
其中&serverTimezone=UTC
二、mapper代码规范
a.Mapper.xml文件中的namespace必须和mapper(Dao)接口的全限定名相同。
b.Mapper.xml文件中的select,update等的标签id的值必须和mapper(Dao)接口的方法名相同。
c.Mapper.xml文件中的select,update等的标签的parameterType必须和mapper(Dao)接口的方法的形参类型对应
d.Mapper.xml文件中的select,update等的标签的resultType必须和mapper(Dao)接口的方法的返回值对应
e.Mapper.xml文件的文件名尽量和mapper(Dao)接口的名字一样
f.Mapper.xml文件的路径尽量和mapper(Dao)接口的路径在同一层目录。
三、核心配置文件
1、配置文件顺序(按照规则)
2、properties(引入外部properties文件)
settings(全局配置参数)
3、typeAliases(类型别名)
4、mapper(映射器)
2)properties步骤:
1.抽取四个基本项到jdbc.properties
2.在SqlMapConfig.xml使用properties标签引入jdbc.properties
使用${xxx}使用
3.动态获得赋值
3)typeAliases使用
<typeAliases>
<typeAlias type="com.study.dao.UserDao" alias="User" />
typeAliases>
<package name="com.study.bean"/>
4)Mapper使用(注意前面提到映射文件和接口文件的对应关系)
<mapper resource="com/study/dao/Userdao.xml"/>
<package name="com.study.dao"/>
四、Mybatis案例 ----CURD
1.增加insert
<insert id="saveUser" parameterType="User">
INSERT INTO t_user(username,sex,birthday,address)
VALUES (#{username},#{sex},#{birthday},#{address})
insert>
如何获取自增值
方式一:Mysql内置的函数
<insert id="add" parameterType="User" >
<selectKey keyProperty="uid" keyColumn="uid" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
selectKey>
INSERT INTO t_user(username,sex,birthday,address)
VALUE (#{username},#{sex},#{birthday},#{address})
insert>
方式二:
<insert id="add" parameterType="User" keyProperty="uid" useGeneratedKeys="true">
INSERT INTO t_user(username,sex,birthday,address)
VALUE (#{username},#{sex},#{birthday},#{address})
insert>
2.删除delect
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM t_user WHERE uid = #{uid}
delete>
3.更新update
4查询select
模糊查询
#{}与${}的区别
1.#{}表示一个占位符号
2.${}表示拼接sql串
注意:${}适用于简单参数
五、parameterType深入
1、传简单类型
直接使用#{}或者KaTeX parse error: Expected 'EOF', got '#' at position 46: …gnl表达式解析对象字段的值,#̲{}或者{}括号中的值为pojo属性名称
3、传封装的JavaBean
通过.调用 例如 Vo对象中存在User对象 ,在输入参数时使用Vo,调用#{User.Uid},即属性名对应的对象的属性名。
六、resultType深入
1、输出简单类型
2、输出pojo对象
3、输出pojo列表
4、resultMap输出类型
主要处理数据库字段名和项目实体类中的字段名无法对应的时候使用。可参考前面的笔记。
七、复杂查询
1.if判断(之前也有)
<select id="findByQueryVo" resultType="User" parameterType="QueryVo">
SELECT * FROM t_user
<where>
<if test="user != null and user.uid != null">
AND uid > #{user.uid}
if>
<if test="user != null and user.username !='' and user.username != null">
AND username LIKE #{user.username}
if>
where>
select>
2.if结合foreach
<select id="findByForeach01" parameterType="QueryVo" resultType="User">
<include refid="UserSQL">include>
<where>
<if test="ids != null">
<foreach collection="ids" open="uid IN(" close=")" item="uid" separator=",">
#{uid}
foreach>
if>
where>
select>
3.一对多关系
<resultMap id="User02ResultMap" type="User02">
<id property="uid" column="uid">id>
<result property="username" column="username">result>
<result property="sex" column="sex">result>
<result property="birthday" column="birthday">result>
<result property="address" column="address">result>
<collection property="accounts" ofType="Account" >
<id column="aid" property="aid"/>
<result column="money" property="money"/>
collection>
resultMap>
SQL语句在加强 join limit 等