SSM框架 ------ MyBatis学习记录

125 阅读11分钟

一、引言

1.1 原始jdbc操作

//1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取连接
connection = DriverManager.getConnection(url, username, password);
//3. 获取statement
preparedStatement = connection.prepareStatement(sql);
//4. 执行更新或查询
resultSet = preparedStatement.executeQuery(sql);
//5. 遍历结果集
while (resultSet.next()) {                
System.out.println(resultSet.getInt("id")+'-'+resultSet.getString("username")+','+resultSet.getString("password"));
UserEntity userEntity = new UserEntity();
userEntity.setId(resultSet.getInt("id"));
userEntity.setUsername(resultSet.getString("username"));
userEntity.setPassword(resultSet.getString("password"));
System.out.println(userEntity);           
}

//6. 释放资源
resultSet.close();
preparedStatement.close();
connection.close();

1.2 原始jdbc存在的问题及解决方案

问题

  • 数据库连接创建、释放频繁造成系统资源浪费从而影响性能。
  • java代码和sql语句耦合死,sql语句是硬编码,代码不易维护。
  • 查询操作需要手动将结果集封装到实体中,增删改手动将实体数据设置到sql语句的占位符

解决方案

  • 使用数据库连接池初始化连接资源
  • 将sql语句抽取到xml配置文件中。
  • 使用反射、内省等底层技术自动将实体属性和表字段进行映射。

二、认识mybatis

2.1 什么是mybatis?

* mybatis是一个优秀的基于java代码的持久层框架,内部封装了jdbc,开发者只关注sql语句本身。

* mybatis通过xml配置或注解的方式将要执行的各种statement配置,并通过java对象和statement中sql动态参数进行映射生成最终的sql语句。

* mybatis执行的sql并将结果映射为java对象并返回。采用ORM思想解决实体和数据库表映射问题,对jdbc进行封装,屏蔽了jdbc API底层访问细节,使我们不用和jdbc API打交道就完成了数据库的持久化操作。

我的理解: Mybatis是一个持久层框架。其内部隐藏了jdbc繁杂的API。使得开发者只需要关注sql语句本身。它能够将数据库表字段和java中的实体对象的属性进行自动映射。

详情学习可以参照官网

补充:
ORM思想:(Object Relational Mapping)思想:对象关系映射。
ORM框架自动实现Entity实体的属性与关系型数据库字段的映射。CRUD的工作则可以交给ORM来自动生成代码方式实现。

帮助我们开发人员跟踪实体的变化,并将实体的变化翻译成sql脚本,执行到数据库中去,也就是将实体的变化映射到了表的变化。

2.2 mybatis的快速入门

下面先通过一个入门案例感受一下mybatis操作数据持久层

  1. 先导入pom.xml相关mybatis依赖
<!--mysql的驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.20</version>
</dependency>
<!--mybatis的依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.4</version>
</dependency>
<!--单元测试依赖-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
</dependency>
<!--日志依赖-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
  1. 创建一张user数据表

image.png

  1. 准备user实体类
public class User {

    private int id;

    private String username;

    private String password;

    private String phoneNum;

    private int status;
// 自行生成get/set方法、构造器、toString方法    
  1. 编写映射文件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="userMapper">
    <select id="findAll" resultType="cn.hfnu.domain.User">
        select * from t_user
    </select>
</mapper>
  1. 编写核心配置文件mybatis-config.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>
    <!--配置数据源环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db_test?serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--加载映射文件-->
    <mappers>
        <mapper resource="cn/hfnu/mapper/UserMapper.xml"></mapper>
    </mappers>
</configuration>          
  1. 测试
@Test
public void test1() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession会话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行sql语句  参数:命名空间 . id
    List<User> userList = sqlSession.selectList("userMapper.findAll");
    System.out.println("=======userList=========>"+userList);
    //释放资源
    sqlSession.close();
}

效果图

image.png

