JAVA框架-Mybatis上(配置和基础使用)

什么是Mybatis?

MyBatis是java平台下一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,简单普通的 Java对象)映射成数据库中的记录。

其前身为apache的ibatis后来迁移到Gihub并更名为MyBatis

特点

1.轻量级自身不依赖其他任何JAR,但需要提供JDBC实现

2.灵活,更加适用于需求变化频繁的互联网应用

3.学习成本低,相比ORM框架而言,掌握MyBatis的使用是很轻松的

在项目中的位置

可以看出MyBatis处在DAO(数据访问对象)的位置,回顾一下DAO的工作职责:

  • 连接数据库

  • 接收输入数据

  • 拼接并执行SQL

  • 解析并返回结果

其实Mybatis就是一个数据库的框架

特色功能

MyBatis在解决上述问题的同时提供了更多实用的功能

  • 动态SQL,即在SQL语句中可以包含逻辑处理(判断,循环等....)
  • 高级映射,支持一对一,一对多映射
  • 动态代理Mapper,使得可以用面向对象的方式来完成数据库操作
  • 逆向工程,根据表结构自动生成,POJO,Mapper映射和Mapper接口,包含简单的CRUD

Mybatis环境搭建

官方文档:https://mybatis.org/mybatis-3/getting-started.html

这里我们直接创建Maven项目,然后把Mybatis当做依赖添加过来,在porm.xml文件中添加如下依赖

  <dependencies>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.4</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.17</version>
    </dependency>

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

    <dependency>
      <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version>
    </dependency>
  </dependencies>

然后顺手配置一下log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout  
# Console output... 设置输出格式
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

然后我们还需要配置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"/>
            <!--            指定数据源 就是数据来自哪里 这里默认使用MyBatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!-- 表示本机 localhost  &amp;就是&  xml中&需要转译-->
                <property name="url" value="jdbc:mysql:///mybatisDB?serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="3692512"/>
            </dataSource>
        </environment>
    </environments>
    <!--    指定要加载的映射文件-->
    <mappers>
        <mapper resource="mapper/ProductsMapper.xml"/>
    </mappers>
</configuration>

到了这一步,要注意,其实我们的sql语句都是写在mapper文件夹下的ProductsMapper.xml中,这样我们就避免了数据库语言的硬编码,目前为止所有的配置文件对应的目录应该如下:

Mybatis的基本CRUD

首先为了演示方便,先建立一个数据库

