首页 > 其他分享 >MyBatis

MyBatis

时间:2023-07-26 20:33:19浏览次数:53  
标签:username xml gender age user MyBatis id

MyBatis

一.简介

1.是什么

MyBatis是一个优秀的基于java的持久层框架,它内部封装了JDBC,使开发者只需要关注SQL语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。

MyBatis通过XML或注解的方式将要执行的各种statement配置起来,并通过JAVA对象和statement中SQL的动态参数进行映射生成最终执行的SQL语句。

最后MyBatis框架执行SQL并将结果映射为Java对象并返回。采用ORM思想解决了实体和数据库映射的问题,对JDBC进行了封装,屏蔽了JDBC API底层访问细节,使我们不用与JDBC API打交道,就可以完成对数据库的持久化操作

简单说就是:有一种叫MyBatis的持久层技术,能够代替JDBC,简化JDBC开发。

2.ORM

对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用“虚拟对象数据库”。

简单的说:就是把数据库表和实体类及实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表。

数据库 实体类
user表 User类
id列 id属性
username列 userName属性
age列 age属性

二.环境及测试

1.建立普通的Maven项目,导入依赖

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <!-- log4j依赖 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>

2.建表

CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `gender` varchar(6) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `addr` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;

INSERT INTO `user` VALUES (1, 'zhangsan', '123', 20, 'male', 'qd');
INSERT INTO `user` VALUES (2, 'lisi', '123', 21, 'male', 'bj');
INSERT INTO `user` VALUES (4, 'tom', '123', 19, 'male', 'nj');
INSERT INTO `user` VALUES (5, 'wangwu', '123', 20, 'male', 'sh');
INSERT INTO `user` VALUES (6, 'weihua', '111', 21, 'female', 'sz');

3.实体类

/**
 * 表示用户的实体类
 *
 * 属性名和数据库表名对应
 *
 * 符合JavaBean的规范
 */
public class User {
    private Long id;
    private String username;
    private String password;
    private Integer age;
    private String gender;
    private String addr;

    //set和get方法
    //toString方法
}

4.其他文件

编写映射文件UserMapper.xml

放在resources目录下的mappers

<?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">
<mapper namespace="userMapper">
    <select id="findAll" resultType="tech.code2048.bean.User">
        SELECT * FROM user
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 映射文件DTD约束,用来约束XML中的标签,直接从素材中拷贝就可以,不需要去记。-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 映射文件的根标签,其他的内容都要写在该标签的内部
	namespace:命名空间,与下面语句的id一起组成查询的标识,唯一的确定要执行的SQL语句 
-->
<mapper namespace="userMapper">
    <!-- select标签表示这是一个查询操作,除了这个标签还可以有insert、delete、update
		id:语句的id,和上面的namespace一起组成查询的标识,唯一的确定要执行的SQL语句
		resultType:查询结果对应的实体类型,目前这里先写全类名(包名+类名)
	-->
    <select id="findAll" resultType="tech.code2048.bean.User">
        <!-- SQL语句 -->
        SELECT * FROM user
    </select>
</mapper>

编写核心配置文件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">
<!-- 配置环境
	 default:指定默认环境,如果下面配置了多个id,通过delfault属性的值指定使用哪个环境
-->
<configuration>
    <!-- 配置环境 -->
    <environments default="dev">
        <environment id="dev">
             <!-- type:事务管理器类型,类型有如下两种。
			JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
 			MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。 
					默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将closeConnection属性设置
					为false来阻止它默认的关闭行为。
		-->
            <transactionManager type="JDBC"></transactionManager>
             <!-- type:指定数据源类型,类型有如下三种。
			UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
			POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
			JNDI:这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,
				容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
 		-->
            <dataSource type="POOLED">
                 <!-- 配置数据源的基本参数 -->
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

    <!-- 加载映射配置文件,该标签的作用是加载映射文件,加载方式有如下几种:

使用相对于类路径的资源引用 <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
使用完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
使用映射器接口实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
将包内的映射器接口实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>-->
    <mappers>
        
        <mapper resource="mappers/UserMapper.xml" />
    </mappers>

</configuration>

properties标签

将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件

创建配置数据源的配置文件jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false
jdbc.username=root
jdbc.password=root