三、mybatis的映射文件的概述

<?xml version="1.0" encoding="UTF-8" ?>
<!--映射文件DTD的约束头-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--根标签的命名空间属性与下面的id组成查询的标识-->
<mapper namespace="userMapper">
    <!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
    <select id="findAll" resultType="cn.hfnu.domain.User">
        /*要执行的sql语句*/
        select * from t_user
    </select>
</mapper>

mybatis的增删改操作

<!--添加操作-->
<insert id="add" parameterType="cn.hfnu.domain.User">
    insert into t_user (username, password, phone_num, status) values (#{username}, #{password}, #{phoneNum}, #{status})
</insert>
@Test
public void test2() throws IOException {
    //创建一个user对象
    User user = new User();
    user.setUsername("大梦");
    user.setPassword("3344");
    user.setPhoneNum("139555001212");
    user.setStatus(1);
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession会话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行sql语句  参数:命名空间 . id
    int count = sqlSession.insert("userMapper.add", user);
    System.out.println("=========count========>"+count);
    //提交事务
    sqlSession.commit();
    //释放资源
    sqlSession.close();
}
<!--修改操作-->
<update id="update" parameterType="cn.hfnu.domain.User">
    update t_user set username=#{username}, phone_num = #{phoneNum}, status = #{status}  where id = #{id};
</update>
@Test
public void test3() throws IOException {
    //创建一个user对象
    User user = new User();
    user.setId(7);
    user.setUsername("大梦初醒");
    user.setPhoneNum("15043995110");
    user.setStatus(0);
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession会话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行sql语句  参数:命名空间 . id
    int count = sqlSession.update("userMapper.update", user);
    System.out.println("=========count========>"+count);
    //提交事务
    sqlSession.commit();
    //释放资源
    sqlSession.close();
}
<!--删除操作-->
<delete id="delete" parameterType="java.lang.Integer">
    delete from t_user where id = #{id}
</delete>
@Test
public void test4() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession会话对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行sql语句  参数:命名空间 . id
    int count = sqlSession.delete("userMapper.delete", 7);
    System.out.println("=========count========>"+count);
    //提交事务
    sqlSession.commit();
    //释放资源
    sqlSession.close();
}

四、mybatis的核心配置文件的标签

mapper标签:用来加载映射文件的,其加载方式:

  1. 使用相对于类路径的资源引用
  2. 使用完全限定资源定位符(URL)、
  3. 使用映射器接口实现类的完全限定类名
  4. 将包名内的映射器接口实现全部注册为映射器

properties标签:将数据源信息单独抽成一个properties。

<!--通过properties标签加载外部properties文件-->
<properties resource="jdbc.properties"></properties>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_test?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root

typeAliases标签:类型别名

<!--自定义配置别名-->
<typeAliases>
    <typeAlias type="cn.hfnu.domain.User" alias="user"></typeAlias>
</typeAliases>
<!--查询操作-->
<!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
<select id="findAll" resultType="user">
    /*要执行的sql语句*/
    select * from t_user
</select>

typehandlers标签:类型处理器获取的值以合适的值转换成Java类型。

准备实体类User