CREATE DATABASE IF NOT EXISTS `mybatisDB` CHARACTER SET utf8;
USE `mybatisDB`;
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR(20) DEFAULT NULL,
 `price` DOUBLE DEFAULT NULL,
 `date` DATE DEFAULT NULL,
 `cid` VARCHAR(20) DEFAULT NULL,
 PRIMARY KEY (`pid`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
INSERT INTO `products` VALUES (1,'东北大米',40,NULL,'s002'),(2,'新疆大枣',38,NULL,'s002'),(3,'新疆切糕',68,NULL,'s001'),(4,'十三香',10,NULL,'s002'),(5,'老干爹',20,NULL,'s002'),(6,'泰
国咖喱2',50.5,'2020-01-02','s001'),(7,'泰国咖喱2',50.5,'2020-01-02','s001');

普通查询和模糊查询

刚才说了,我们的查询语言应该都是写在mapper文件夹下ProductsMapper.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">
<!--namespace 用于多个Mapper出现相同的sql时区分不同包-->
<mapper namespace="Bean.ProductMapper">

    <!--查询语句
    id用于表示这条sql
    parameterType 表示 sql语句接受一个整数参数
    resultType表示 将结果映射到Products对象中
    #{} 表示一个站位符等同于 ?
	如果在字符串中 要把#换成$
    若输入参数是基础数据类型则可以随意写
    若输入是一个POJO则写属性名称-->
    
    <select id="selectProductById" parameterType="int" resultType="Bean.Product">
        select * from products where id = #{id}
    </select>

    <!--多个参数查询-->
    <select id="selectProductByIdAndPrice" parameterType="map" resultType="Bean.Product">
        select *from products where id = #{id} and cid = #{cid}
    </select>
    
	<!--模糊查询-->
    <select id="selectProductLikeName" parameterType="string" resultType="Bean.Product">
        select * from products where name like "%${name}%"
    </select>

</mapper>

然后我们进行测试

public class MyTest {

    private SqlSessionFactory factory;

    @Before
    public  void init() throws IOException {
        //获取的工厂构造器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //加载配置文件
        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        //获得会话工厂
        factory = builder.build(stream);
    }

    @Test
    public void selectTest() throws IOException {
        //获得会话
        SqlSession sqlSession = factory.openSession();
        //执行sql
        Product product = sqlSession.selectOne("selectProductById", 2);
        System.out.println(product);
    }
    
    @Test
    public void selectTest2() throws IOException {
        //获得会话
        SqlSession sqlSession = factory.openSession();
        HashMap map = new HashMap();
        map.put("id",4);
        map.put("cid","s002");

        //执行sql
        Product product = sqlSession.selectOne("selectProductByIdAndPrice", map);
        System.out.println(product);
    }

    @Test
    public void selectTest3() throws IOException {
        //获得会话
        SqlSession sqlSession = factory.openSession();
        //执行sql
        List<Product> products = sqlSession.selectList("selectProductLikeName", "新疆");
        System.out.println(products);
        sqlSession.close();
    }
}

插入数据

在mapper文件夹下ProductsMapper.xml添加:

<!-- insert没有返回值-->
<insert id="insertProduct" parameterType="Bean.Product">
    insert into products values(null,#{name},#{price},#{pdate},#{cid})
</insert>

测试代码

@Test
public void insertTest() {
    //设置自动提交为true 默认为false
    SqlSession session = factory.openSession(true);
    //实例化一个商品
    Product p = new Product();
    p.setName("虎邦辣酱");
    p.setPrice(5.5f);
    p.setPdata(new Date());
    p.setCid("s001");
    session.insert("insertProduct",p);
    //session.commit();//手动commit
    session.close();
}

这里注意,mybatis是默认开启事务回滚的,所以我们要么在创建session的时候,设置属性factory.openSession(true);,要么需要手动设置回滚确认session.commit();

获取当前插入数据的ID

很多情况下需要获取刚刚添加的记录的id用来做表关联,要获得id有两种方式

  • 对于支持自增的数据库MySQL,我们只需要指定这两个属性即可:keyProperty="id" useGeneratedKeys="true",第一个就是要告诉mybatis谁是主键,MyBatis会把id存储到传入对象的pid属性中

    <insert id="insertProduct" parameterType="Bean.Product" keyProperty="id" useGeneratedKeys="true">
      insert into products values(null,#{pname},#{price},#{pdate},#{cid})
    </insert>
    

随后我们在java中插入数据后,只需要访问Bean的pid属性就好了

  @Test
  public void insertTest() {
      //设置自动提交为true 默认为false
      SqlSession session = factory.openSession(true);
      //实例化一个商品
      Product p = new Product();
      p.setName("虎邦辣酱");
      p.setPrice(5.5f);
      p.setPdata(new Date());
      p.setCid("s001");
      session.insert("insertProduct",p);
      //session.commit();//手动commit
      session.close();
      System.out.println("输入数据的行数:"+p.getPid());
  }
  • 不支持自增的数据库

    <!--插入数据    -->
    <insert id="insertProduct" parameterType="Bean.Product" >
        insert into products values(null,#{name},#{price},#{date},#{cid})
        <!--指定如何获取id 并放入对象某个属性中 -->
        <selectKey resultType="int" keyProperty="pid" order="AFTER" >
            select last_insert_id();
        </selectKey>
    </insert>
    

    注意:select last_insert_id();是mysql的函数,oracle没有,那就需要将其替换为oracle中生产id的函数,selectKey的原理是执行这个sql函数,然后将结果放入对象的属性中,order指定id放入对象属性是在执行sql前或者后。关于before和after的选择,要根据id的来源是自增的还是自己编写语句获取的.

更新数据

<!--更新数据    -->
    <update id="updateProduct" parameterType="Bean.Product">
        update products set
            name = #{name},
            price = #{price},
            date = #{date},
            cid = #{cid}
        where id = #{id}
    </update>
@Test
public void updateTest() {
    SqlSession session = factory.openSession();
    //先获取一条记录
    Products p = session.selectOne("selectProductBtId", 1);
    //更新属性
    p.setPrice(99.99f);
    //执行更新
    int count = session.update("updateProduct", p);
    System.out.println("update count :"+count);
    //提交事务
    session.commit();
    session.close();
}

删除数据

<!--通过id删除    -->
<delete id="deleteProductById" parameterType="int">
  delete from products where
  id = #{id}
</delete>
@Test
public void deleteTest() {
    SqlSession session = factory.openSession();
    int count = session.delete("deleteProductById", 2);
    System.out.println("delete count :"+count);
    session.commit();
    session.close();
}

原文地址:https://www.cnblogs.com/JeasonIsCoding/p/13232677.html