typeAliases标签

写法1

<!-- 配置别名 -->
<typeAliases>
    <typeAlias type="tech.code2048.bean.User" alias="user" />
</typeAliases>

通过上面的配置为tech.code2048.bean包下的User类起了一个别名user。这种写法需要为每个类分别设置别名,如果类很多,这里的配置会很繁琐。

写法2

<!-- 配置别名 -->
<typeAliases>
    <package name="tech.code2048.bean"/>
</typeAliases>

这种写法为tech.code2048.bean下的所有类设置别名,别名为类名的首字母小写。

编写日志配置文件

log4j.properties 直接复制即可

#
# Hibernate, Relational Persistence for Idiomatic Java
#
# License: GNU Lesser General Public License (LGPL), version 2.1 or later.
# See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
#

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout
级别 描述
ALL LEVEL 打开所有日志记录开关;是最低等级的,用于打开所有日志记录
DEBUG 输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的
INFO 输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程
WARN 输出警告信息;表明会出现潜在错误的情形
ERROR 输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行
FATAL 输出致命错误;指出每个严重的错误事件将会导致应用程序的退出
OFF LEVEL 关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录

5.测试

public class MyTest {
    @Test
    public void test1() throws IOException {
        //加载核心配置文件
        InputStream stream = Resources.getResourceAsStream("SqlMapConfig.xml");
		//获得sqlSession工厂对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        //获得sqlSession对象
        SqlSession sqlSession = factory.openSession();
        //执行sql语句
        List<User> list = sqlSession.selectList("userMapper.findAll");
        //打印结果
        list.forEach(System.out::println);
		//释放资源
        sqlSession.close();
    }
}

三.使用(代理开发方式)

1.介绍

MyBatis代理开发方式实现Dao层的开发。

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

需要遵循的规范:

  • Mapper.xml文件中的namespacemapper接口的全限定名相同;
  • Mapper接口方法名和Mapper.xml中定义的每个statementid相同;
  • Mapper接口方法的输入参数类型和mapper.xml中定义的每个sqlparameterType的类型相同;
  • Mapper接口方法的返回值类型和mapper.xml中定义的每个sqlresultType的类型相同。

约定大于配置

2.准备

1.实体类

public class User {
    private Long id;
    private String username;
    private String password;
    private Integer age;
    private String gender;
    private String addr;
    
    //set、get
    //toString
}

2.下载MyBatisX插件

3.CRUD操作

1.编写UserMapper接口

public interface UserMapper {
    void add(User user);
    void delete(int id);
    void chg(User user);
    User findById(int id);
    List<User> findAll();
}

2.映射文件