```
public class User {
    private int id;
    private String username;
    private String password;
    private String phoneNum;
    private int status;
    private Date birth;
//getter()/setter()方法略    

image.png

报错信息:

image.png

自定义日期类型处理器

//将java的属性的类型转化成数据库的字段对应的类型
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
    long time = date.getTime();
    preparedStatement.setLong(i, time);
}

//将数据库的字段的类型转换成java的属性类型
@Override
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
    //获取结果集中需要的数据(long)类型转换成date类型的数据
    long aLong = resultSet.getLong(s);
    Date date = new Date(aLong);
    return date;
}

//将数据库的字段的类型转换成java的属性类型
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
    //获取结果集中需要的数据(long)类型转换成date类型的数据
    long aLong = resultSet.getLong(i);
    Date date = new Date(aLong);
    return date;
}

//将数据库的字段的类型转换成java的属性类型
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
    long aLong = callableStatement.getLong(i);
    Date date = new Date(aLong);
    return date;
}
<!--自定义类型处理器-->
<typeHandlers>
    <typeHandler handler="cn.hfnu.handler.DateTypeHandler"/>
</typeHandlers>
<!--添加操作-->
<insert id="add" parameterType="user">
    insert into t_user (username, password, phone_num, status, birth)
    values (#{username}, #{password}, #{phoneNum}, #{status}, #{birth})
</insert>
public void add(User user);
@Test
public void test4() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    User user = new User();
    user.setUsername("meng");
    user.setPassword("000");
    user.setPhoneNum("13911220011");
    user.setStatus(1);
    user.setBirth(new Date());
    mapper.add(user);

    sqlSession.commit();
    sqlSession.close();
}

效果图

image.png

<!--根据id查询-->
<select id="findById" parameterType="int" resultType="user">
    select * from t_user where id = #{id};
</select>
@Test
public void test5() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    User user = mapper.findById(8);
    System.out.println("========birth=========>"+user.getBirth());
    sqlSession.close();
}

效果图

image.png

plugins标签:扩展功能,PageHelper分页的复杂操作进行封装。

<!--分页助手的依赖-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.4</version>
</dependency>
<dependency>
    <groupId>com.github.jsqlparser</groupId>
    <artifactId>jsqlparser</artifactId>
    <version>0.9.5</version>
</dependency>
<!--配置分页助手插件-->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <property name="dialect" value="mysql"/>
    </plugin>
</plugins>
//设置分页所需要的参数   当前页 + 每页显示的条数
PageHelper.startPage(2, 3);
//设置分页所需要的参数   当前页 + 每页显示的条数
PageHelper.startPage(3, 3);

List<User> userList = mapper.findAll();
for (User user : userList) {
    System.out.println(user);
}

//获得分页相关的参数
PageInfo<User> pageInfo = new PageInfo<User>(userList);
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示的条数:"+pageInfo.getPageSize());
System.out.println("总的记录数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("上一页:"+pageInfo.getPrePage());
System.out.println("下一页:"+pageInfo.getNextPage());
System.out.println("是否到首页:"+pageInfo.isIsFirstPage());
System.out.println("是否是尾页:"+pageInfo.isIsLastPage());

效果图

image.png

五、mybatis的API简介

六、mybatis的持久层实现

6.1 传统的方式

手动对dao层的实现 userdao接口:

List findAll();

userdaoimpl实现类:

private SqlSessionFactory factory; 
public UserDaoImpl(SqlSessionFactory factory) { this.factory = factory; }
@Override 
public List findAll() { 
SqlSession session = factory.openSession(); 
List users = session.selectList("com.itheima.dao.IUserDao.findAll"); session.close(); 
return users; 
}

6.2 代理开发的方式(重点)

1.mapper.xml文件中namespace与mapper接口的全限定名相同

2.mapper接口方法名和mapper.xml定义的每个statement的id相同。

3.mapper接口方法的输入参数类型和mapper.xml定义的每一个sql的parameterType的类型相同

4.mapper接口的输出参数和mapper.xml定义的每一个sql的resulttype的类型相同。

<mapper namespace="cn.hfnu.dao.UserMapper">
    <!--查询操作-->
    <!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
    <select id="findAll" resultType="user">
        /*要执行的sql语句*/
        select * from t_user
    </select>
</mapper>
public interface UserMapper {

    public List<User> findAll() throws IOException;
}
@Test
public void test1() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
   
//通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> all = mapper.findAll();
    System.out.println(all);
}

效果图

image.png

七、mybatis的映射文件

7.1 动态sql

引入log4j.properties

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<!--根据条件查询-->
<select id="findByCondition" parameterType="user" resultType="user">
    select * from t_user
    <where>
    <if test="username != null and username != ''">
        and username=#{username}
    </if>
     <if test="password != null and password != ''">
        and password=#{password}
     </if>
     <if test="status != null and status != ''">
         and status=#{status};
     </if>
    </where>
</select>
public List<User> findByCondition(User user);
@Test
public void test2() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    User user = new User();
    //user.setUsername("张三");
    user.setPassword("123");
    user.setStatus(0);
    List<User> userList = mapper.findByCondition(user);
    System.out.println("=============userList=========>"+userList);
}

效果图

image.png

<!--根据ids进行查询-->
<select id="findByIds" parameterType="list" resultType="user">
    select * from t_user
    <where>
        <foreach collection="list" open="id in (" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>
public List<User> findByIds(List<Integer> ids);
@Test
public void test3() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    List<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(3);
    ids.add(4);

    List<User> userList = mapper.findByIds(ids);
    System.out.println("========userList=========>"+userList);
}

效果图

image.png

7.2 sql片段

<!--sql语句的抽取-->
<sql id="selectUser">
    select username, status from t_user
</sql>

<!--根据ids进行查询-->
<select id="findByIds" parameterType="list" resultType="user">
    <include refid="selectUser"></include>
    <where>
        <foreach collection="list" open="id in (" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

八、 mybatis的多表操作

8.1 一对一的模型映射

image.png

public class Orders {

    private int id;
    private Date orderTime;
    private double total;

    //当前订单所属哪一个用户
    private User user;
//getter/setter方法省略
public interface OrderMapper {

    public List<Orders> findAll();
<!--自定义配置别名-->
<typeAliases>
    <typeAlias type="cn.hfnu.domain.User" alias="user"></typeAlias>
    <typeAlias type="cn.hfnu.domain.Orders" alias="order"></typeAlias>
</typeAliases>
<!--加载映射文件-->
<mappers>
    <mapper resource="cn/hfnu/mapper/UserMapper.xml"></mapper>
    <mapper resource="cn/hfnu/mapper/OrderMapper.xml"></mapper>
</mappers>
<mapper namespace="cn.hfnu.dao.OrderMapper">
    <resultMap id="orderMap" type="order">
        <!--设置实体属性和表字段的映射关系-->
        <id column="oid" property="id"></id>
        <result column="order_time" property="orderTime"></result>
        <result column="total" property="total"></result>
        <result column="user_id" property="user.id"></result>
        <result column="username" property="user.username"></result>
        <result column="password" property="user.password"></result>
        <result column="phone_num" property="user.phoneNum"></result>
        <result column="status" property="user.status"></result>
        <result column="birth" property="user.birth"></result>
    </resultMap>
    <select id="findAll" resultMap="orderMap">
        SELECT *,o.id oid from t_orders o, t_user u WHERE o.user_id = u.id
    </select>
</mapper>
<resultMap id="orderMap" type="order">
    <!--设置实体属性和表字段的映射关系-->
    <id column="oid" property="id"></id>
    <result column="order_time" property="orderTime"></result>
    <result column="total" property="total"></result>
    <!--<result column="user_id" property="user.id"></result>
    <result column="username" property="user.username"></result>
    <result column="password" property="user.password"></result>
    <result column="phone_num" property="user.phoneNum"></result>
    <result column="status" property="user.status"></result>
    <result column="birth" property="user.birth"></result>-->
    <!--1:1的映射配置-->
    <association property="user" javaType="user">
        <id column="user_id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="phone_num" property="phoneNum"></result>
        <result column="status" property="status"></result>
        <result column="birth" property="birth"></result>
    </association>
</resultMap>
@Test
public void test1() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);

    List<Orders> ordersList = mapper.findAll();
    for (Orders orders : ordersList) {
        System.out.println("=========orders===========>"+orders);
    }
    sqlSession.close();

}

效果图

image.png

8.2 一对多的模型映射

<resultMap id="userMap" type="user">
    <id column="user_id" property="id"></id>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="phone_num" property="phoneNum"></result>
    <result column="status" property="status"></result>
    <result column="birth" property="birth"></result>
    <!--配置集合信息-->
    <collection property="ordersList" ofType="order">
        <!--封装订单信息-->
        <id column="oid" property="id"></id>
        <result column="order_time" property="orderTime"></result>
        <result column="total" property="total"></result>
    </collection>
</resultMap>
<!--查询操作-->
<!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
<select id="findAll" resultMap="userMap">
    /*要执行的sql语句*/
   /* select * from t_user*/
   select *,o.id oid from t_user u, t_orders o where u.id = o.user_id
</select>
public class User {

    private int id;
    private String username;
    private String password;
    private String phoneNum;
    private int status;
    private Date birth;
    //描述当前用户存在哪些订单中
    private List<Orders> ordersList;
//getter()/setter()方法省略
@Test
public void test2() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = mapper.findAll();
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

8.3 多对多的模型映射

image.png

public List<User> findUserAndRoleAll();
<resultMap id="userRoleMap" type="user">
    <!--封装user信息-->
    <id column="user_id" property="id"></id>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="phone_num" property="phoneNum"></result>
    <result column="status" property="status"></result>
    <result column="birth" property="birth"></result>
    <!--封装user内部的rolelist信息-->
    <collection property="roleList" ofType="role">
        <id column="role_id" property="id"></id>
        <result column="role_name" property="roleName"></result>
        <result column="role_desc" property="roleDesc"></result>
    </collection>
</resultMap>
<select id="findUserAndRoleAll" resultMap="userRoleMap">
    SELECT * FROM t_user u, t_user_role ur, t_role r WHERE u.id = ur.user_id AND r.id = ur.role_id
</select>
public class User {

    private int id;
    private String username;
    private String password;
    private String phoneNum;
    private int status;
    private Date birth;
    //描述当前用户存在哪些订单中
    private List<Orders> ordersList;

    //描述当前用户所具有的哪些角色
    private List<Role> roleList;
//geter/setter方法省略
@Test
public void test3() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //通过mapper代理获取代理对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> userAndRoleAll = mapper.findUserAndRoleAll();
    for (User user : userAndRoleAll) {
        System.out.println(user);
    }
    sqlSession.close();
}

九、mybatis的注解开发

9.1 以注解的方式完成CRUD

usermapper的接口

@Insert("insert into t_user values (#{id}, #{username}, #{password}, #{phoneNum}, #{status}, #{birth})")
public void add(User user);

@Update("update t_user set username=#{username}, password=#{password} where id=#{id}")
public void update(User user);

@Delete("delete from t_user where id=#{id}")
public int delete(int id);

@Select("select * from t_user where id=#{id}")
public User findById(int id);

@Select("select * from t_user")
public List<User> findAll();
<!—注解方式加载映射关系-->
<mappers>
    <!--加载接口所在的包-->
    <package name="cn.hfnu.mapper"></package>
</mappers>
private UserMapper mapper;

@Before
public void before() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession会话对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    mapper = sqlSession.getMapper(UserMapper.class);
}

@Test
public void add(){
    User user = new User();
    user.setUsername("林心如");
    user.setPassword("123");
    user.setPhoneNum("139333210101");
    user.setStatus(1);
    mapper.add(user);
}

@Test
public void update(){
    User user = new User();
    user.setId(10);
    user.setUsername("心茹");
    user.setPassword("777");
    mapper.update(user);
}

@Test
public void delete(){
    int count = mapper.delete(8);
    System.out.println("========count===>"+count);
}

@Test
public void findById(){
    User user = mapper.findById(13);
    System.out.println("=======user=========>"+user);
}

@Test
public void findAll(){
    List<User> userList = mapper.findAll();
    for (User user : userList) {
        System.out.println("========userList=========>"+user);
    }
}

效果图

image.png

9.2 mybatis的注解实现复杂的映射关系

9.2.1 1:1的模型

image.png

public class Orders {

    private int id;
    private String orderTime;
    private double total;

    //当前的订单所属哪一个用户  1 :1
    private User user;
//getter/setter方法省略
@Select("select *,u.id uid, o.id oid from t_orders o, t_user u WHERE o.user_id = u.id")
@Results({
        @Result(column = "oid", property = "id"),
        @Result(column = "order_time", property = "orderTime"),
        @Result(column = "total", property = "total"),
        @Result(column = "user_id", property = "user.id"),
        @Result(column = "username", property = "user.username"),
        @Result(column = "password", property = "user.password"),
        @Result(column = "phone_num", property = "user.phoneNum"),
        @Result(column = "status", property = "user.status"),
        @Result(column = "birth", property = "user.birth"),
})
public List<Orders> findAll();
private OrderMapper mapper;

@Before
public void before() throws IOException {
    //加载核心配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //获取sqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession会话对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    mapper = sqlSession.getMapper(OrderMapper.class);
}

@Test
public void findAll(){
    List<Orders> ordersList = mapper.findAll();
    for (Orders orders : ordersList) {
        System.out.println("==========orders========>"+orders);
    }
}

效果图

image.png

@Select("select * from t_orders")
@Results({
        @Result(column = "oid", property = "id"),
        @Result(column = "order_time", property = "orderTime"),
        @Result(column = "total", property = "total"),
        @Result(
                property = "user",  //要封装的属性名称
                column = "user_id",   //根据哪个字段查询user表的数据
                javaType = User.class,  //要封装的实体类型
                //select属性:代表查询哪个接口的方法获得数据
                one = @One(select = "cn.hfnu.mapper.UserMapper.findById")
        )
})
public List<Orders> findAll();

效果图

image.png

9.2.2 1:n 的映射模型

image.png

@Select("select * from t_user")
@Results({
        @Result(id = true, column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "passsword", property = "password"),
        @Result(column = "phone_num", property = "phoneNum"),
        @Result(column = "status", property = "status"),
        @Result(
                property = "ordersList",
                column = "id",
                javaType = List.class,
                many = @Many(select = "cn.hfnu.mapper.OrderMapper.findByUid")
        )
})
public List<User> findUserAndOrderAll();
@Select("select * from t_orders where user_id = #{user_id}")
public List<Orders> findByUid(int user_id);
@Test
public void findUserAndOrderAll(){
    List<User> userAndOrderAll = userMapper.findUserAndOrderAll();
    for (User user : userAndOrderAll) {
        System.out.println("===========user======>"+user);
    }
}

9.2.3 m:n模型映射

image.png

//当前用户具有哪些角色
private List<Role> roleList;
public interface RoleMapper {

    @Select("SELECT * from t_user_role ur, t_role r WHERE ur.role_id = r.id AND ur.user_id = #{user_id}")
    public List<Role> findByUserId(int user_id);
}
@Select("select * from t_user")
@Results({
        @Result(id = true, column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "password", property = "password"),
        @Result(column = "phone_num", property = "phoneNum"),
        @Result(
                property = "roleList",
                column = "id",
                javaType = List.class,
                many = @Many(select = "cn.hfnu.mapper.RoleMapper.findByUserId")
        )
})
public List<User> findUserAndRoleAll();
@Test
public void findUserAndOrderAll(){
    List<User> userAndRoleAll = userMapper.findUserAndRoleAll();
    for (User user : userAndRoleAll) {
        System.out.println("========user========>"+user);
    }
}

以上步骤按部就班的完成对数据持久层框架有基础的入门学习,这只是个人的学习记录。如果你在看就点“在看”,点个“赞”,滴,IT学习面试就业必胜卡,坚持一件事情不容易,我们的目标和和人民日报站在一起!