Mybatis学习+简单ssm案例实现mybatis

Mybatis的使用(输入和返回)

一次只修改一条语句 成功返回 1
一次修改两条及以上语句 成功返回 -1

1、新增用户id的返回值

<insert id="save" parameterType="User">
	<!-- KeyProperty代表要返回的值的名称, order:取值为AFTER代表插入后的行为 ,resultType代表返回的类型 -->
	<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(输入类型)

  • 传递简单类型,java.lang.Integer , INT…
  • 传递pojo对象
    Mybatis使用ognl表达式解析对象字段的值,#{}中的值为pojo属性名称
  • 传递pojo包装对象(一般为项目的VO包
    开发中通过pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其他查询条件,这时可以使用包装对象传递输入参数。
    使用方法:parameterType=“定义的vo对象”,通过get方法调用相关属性。

3、返回 resultType(返回类型)
为了对应数据库字段和实体类对象的属性名匹配,有两种做法,一种是直接修改xml中的字段或用别名的方法,推荐第二种,在xml前面定义好resultMap,方便开发效率。

<!--配置 查询结果的列名(column ->数据库字段名)和实体类的属性名(property ->对象定义的名)的对应关系 -->
<!--注意 type属性:正常应该写全限定类名,此处因项目引入起别名方法。 -->
<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>
    

Mybatis中动态sql语句(针对查询)

1、if标签

	<!--注意:1、 if中的并且只能使用 and 而不可以使用 && -->
	<!--注意:2、 parameterType为传入的参数,主要将#{userName}中的userName与user封装的对象中确保一致(包括大小写!!!),当然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。

	<!--queryvo:方便传入参数封装,下面的ids就是在vo中定义的一个List集合-->
	<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:该sql片段在当前namespace下唯一标识符
    -->
	<sql id="UserSQL">
	     SELECT * FROM t_user
	</sql>
	<!--select标签: 查询
        id属性: 方法名
        resultType属性: 写方法返回值类型(如果是list,直接写实体类的全限定名)
        标签体: sql语句
        SELECT * FROM t_user_copy1
    -->
    <select id="findAll" resultType="User">
        <include refid="UserSQL"></include>
    </select>

Mybatis中的多表查询

示例:
用户和账户——一个用户有多个账户,一个账户只能属于一个用户(多个用户也可以属于同一个用户)
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">
<!-- 定义封装account和user的resultMap-->
<!-- 先定义主表信息 column ->数据库字段名,property ->对象定义的名-->
	<id column="aid" property="id"></id>
	<result column="uid" property="uid"></result>
	<result column="money" property="money"></result>
	<!-- 一对一的关系映射:配置封装User的内容 使用association:column->外键,property->关联的表对象-->
	<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">
<!-- 定义封装account和user的resultMap-->
<!-- 先定义主表信息 column ->数据库字段名,property ->对象定义的名-->
		<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>
		<!-- 一对多的关系映射:配置封装User的account集合 
		association:property->关联的表对象,
		ofType(尽量使用全限定类名com.xx.account,此处简写是因为引入别名)-->
		<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">
<!-- 先定义主表信息 column ->数据库字段名,property ->对象定义的名-->
		<id column="id" property="roleId"></id>
		<result column="role_name" property="roleName"></result>
		<result column="role_desc" property="roleDesc"></result>
		<!-- 多对多的关系映射:配置封装role的user集合 
		collection:property->关联的表对象,
		ofType(尽量使用全限定类名com.xx.account,此处简写是因为引入别名)-->
		<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即可。


SSM框架(黑马的 b站收藏)

一、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映射文件

<?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">
<!--namespace属性: 接口类的全限定名-->
<mapper namespace="com.study.dao.UserDao">
    <select id="findAll" resultType="com.study.bean.User" >
        select * from t_user
    </select>
    
</mapper>

5.创建核心配置文件SqlMapConfig.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>
    <!--配置连接数据库的环境 default:指定使用哪一个环境-->
    <environments default="development">
        <environment id="development">
            <!--配置事务,MyBatis事务用的是jdbc-->
            <transactionManager type="JDBC"/>
            <!--配置连接池, POOLED:使用连接池(mybatis内置的); UNPOOLED:不使用连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!--引入单个映射文件; resource属性: 映射文件的路径-->
         <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使用

	<!--	单个类
            type:要起别名的JavaBean的全限定名
            alias:别名
        -->
	<typeAliases>
        <typeAlias type="com.study.dao.UserDao" alias="User" />
    </typeAliases>
    <!-- 方法二:直接对包进行扫描批量起别名,别名为JavaBean的名称,忽略大小写-->
	<package name="com.study.bean"/>

4)Mapper使用(注意前面提到映射文件和接口文件的对应关系)

<!--引入单个映射文件; resource属性: 映射文件的路径-->
<mapper resource="com/study/dao/Userdao.xml"/>
<!--<mapper class="com.study.dao.Userdao"/>-->
<!--包扫描批量引入映射文件-->
<package name="com.study.dao"/>


四、Mybatis案例 ----CURD
1.增加insert

		<!--
        新增用户
        #{} <===> ? 占位符
        #{xxx}:xxx 为对应JavaBean的属性名
        -->
        <insert id="saveUser" parameterType="User">
        INSERT INTO t_user(username,sex,birthday,address)
        VALUES (#{username},#{sex},#{birthday},#{address})
   		</insert>

如何获取自增值
方式一:Mysql内置的函数

<!--  
		keyProperty:对应JavaBean中主键的属性名
        useGeneratedKeys:是否自动生成主键
        keyColumn:主键的列名,一般情况下不写
        ORDER:顺序
            BEFORE:表示selectKey中的SQL语句在INSERT SQL语句之前执行
            AFTER:表示selectKey中的SQL语句在INSERT SQL语句之后执行
            resultType:对应JavaBean中主键的属性名对应的类型
    -->
    <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.#{}表示一个占位符号

  • 通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和数据库类型转换
  • #{}可以有效防止sql注入
  • #{}可以接受简单类型值(基本类型,String)或pojo属性值
  • 如果parameterType传输单个简单类型值(String,基本类型),#{}括号中可以是value或任意其他名称

2.${}表示拼接sql串

  • 通过${}可以将parameterType传入的内容拼接sql中且不进行jdbc类型转换。
  • ${}不能防止sql注入
  • ${}可以接受简单类型值或pojo属性值
  • 如果parameterType传输单个类型值。${}括号中只能是value。

注意:${}适用于简单参数


五、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判断(之前也有)

	<!--复杂参数查询
	    if.test:要判断的内容
	    在 uid 如果不为空时可以根据 uid查询(查询出uid大于所输入值)
	    如果 username 不同空时根据username进行模糊查询
	
	    -->
    <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

	<!--findByForeach01
	    SELECT * FROM t_user WHERE uid IN(1,2,3)
	    -->
    <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 等


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值