<?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="tech.code2048.mapper.UserMapper">
    <!-- 
		id和接口中对应方法的方法名相同
		parameterType的类型和接口中对应方法的参数类型相同
	-->
    <insert id="add" parameterType="user">
		insert into user(username, password, age, gender, addr) values(#{username}, #{password}, #{age}, #{gender}, #{addr})
    </insert>

    <delete id="delete" parameterType="int">
        DELETE FROM user WHERE id=#{id}
    </delete>

    <update id="chg" parameterType="user">
        UPDATE user SET username=#{username}, password=#{password} WHERE id=#{id}
    </update>
	
    <!-- 
		resultType的类型和接口中对应方法的返回值类型相同
	-->
    <select id="findById" parameterType="int" resultType="user">
        SELECT * FROM user WHERE id=#{id}
    </select>

    <select id="findAll" resultType="user">
      SELECT * FROM user
    </select>
</mapper>

3.核心文件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>
    <typeAliases>
        <package name="tech.code2048.bean"/>
    </typeAliases>
    
    <!-- 配置环境 -->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/>
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

    <!-- 加载映射配置文件 -->
    <mappers>
        <mapper resource="tech/code2048/mapper/UserMapper.xml" />
    </mappers>
</configuration>

4.测试类

public class MyTest {
    private SqlSession sqlSession;
    private UserMapper userMapper;
    @Before
    public void init() throws IOException {
        //加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获取连接
        sqlSession = factory.openSession();
		//创建接口的代理对象
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @After
    public void destroy() {
        //关闭连接
        sqlSession.close();
    }

    @Test
    public void testFindById() {
        User user = userMapper.findById(1);
        System.out.println(user);
    }

    @Test
    public void testFindAll() {
        List<User> users = userMapper.findAll();
        users.forEach(user -> System.out.println(user));
    }
}

项目结构如下所示

4.参数绑定

需要传两个参数时

4.1序号参数绑定

UserMapper

List<User> findByNameAndGender(Integer age , String gender);

UserMapper.xml

<select id="findByNameAndGender" resultType="com.stedu.bean.User">
    SELECT * FROM `user` where  age=#{param1} and gender=#{param2}
</select>

java 测试类

@Test
public void testfindbynameandage() {
    List<User> byNameAndGender = userMapper.findByNameAndGender(20,"male");
    byNameAndGender.forEach(System.out::println);
}

用param1 param2 或 arg0 arg1代替

4.2注解参数绑定

UserMapper

List<User> findByNameAndGender1(@Param("age") Integer age ,@Param("gender") String gender);

UserMapper.xml

<select id="findByNameAndGender1" resultType="com.stedu.bean.User">
    SELECT * FROM `user` where  age=#{age} and gender=#{gender}
</select>

java 测试类

@Test
public void testfindbynameandage1() {
    List<User> byNameAndGender = userMapper.findByNameAndGender1(20,"male");
    byNameAndGender.forEach(System.out::println);
}

4.3Map参数绑定

UserMapper

List<User> findByMap(Map<String , Object>  map);

UserMapper.xml

<select id="findByMap" resultType="com.stedu.bean.User">
    SELECT * FROM `user` where  age=#{age} and gender=#{gender}
</select>

java 测试类

@Test
public void testfindbynameandage2() {
    HashMap<String, Object> map = new HashMap<>();
    map.put("age", 20);
    map.put("gender", "male");
    List<User> byNameAndGender = userMapper.findByMap(map);
    byNameAndGender.forEach(System.out::println);
}

4.4对象参数绑定

UserMapper

 User fingByObj(User user);

UserMapper.xml

<select id="fingByObj" resultType="user">
    <!-- 占位符的名字和参数实体类属性的名字相同 -->
    select * from user where username=#{username} and password=#{password}
</select>

java 测试类

@Test
public void testFindByObj() {
    User user = new User();
    user.setUsername("admin");
    user.setPassword("123456");

    User u = userMapper.fingByObj(user);
    System.out.println(u);
}

5.模糊查询

UserMapper

List<User> findByName(String username);

UserMapper.xml

<select id="findByName" resultType="com.stedu.bean.User">
    SELECT * FROM `user` where `username` like concat('%',#{username},'%')
</select>

java 测试类

@Test
public void testFindByName() {
    List<User> users = userMapper.findByName("zhang");
    users.forEach(System.out::println);
}

6.主键回填

6.1 last_insert_id()查询主键

适用于整数类型自增主键

<insert id="add" parameterType="user">
    <selectKey keyColumn="id" keyProperty="id" resultType="long" order="AFTER">
        <!-- 适用于整数类型自增主键 -->
        SELECT LAST_INSERT_ID()
    </selectKey>
    insert into user(username, password, age, gender, addr) values(#{username}, #{password}, #{age}, #{gender}, #{addr})
</insert>
6.2通过uuid()查询主键

适用于字符类型主键

<?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" >
<mapper namespace="tech.code2048.mapper.ProductMapper">
    <insert id="add" parameterType="product">
        <selectKey keyProperty="id" keyColumn="id" resultType="string" order="BEFORE">
            <!-- 适用于字符类型主键 -->
            SELECT REPLACE(UUID(),'-','')
        </selectKey>
        insert into product(id, name) values(#{id}, #{name})
    </insert>
</mapper>

7.动态SQL语句

7.1介绍

有很多时候,业务逻辑变化时,需要SQL语句是动态变化的。如名字为空时查询全部,不为空时模糊查询。

7.2 if

UserMapper

List<User> findByAgeAndAddr(@Param("age")Integer age,@Param("addr") String addr);

UserMapper.xml

<!-- 动态sql -->
<select id="findByAgeAndAddr" resultType="com.stedu.bean.User">
    select * from `user`
    <where>
        <if test="age!=null">
            and `age`=#{age}
        </if>
    <if test="addr!=null">
        and `addr`=#{addr}
    </if>
    </where>
</select>

或把where写在外面

<select id="findByCondition" resultType="user">
    <!-- 注意这里的where 1=1 -->
    select * from user where 1=1
    <if test="age!=null">
        and age=#{age}
    </if>
    <if test="gender!=null">
        and gender=#{gender}
    </if>
</select>

7.3 set

我们根据实体类属性的不同取值,使用不同的SQL语句来进行修改。比如在age不为空时对age进行修改,如果gender不为空时还要对gender进行修改。

Integer Update(User user);
    <update id="Update" parameterType="user">
        update `user`
            <set>
                <if test="username!=null and username.length>0">
                    `username`=#{username}
                </if>
                <if test="password!=null and password.length>0">
                    `password`=#{password}
                </if>
                <if test="age!=null and age.length>0">
                    `age`=#{age}
                </if>
                <if test="gender!=null and gender.length>0">
                    `gender`=#{gender}
                </if>
                <if test="addr!=null and addr.length>0">
                    `addr`=#{addr}
                </if>
            </set>
where `id`=#{id}
    </update>

7.4 trim

<trim prefix="" suffix="" prefixOverrides="" suffixOverrides="">`代替`<where>、<set>
<!--
	prefix:自动加入前缀
	prefixOverrides:自动忽略第一个“and”或者“or”
-->
<select id="findByCondition1" resultType="user">
    select * from user
    <trim prefix="where" prefixOverrides="and|or">
        <if test="age!=null">
            and age=#{age}
        </if>
        <if test="gender!=null">
            and gender=#{gender}
        </if>
    </trim>
</select>

<!--
	prefix:自动加入前缀
	suffixOverrides:自动忽略最后一个”,“
-->
<update id="chgByCondition1" parameterType="user">
    update t_users
    <trim prefix="set" suffixOverrides=",">
        <if test="age!=null">
            age=#{age},
        </if>
        <if test="gender!=null">
            gender=#{gender},
        </if>
    </trim>
    where id=#{id}
</update>

7.5 foeach

循环

例子:根据id范围查找

List<User> findbyids(List<Object> ids);
<select id="findbyids" resultType="com.stedu.bean.User">
    SELECT * from `user`
<where>
    <foreach collection="list" item="id" open="id in (" separator="," close=")">
        #{id}
    </foreach>
</where>
</select>

7.6 SQL片段抽取

目的:将重复的SQL提取出来,使用时用include引用即可,最终达到SQL重用的目的,减少代码冗余。

<?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">
<mapper namespace="tech.code2048.mapper.UserMapper">
    <sql id="selectAll">
        SELECT * FROM user
    </sql>
        <select id="findAll" resultType="user">
      <include refid="selectAll" />
    </select>
    
    <select id="findByCondition" resultType="user">
        <include refid="selectAll" />
        <where>
            <if test="age!=null">
                and age=#{age}
            </if>
            <if test="gender!=null">
                and gender=#{gender}
            </if>
        </where>
    </select>

    <select id="findByIds" resultType="user">
        <include refid="selectAll" />
        <where>
            <foreach collection="list" open="id in (" close=")" separator="," item="id">
                #{id}
            </foreach>
        </where>
    </select>
</mapper>

8.多表查询

8.1一对一查询

OrderMapper.xml

<!--
	resultMap:完成结果映射,表的字段到对象属性的映射,在表的字段名和对象属性名不相同时通常会被用到
	id:设置主键列的对应关系
	result:设置普通列的对应关系
	column:表的字段名
	property:对象的属性名

	这种映射关系了解即可,通常不用这种方式
-->
<!--
    <resultMap id="orderMap" type="order">
        <id column="id" property="id" />
        <result column="ordertime" property="ordertime" />
        <result column="total" property="total" />
        <result column="uid" property="user.id" />
        <result column="username" property="user.username" />
        <result column="password" property="user.password" />
    </resultMap>
-->
 <resultMap id="orderMap" type="order">
     <id column="id" property="id" />
     <result column="ordertime" property="ordertime" />
     <result column="total" property="total" />
     <!-- 
	 	association:用于建立一对一的关系
  		javaType:指定属性的类型
	 -->
     <association property="user" javaType="user">
         <id column="uid" property="id" />
         <result column="username" property="username" />
         <result column="password" property="password" />
     </association>
</resultMap>

<!--
	 resultMap:用于指定要使用的resultMap
-->
<select id="findAll" resultMap="orderMap">
    SELECT
    	o.*, u.id uid, u.username username, u.password password
    FROM
    	`order` o, user u
    WHERE
         o.uid=u.id;
</select>

或者

UserMapper.xml

<?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">
<mapper namespace="tech.code2048.mapper.OrderMapper">
    <resultMap id="orderMap" type="order">
        <id column="id" property="id" />
        <result column="ordertime" property="ordertime" />
        <result column="total" property="total" />
        <!-- 
            association:用于建立一对一的关系
            javaType:指定属性的类型
			column:	数据库中的列名,或者是列的别名,被设置为对应嵌套Select语句的参数
			select:用于加载复杂类型属性的映射语句的 ID,
				它会从 column 属性指定的列中检索数据,作为参数传递给目标 select 语句。
			注意这里select中的写法,这里需要UserMapper.xml中相应ID处有对应的SQL语句
         -->
        <association property="user" column="uid" javaType="user" select="tech.code2048.mapper.UserMapper.findById" />
    </resultMap>

    <select id="findAll" resultMap="orderMap">
        SELECT * FROM `order`
    </select>
</mapper>
<?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">
<mapper namespace="tech.code2048.mapper.UserMapper">
    <select id="findById" resultType="user">
        SELECT * FROM user WHERE id=#{id}
    </select>
</mapper>

8.2 一对多查询

<mapper namespace="tech.code2048.mapper.UserMapper">
    <resultMap id="userMap" type="user">
        <id column="id" property="id" />
        <result column="username" property="username" />
        <result column="password" property="password" />
        <!--
 			collection:关联一个集合
		-->
        <collection property="orders" ofType="order">
            <id column="oid" property="id" />
            <result column="ordertime" property="ordertime" />
            <result column="total" property="total" />
        </collection>
    </resultMap>

    <select id="findAll" resultMap="userMap">
        SELECT
            u.*, o.id oid, o.ordertime ordertime, o.total total
        FROM
            user u, `order` o
        WHERE
            u.id=o.uid;
    </select>
</mapper>

或者

UserMapper.xml

<?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">
<mapper namespace="tech.code2048.mapper.UserMapper">
    <resultMap id="userMap" type="user">
        <id column="id" property="id" />
        <result column="username" property="username" />
        <result column="password" property="password" />
        <!--
 			collection:关联一个集合
			column:	数据库中的列名,或者是列的别名,被设置为对应嵌套Select语句的参数
			select:用于加载复杂类型属性的映射语句的 ID,
				它会从 column 属性指定的列中检索数据,作为参数传递给目标 select 语句。
			注意这里select中的写法,这里需要UserMapper.xml中相应ID处有对应的SQL语句
		-->
        <collection property="orders" column="id" ofType="order" select="tech.code2048.mapper.OrderMapper.findByUid" />
    </resultMap>

    <select id="findAll" resultMap="userMap">
        SELECT * FROM user
    </select>
</mapper>

OrderMapper.xml

<?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">
<mapper namespace="tech.code2048.mapper.OrderMapper">
    <select id="findByUid" resultType="order">
        SELECT * FROM `order` WHERE uid=#{id}
    </select>
</mapper>

8.3 多对多查询

SysUserMapper.xml

<?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">
<mapper namespace="tech.code2048.mapper.SysUserMapper">
    <resultMap id="userMap" type="sysuser">
        <id column="id" property="id" />
        <result column="username" property="username" />
        <result column="email" property="email" />
        <result column="password" property="password" />
        <result column="phoneNum" property="phoneNum" />
        <collection property="roles" ofType="sysrole">
            <id column="rid" property="id" />
            <result column="roleName" property="roleName" />
            <result column="roleDesc" property="roleDesc" />
        </collection>
    </resultMap>

    <select id="findAll" resultType="sysuser" resultMap="userMap">
        SELECT
            u.*, r.id rid, r.roleDesc roleDesc, r.roleName roleName
        FROM
            sys_user u, sys_user_role ur, sys_role r
        WHERE
            u.id=ur.userId AND r.id=ur.roleId
    </select>

</mapper>

SysRoleMapper.xml

<?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">
<mapper namespace="tech.code2048.mapper.SysRoleMapper">
    <resultMap id="roleMap" type="sysrole">
        <id column="id" property="id" />
        <result column="roleName" property="roleName" />
        <result column="roleDesc" property="roleDesc" />
        <collection property="users" ofType="sysuser">
            <id column="uid" property="id" />
            <result column="username" property="username" />
            <result column="email" property="email" />
            <result column="password" property="password" />
            <result column="phoneNum" property="phoneNum" />
        </collection>
    </resultMap>
    
    <select id="findAll" resultMap="roleMap">
        SELECT
        r.*, u.id uid, u.username username, u.`password` `password`, u.email email, u.phoneNum phoneNum
        FROM
        sys_user u, sys_user_role ur, sys_role r
        WHERE
        u.id=ur.userId AND r.id=ur.roleId
    </select>
</mapper>

9.其他

标签:username,xml,gender,age,user,MyBatis,id
From: https://www.cnblogs.com/AaaalexQaQ/p/17583490.html

相关文章

  • mybatis-plus分页插件之count优化
    分页插件配置packagecom.example.demo.conf;importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;importorg.mybatis.spring.annotation.MapperScan;import......
  • MyBatisPlus入门案例
              ......
  • mybatis mapper 底层原理
    使用SqlSession的接口查询比较麻烦,MappedStatement的id也是字符串容易出错,也不符合面向接口的编程方式。所以mybatis也支持使用mapper接口的方法来简化操作初始化前面分析初始化过程的时候有说到MappedStatement的维护,这一步是在解析映射文件的时候完成的,mapper的注......
  • Mybatis数据库模型-代码生成器
    pom文件添加<dependencies><!--SpringBoot整合MyBatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3&l......
  • mybatisplus入门
    1. MybatisPlus的介绍MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。愿景我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。2.......
  • mybatis批量保存
    <insertid="saveBatchForList"parameterType="java.util.List">insertintoT_PRICE_PPI_BASEWEIGHT(BASEYEAR,ORGCODE,ORGNAME,BASECODE,BASENAME,WEIGHT,DATA_TYPE,STARTTIME,CREATOR,CREATETIME,AREACODE,AREANAME,GROUP_......
  • 转:求求你们了,MyBatis 批量插入别再乱用 foreach 了,5000 条数据花了 14 分钟。。
    转:求求你们了,MyBatis批量插入别再乱用foreach了,5000条数据花了14分钟。。MyBatis批量插入的五种方式,哪种最强??? Mysql调整Mybatis批量插入数量限制Mysql对语句的长度有限制,默认是4M。Mybatis对动态语句没有数量上的限制。   ......
  • 注解最后一篇利用注解整合mybatis
    步骤:1.在pom中添加依赖,下方spring-jdbc中的版本号需要和最开始添加依赖的版本一致2.在config中创建配置类,在配置类里面利用@bean创建方法返回数据库信息,同时扫描包,将包放入IOC容器中 总结:整合Batista就做两件事:1.创建会话工厂  2.生成目标包(dao层/mapper层)下所有有接口的......
  • MyBatis-Plus数据权限控制
    平时开发中遇到根据当前用户的角色,只能查看数据权限范围的数据需求。列表实现方案有两种,一是在开发初期就做好判断赛选,但如果这个需求是中途加的,或不希望每个接口都加一遍,就可以方案二加拦截器的方式。在mybatis执行sql前修改语句,限定where范围。当然拦截器生效后是全局性的,如何......
  • MyBatis-Plus这样实现动态SQL
    拦截器介绍拦截器是一种基于AOP(面向切面编程)的技术,它可以在目标对象的方法执行前后插入自定义的逻辑。MyBatis定义了四种类型的拦截器,分别是:Executor:拦截执行器的方法,例如update、query、commit、rollback等。可以用来实现缓存、事务、分页等功能。ParameterHandler:拦截参......