MybatisORM框架超轻松入门

1.初步认识

1.1 什么是框架?

框架是一个半成品,是已经对基础的代码进行了封装并提供相应的API,开发者在使用框架可直接调用封装好的api,能够省去很多代码的编写,从而提高工作效率和开发速度。

1.2 什么是ORM?

 ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

1.3 什么是mybatis框架?

MyBatis 是支持普通 SQL 查询存储过程高级映射的优秀==ORM框架==。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索封装。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录. 半自动化框架。必须写sql语句。即mybatis就是封装与数据库交互的半成品。

2. 如何使用mybatis.

准备条件,先创建一个数据库备用

create database mybatis;
use mybatis;
CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, NAME
VARCHAR(20), age INT);
INSERT INTO users(NAME, age) VALUES('Tom', 12);
INSERT INTO users(NAME, age) VALUES('Jack', 11);

(1)创建一个maven的java工程。

(2)引入mybatis 和 mysql等驱动需要用到的jar包。

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.27</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
    </dependency>
</dependencies>

 点击maven标志运行jar包

(3)创建一个实体类对象,与开头创建的数据库表对应

@Data
@NoArgsConstructor//无参构造
@AllArgsConstructor//有参构造
public class User {
    private int id;
    private String name;
    private int age;
}

(4)配置mybatis的配置文件---mybatis会读取该文件的内容完成连接数据库的功能。

新建一个mybatisXML

进入mybatis进行配置

<?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" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
</configuration>

 (5)编写相应的映射文件。

新建一个文件夹,创建一个XML

进入UserMapper编写相应的映射文件  -----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">
<!--namespace:命名空间:它的值现在可以随便写。
              以后必须和dao接口对应。
-->
<mapper namespace="a">

    <!--sql语句-->
    <!--1.根据id查询用户信息
          select:表示查询标签
             id:唯一标签.
             resultType: 返回结果的类型。 mybatis框架帮你把结果封装到User类型中。

             #{}:====>占位符。并且或解析uid的值。
    -->
    <select id="selectById" resultType="com.lly.entity.User">
        select * from users where id=#{uid}
    </select>
</mapper>

(6) 把映射文件引入到mybatis配置文件中。

 (7) 进行测试

 3.CUAD操作

public class UserTest {
    @Test
    public void selectById() throws Exception{
        //1.读取mybatis的配置文件。  连接数据库---
        Reader reader = Resources.getResourceAsReader("mybatis");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);

        //2.获取Session对象---->Connection对象
        SqlSession session=sqlSessionFactory.openSession();

        //3.执行相应的功能
        User user = session.selectOne("a.selectById", 2);
        System.out.println(user);
    }
    //将读取mybatis的配置文件,连接数据库,获取session等操作提取出来,每次运行优先执行一次
    SqlSession session;
    @Before
    public void before() throws Exception{
        Reader mybatis = Resources.getResourceAsReader("mybatis");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(mybatis);
        session=build.openSession();
    }
    @Test
    public void selectAll(){
        List<User> list = session.selectList("a.selectAll");
        System.out.println(list);
    }
    @Test
    public void insert(){
        User user = new User();
        user.setName("汤姆");
        user.setAge(8);
        session.insert("a.inset", user);
        session.commit();
    }
    @Test
    public void delete(){
        session.delete("a.delete",9);
        session.commit();
    }
    @Test
    public void update(){
        User user = new User();
        user.setName("唐老鸭");
        user.setAge(17);
        user.setId(10);
        session.update("a.updateUser",user);
        session.commit();
    }
}

4.实际开发中使用DAO操作

可以自己定义方法

4.1定义一个相关的接口。  

(1)定义接口,自定义方法

    public List<User> selectAll();

    public User selectById(int id);

    public int insertUser(User user);

    public int updateUser(User user);

    public int deleteById(int id);

(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:命名空间:它的值现在可以随便写。
              以后必须和dao接口对应。
-->
<mapper namespace="com.lly.dao.UserDao">//与接口对应
    <!--添加-->
    <insert id="insertUser">//id与接口中自定义方法名对应
          insert into users(name,age) values(#{name},#{age})
    </insert>
    <!--修改-->
    <update id="updateUser">
         update users set name=#{name},age=#{age} where id=#{id}
    </update>
    <!--删除-->
    <delete id="deleteById">
        delete from users where id=#{id}
    </delete>
    <!--这里的id必须和Dao中的方法名一致。-->
    <select id="selectById" resultType="com.lly.entity.User">
        select * from users where id=#{id}
    </select>

    <select id="selectAll" resultType="com.lly.entity.User">
         select * from users
    </select>

</mapper>

(3)测试

public class UserTest {
    SqlSession session;
    @Before
    public void before() throws Exception{
        Reader mybatis = Resources.getResourceAsReader("mybatis");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(mybatis);
        session=build.openSession();
    }
    @Test
    public void testInsert(){
        //得到dao的实现类。由mybatis框架按照映射文件帮你生成
        UserDao userDao=session.getMapper(UserDao.class);

        User user=new User();
        user.setAge(18);
        user.setName("葫芦娃");
        userDao.insertUser(user); //调用就是dao中自己的方法。

        session.commit();
    }
}

5.传递多个参数

两种方式

1.

2.

 测试

6.特殊字符

 示例  两种方法

1.

2.使用<![CDATA[ 特殊字符或SQL语句 ]]>

 7.mybatis的优化

7.1 引入db属性文件。

(1)新建一个数据库属性文件. properties

jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai
jdbc.driverName=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=root

 (2)在mybatis配置文件中引入属性文件并使用相应的key

7.2 引入日志文件。----更好的显示sql语句

(1)引入日志jar包

<dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.17</version>
 </dependency>

  (2)引入日志的配置文件,新建一个 log4j.properties

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

 测试

7.3 解决列名和属性名不一致。

第一种: 为查询的列起别名;让别名和属性名一致。

<select id="selectById" resultType="com.lly.entity.Order">
    select order_id id,order_no no,order_price price from orders where order_id=#{id}
</select>

 第二种: 使用resultMap标签 来完成属性和列的映射关系。

 <!--
        id:唯一标识
        type: 类型 ; 表与哪个实体类的映射
           <id 主键的映射关系 column="列名"  property="属性名"/>
           <result 普通字段/>

        autoMapping=true 表示自动映射。默认true
    -->
    <resultMap id="My01" type="com.lly.entity.Order" >
          <!--id必写-->
          <id property="id" column="order_id"/>
          <result property="no" column="order_no"/>
          <result property="price" column="order_price"/>
    </resultMap>
    <!--注意:使用了resultMap不能在使用resultType-->
    <select id="selectById" resultMap="My01" >
        select * from orders where order_id=#{id}
    </select>

8.链表查询

8.1 多对一

新建表备用

 

(1) 根据订单id查询订单信息以及该订单对应的用户信息。

第一种方式 通过链表查询。

<resultMap id="My01" type="com.lly.entity.Order" >
      <!--id必写-->
      <id property="id" column="order_id"/>
      <result property="price" column="order_price"/>
      <result property="num" column="num"/>
    <!--association:表示多对一
            property:表示对象属性名
            javaType:表示该对象所属的类型
            autoMapping必须写
    -->
      <association property="user" javaType="com.lly.entity.User" autoMapping="true">
          <!--User和User表的对应关系-->
           <id property="id" column="id"/>
      </association>
</resultMap>
<!--注意:使用了resultMap不能在使用resultType-->
<select id="selectById" resultMap="My01" >
    select * from orders o join users u on o.uid=u.id where o.order_id=#{id}
</select>

 第二种方式 通过嵌套查询。----两次查询。

 8.2一对多

从一的一方查询多的一方。

比如: 班级--1---n-->学生.

 创建表备用

CREATE TABLE class(
c_id INT PRIMARY KEY AUTO_INCREMENT,
c_name VARCHAR(20),
);
INSERT INTO class(c_name) VALUES('A');
INSERT INTO class(c_name) VALUES('B');
INSERT INTO class(c_name) VALUES('C');
CREATE TABLE student(
s_id INT PRIMARY KEY AUTO_INCREMENT,
s_name VARCHAR(20),
class_id INT
);
INSERT INTO student(s_name, class_id) VALUES('xs_A', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_B', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_C', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_D', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_E', 3);
INSERT INTO student(s_name, class_id) VALUES('xs_F', 3);

 例子:根据班级id查询班级信息以及该班级下所有的学生信息。

<resultMap id="My03" type="com.lly.entity.Clazz">
    <id column="c_id" property="cid"/>
    <result property="cname" column="c_name"/>
    <!--
         collection: 集合的意思 多的意思
            property:集合对象名
            ofType: 集合的泛型
    -->
    <collection property="students" ofType="com.lly.entity.Student" autoMapping="true">
          <id property="id" column="s_id"/>
          <result property="name" column="s_name"/>
          <result property="classId" column="class_id"/>
    </collection>
</resultMap>
<!--这里的id必须和Dao中的方法名一致。-->
<select id="findById" resultMap="My03">
       select * from class c join student s on c.c_id=s.class_id where c_id=#{id}
</select>

9.动态SQL语句

 (1)if和where一起用

  <!--如果传入了书名 则按照书名进行查询 如果没有传入书名 则查询所有
          where:可以帮你添加where关键 并且把第一个and | or去除
    --> 
<select id="findByCondition" resultMap="map">
        select * from book_info
        <where>
            <if test="bookname!=null and bookname!=''">
                and  book_name=#{bookname}
            </if>
            <if test="author!=null and author!=''">
                and  book_author=#{author}
            </if>
        </where>
    </select>

测试:

 

@Test
    public void testSelect01(){
        BookDao bookDao = session.getMapper(BookDao.class);
        Map<String,Object> map=new HashMap<String,Object>();//从网页中得到参数值 并且封装到map对象中。
        map.put("bookname1","西游记");
        map.put("author","罗贯中");
        List<Book> list = bookDao.findByCondition(map);

    }

(2) [choose when otherwise] 和where

<!--choose +where
      when:当条件满足时不会执行下面的when和other  都不满足则执行otherwise

-->
<select id="findByCondition2" resultMap="map">
     select * from book_info
     <where>
          <choose>
               <when test="bookname!=null and bookname!=''">
                    and book_name=#{bookname}
               </when>
             <when test="author!=null and author!=''">
                 and book_author=#{author}
             </when>
             <otherwise>
                  and book_price>35
             </otherwise>
         </choose>
     </where>
</select>
@Test
    public void testSelect02(){
        BookDao bookDao = session.getMapper(BookDao.class);
        Map<String,Object> map=new HashMap<String,Object>();//从网页中得到参数值 并且封装到map对象中。
        map.put("bookname","西游记");
        map.put("author","施耐庵");
        List<Book> list = bookDao.findByCondition2(map);
    }

(3)set标签。修改部分字段。

<!--修改部分列的值。
      set 可以帮你添加set关键字 并且去除最后的逗号。
-->
<update id="update">
    update book_info
    <set>
         <if test="name!=null and name!=''">
              book_name=#{name},
         </if>
         <if test="author!=null and author!=''">
             book_author=#{author},
         </if>
         <if test="pub!=null and pub!=''">
              book_pub=#{pub},
         </if>
         <if test="price!=null">
              book_price=#{price},
         </if>
    </set>
    where book_id=#{id}
</update>
@Test
public void testUpdate(){
    BookDao bookDao = session.getMapper(BookDao.class);
    Book book=new Book();
    book.setAuthor("鲁迅");
    book.setName("狂人日记");
    book.setId(1002);
    bookDao.update(book);
    session.commit();
}

(4) foreach 批量删除。

 <!--
     delete from book_info where id in(1001,1002,1003)

       in (1001,1002,1003)
       foreach:
         collection:要遍历的集合和数组名
         item: 每次遍历时赋值的元素变量名
         open: 以什么开始
         close:以什么结束
         separator: 分隔符
    -->
    <delete id="batchDelete">
        delete from book_info where book_id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
             #{id}
        </foreach>
    </delete>
@Test
public void testUpdat2e(){
    BookDao bookDao = session.getMapper(BookDao.class);
    int [] ids={1001,1002,1003};
    bookDao.batchDelete(ids);
    session.commit();
}

9.模糊查询

 10.分页插件--PageHelper

(1) 引入相关的pageHelper依赖

<!--分页插件的依赖-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.11</version>
</dependency>

(2) 加入拦截

(3)测试

@Test
public void testUpdate3(){
    EmpDao empDao = session.getMapper(EmpDao.class);
    //使用分页功能 request.getParamter("page")  request.getParamter("pageSize")
    PageHelper.startPage(2,10);
    List<Emp> list = empDao.findAll3("王");
     //可以把查询的结果封装到PageInfo类中 包含你想要的任何信息
        PageInfo<Emp> pageInfo=new PageInfo<Emp>(list);
        System.out.println("总条数:"+pageInfo.getTotal());
        System.out.println("当前页码的数据:"+pageInfo.getList());
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值