• MyBatis(上)


    目录

    1、概述:

    2、MyBatis的配置:

    1、第一个是: mybatis-config.xml:

    1、environments:

    2、transactionManager:

    3、dataSource:

    2、第二个是:XXXMpaper.xml

    3、MyBatis完成CRUD:

    1、Create(增):

    2、delete(删):

    3、update(改)

    4、select(查): 

    4、MyBatis的参数处理:

    1、单个简单参数:

    2、Map参数:

    3、对象类型:

     4、多参数:

    5、多参数之Param注解

    6、 返回map集合:

    (1)单个map:

    (2)多个map:

    (3)返回Map:,map>

    7、resultMap结果映射:

    (1)resultMap进行结果映射

    (2)开启驼峰命名自动映射:


    1、概述:

            MyBatis(以前称为iBATIS)是一个Java持久性框架,用于简化数据库访问和与关系数据库的交互。它提供了一种将数据库操作与Java应用程序的业务逻辑分离的方式,使开发人员能够更轻松地编写数据库访问代码。MyBatis本质上就是对JDBC的封装,通过MyBatis完成CRUD。

            MyBatis作为持久层的一个框架,使用到的一个思想就是ORM,用于将对象模型(通常是面向对象编程语言中的类和对象)映射到关系数据库中的数据模型(表、列等)。ORM框架允许开发人员以面向对象的方式进行数据库操作,而不必直接编写SQL查询。通过这个可以使Java中的对象转化为数据库表的一个记录,这种转化的关系就叫做映射。

            之前也注意到啦,什么domain、bean、pojo,只不过一开始没注意其中的含义,大概意思就是,pojo是普通的java类,bean(Spring框架的时候使用的比较多),domain(领域模型------封装数据的),不同的开发的团队可能叫法不一样。

            MyBatis是一个半自动化的ORM框架,就是需要我们手动去书写SQL语句,Hibernate是一个全自动的ORM框架。

    1. SQL映射:MyBatis通过XML或注解方式定义SQL查询,将Java对象与数据库表之间的映射关系。这使得开发人员可以在SQL中编写原生SQL查询,而不需要使用对象关系映射(ORM)框架。

    2. 简化数据访问:MyBatis处理了许多数据库访问的底层细节,如连接管理、事务处理和结果集映射,从而使开发人员能够专注于业务逻辑而不必关心这些细节。

    3. 动态SQL:MyBatis允许在SQL查询中使用动态SQL,根据条件动态生成SQL查询,这在构建复杂查询时非常有用。

    4. 参数映射:MyBatis支持将Java对象作为参数传递给SQL查询,参数映射工作非常灵活,可以轻松地传递单个参数、多个参数、参数对象等。

    5. 结果集映射:MyBatis支持将SQL查询的结果集映射到Java对象,开发人员可以使用XML或注解来定义映射规则。

    6. 事务管理:MyBatis支持事务管理,可以通过编程方式管理事务,也可以配置自动提交或手动提交事务。

    7. 插件支持:MyBatis提供了插件机制,允许开发人员编写自定义插件来扩展其功能,例如添加日志、性能监控等。

    8. 集成性:MyBatis可以与Spring、Spring Boot等常见的Java框架和应用服务器集成,使其更容易在现有项目中使用。

    9. 易于学习和使用:MyBatis的学习曲线相对较低,它的配置和使用都相对简单明了。

            总之,MyBatis是一个轻量级的Java持久性框架,适用于需要直接访问数据库的应用程序。它提供了丰富的功能,包括SQL映射、参数映射、结果集映射等,使得数据库访问变得更加简单和灵活。

    2、MyBatis的配置:

    1、第一个是: mybatis-config.xml:

            当然这配置文件的名字不是固定死的,只是大家都这么叫就随大流好吧,然后是这配置文件的存放位置,这边也是大家默认的存入放在资源路径下也就是Resource路径下,(该路径就是类的根路径)。

    1. "1.0" encoding="UTF-8" ?>
    2. configuration
    3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6. <environments default="development">
    7. <environment id="development">
    8. <transactionManager type="JDBC"/>
    9. <dataSource type="POOLED">
    10. <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    11. <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
    12. <property name="username" value="root"/>
    13. <property name="password" value="10100109"/>
    14. dataSource>
    15. environment>
    16. environments>
    17. <mappers>
    18. <mapper resource="CarMapper.xml"/>
    19. mappers>
    20. configuration>
    1、environments:

            代表环境可以是多个,以“s”结尾表示复数,也就是说mybatis的环境可以配置多个数据源。其中default属性表示默认使用的是哪个环境,default后面填写的是environment的id。default的值只需要和environment的id值一致即可。

            environment作为子标签,具体的环境配置(主要包括:事务管理器的配置 + 数据源的配置)i其中id表示给当前环境一个唯一标识,该标识用在environments的default后面,用来指定默认环境的选择。

    2、transactionManager:

            配置事务管理器,type属性指定事务管理器具体使用什么方式,可选值包括:

    1. JDBC:使用JDBC原生的事务管理机制。
    2. MANAGED:交给其它容器来管理事务,比如WebLogic、JBOSS等。如果没有管理事务的容器,则没有事务。没有事务的含义:只要执行一条DML语句,则提交一次
    3、dataSource:

            用于指定数据源(给程序提供连接对象),type属性用来指定具体使用的数据库连接池的策略,可选值包括三个:

    UNPOOLED:采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用数据库连接池的思想。所以使用sqlsessionFactory创建sqlsesion会话的时候,每一次创建都是一个新的会话对象,这样效率低而其不安全。

    POOLED:采用传统的javax.sql.DataSource规范中的连接池,每一次创建连接都是从连接池中获取连接,可以限制连接的个数。一般使用连接池的话,需要配置参数。

    1. <property name="poolMaximumActiveConnections" value="10"/>
    2. <property name="poolMaximumIdleConnections" value="5"/>
    3. <property name="poolTimeToWait" value="1000"/>
    4. <property name="poolMaximumCheckoutTime" value="10000"/>

     

    JNDI:使用其他第三方的数据库连接池

    mappers:在mappers标签中可以配置多个sql映射文件的路径。

    • mapper:配置某个sql映射文件的路径
      • resource属性:使用相对于类路径的资源引用方式
      • url属性:使用完全限定资源定位符(URL)方式

    2、第二个是:XXXMpaper.xml

            当然这个也是不确定的,一样的性质!操作数据库的文件,按照自己的需求进行修改。

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="kkk">
    6. <insert id="insertCar">
    7. insert into t_car (id,car_num,brand,guide_price,produce_time,car_type)
    8. values (null,'1220','BYD秦',20,'2020-1-1','电动车')
    9. insert>
    10. mapper>

    3、MyBatis完成CRUD:

    1、Create(增):

    1. <insert id="insertCar">
    2. insert into t_car (id,car_num,brand,guide_price,produce_time,car_type)
    3. values (null,#{carNum},#{brand},#{guidingPrice},#{produceTime},#{carType})
    4. /*类的属性名*/
    5. insert>

     Car类:

    1. public class Car {
    2. private Long id;
    3. private String brand;
    4. private String carNum;
    5. private Double guidingPrice;
    6. private String produceTime;
    7. private String carType;}

    主要是根据get和set方法。

    测试类:

    1. //插入数据
    2. @Test
    3. public void test4(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. Car car=new Car(null,"仰望U8","2222",90.0,"2022-2-2","混动");
    6. sqlSession.insert("insertCar",car);//sql语句的id,对象
    7. sqlSession.commit();
    8. sqlSession.close();
    9. }

    2、delete(删):

    1. <delete id="deleteByID">
    2. delete from t_car where id =#{id}
    3. delete>
    1. //删除数据
    2. @Test
    3. public void test5(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. sqlSession.delete("deleteByID",176);
    6. sqlSession.commit();
    7. sqlSession.close();
    8. }

    3、update(改)

    1. <update id="updateCar">
    2. update t_car set car_num=#{carNum}, brand=#{brand}, guide_price=#{guidingPrice},car_type=#{carType} ,produce_time=#{produceTime} where id=#{id}
    3. update>
    1. //修改数据
    2. @Test
    3. public void test6(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. Car car = new Car(177L,"雪铁龙","3457",12.1,"2019-6-9","燃油");
    6. sqlSession.update("updateCar",car);
    7. sqlSession.commit();
    8. sqlSession.close();
    9. }

    4、select(查): 

     查一个:

    1. <select id="selectById" resultType="com.songzhishu.mybatis.pojo.Car">
    2. select id,
    3. brand,
    4. car_num as carNum,
    5. guide_price as guidingPrice,
    6. car_type as carType,
    7. produce_time as produceTime
    8. from t_car
    9. where id = #{id}
    10. select>

    其中查询的配置文件中resultType指定啦查询结果封装的对象。这里有一个问题,查询的结果集的列名,有时候会和我们的定义类的属性不一致,就会导致数据封装的时候,会出现有的属性的值没有被封装上。所以面对不一致的时候我们要进行重命名

    1. //查找数据 一条
    2. @Test
    3. public void test4(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. Object car = sqlSession.selectOne("selectById", 179);
    6. System.out.println(car);
    7. sqlSession.close();
    8. }

    查全部:

    1. <select id="selectAll" resultType="com.songzhishu.mybatis.pojo.Car">
    2. select id,
    3. brand,
    4. car_num as carNum,
    5. guide_price as guidingPrice,
    6. car_type as carType,
    7. produce_time as produceTime
    8. from t_car
    9. select>
    1. //查找数据 一条
    2. @Test
    3. public void test5(){
    4. SqlSession sqlSession = SqlSessionUtil.openSession();
    5. List selectAll = sqlSession.selectList("selectAll");
    6. for (Object o : selectAll) {
    7. System.out.println(o);
    8. }
    9. sqlSession.close();
    10. }
    11. 4、MyBatis的参数处理:

      1、单个简单参数:

      • byte         short          int         long         float         double         char
      • Byte         Short         Integer         Long         Float         Double         Character
      • String
      • java.util.Date
      • java.sql.Date

      mapper:

      1. /**
      2. * 测试接口中的方法只有一个参数,并且是简单类型的数据
      3. * id long name string brith data sex char
      4. *
      5. */
      6. List selectById(Long id);
      7. List selectByName(String name);
      8. List selectByBrith(Date date);
      9. List selectBySex(Character sex);

      mapper映射文件:

      1. <select id="selectById" resultType="Student" parameterType="long">
      2. select *
      3. from t_student
      4. where id = #{id}
      5. select>
      6. <select id="selectByName" resultType="Student" parameterType="string">
      7. select *
      8. from t_student
      9. where name = #{name}
      10. select>
      11. <select id="selectByBrith" resultType="Student" parameterType="date">
      12. select *
      13. from t_student
      14. where birth = #{birth}
      15. select>
      16. <select id="selectBySex" resultType="Student">
      17. select *
      18. from t_student
      19. where sex = #{sex}
      20. select>

      test:

      1. /*
      2. * 测试单个参数,数据类型是简单类型
      3. */
      4. @Test
      5. public void test1() throws ParseException {
      6. SqlSession sqlSession = SqlSessionUtil.openSession();
      7. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      8. //id
      9. List studentList = mapper.selectById(1L);
      10. for (Student student : studentList) {
      11. System.out.println(student);
      12. }
      13. System.out.println("------------");
      14. //name
      15. List studentList1 = mapper.selectByName("张三");
      16. for (Student student : studentList1) {
      17. System.out.println(student);
      18. }
      19. //data
      20. System.out.println("------------");
      21. SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
      22. Date brith=sdf.parse("2003-10-09");
      23. List studentList2 = mapper.selectByBrith(brith);
      24. for (Student student : studentList2) {
      25. System.out.println(student);
      26. }
      27. System.out.println("------------");
      28. //sex
      29. List studentList3 = mapper.selectBySex('男');
      30. for (Student student : studentList3) {
      31. System.out.println(student);
      32. }
      33. }

      2、Map参数:

      mapper接口:

      1. /**
      2. * 测试map集合类型
      3. */
      4. int insertStudentByMap(Map map);

      mapper映射文件:

      1. <insert id="insertStudentByMap" parameterType="map">
      2. insert into t_student(id,name,age,sex,height,birth)
      3. values (null,#{name},#{age},#{sex},#{height},#{birth});
      4. insert>

      测试类:

      1. /**
      2. * map集合类型的参数
      3. */
      4. @Test
      5. public void test2() throws ParseException {
      6. SqlSession sqlSession = SqlSessionUtil.openSession();
      7. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      8. Map map=new HashMap<>();
      9. map.put("name","张彩霞");//key是什么 然后取值的时候就
      10. map.put("sex",'女');
      11. map.put("height",166.0);
      12. map.put("age",45);
      13. map.put("birth",new Date());
      14. int count = mapper.insertStudentByMap(map);
      15. sqlSession.commit();
      16. sqlSession.close();
      17. }

      3、对象类型:

      mapper接口:

      1. /**
      2. * 测试pojo类型
      3. */
      4. int insertStudentByPojo(Student student);

      mapper映射文件:

      1. <insert id="insertStudentByPojo">
      2. insert into t_student(id,name,age,sex,height,birth)
      3. values (null,#{name},#{age},#{sex},#{height},#{birth});
      4. insert>

      测试类:

      1. /**
      2. * pojo类型
      3. */
      4. @Test
      5. public void test3() throws ParseException {
      6. SqlSession sqlSession = SqlSessionUtil.openSession();
      7. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      8. SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
      9. Date brith1=sdf.parse("2003-11-29");
      10. Student student=new Student(null,"小蒋",19,163.0,brith1,'女');
      11. int count = mapper.insertStudentByPojo(student);
      12. System.out.println(count);
      13. sqlSession.commit();
      14. sqlSession.close();
      15. }

       4、多参数:

      mapper接口:

      1. /**
      2. * 多参数类型
      3. */
      4. List selectByNameAndSex(String name,Character sex);

      mapper映射文件:

      1. <select id="selectByNameAndSex" resultType="Student">
      2. select *
      3. from t_student
      4. where name = #{arg0}
      5. and sex = #{arg1}
      6. select>

      测试类:

      1. @Test
      2. public void test4(){
      3. SqlSession sqlSession = SqlSessionUtil.openSession();
      4. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      5. List studentList = mapper.selectByNameAndSex("小蒋", '女');
      6. for (Student student : studentList) {
      7. System.out.println(student);
      8. }
      9. sqlSession.close();
      10. }

      总结:

              

              但是这种方式不太好吧,每一次写sql语句的时候,只能使用mybatis自带的这种命名规则嘛,这样的代码可读性也太差啦。所以就推出啦参数可以使用Param注解。

      5、多参数之Param注解

      mapper接口:

      1. /**
      2. * 多参数类型 Param注解
      3. */
      4. List selectByHeightAndSex(@Param("sex") Character sex,@Param("height") Double height);

      mapper樱色文件:

      1. <select id="selectByHeightAndSex" resultType="Student">
      2. select *
      3. from t_student
      4. where height >#{height}
      5. and sex = #{sex}
      6. select>

       测试类:

      1. /**
      2. * 参数传递 Param注解
      3. */
      4. @Test
      5. public void test5(){
      6. SqlSession sqlSession = SqlSessionUtil.openSession();
      7. StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      8. List studentList = mapper.selectByHeightAndSex('女', 165.0);
      9. for (Student student : studentList) {
      10. System.out.println(student);
      11. }
      12. sqlSession.close();
      13. }

      注意:

              使用Param注解后,arg不可以再使用,但是Param可以使用,但是没有比要,都已经命名啦,还使用没有注解的方式不是多此一举嘛。

      6、 返回map集合:

              主要是针对查询出来的数据没有封装类的数据,用来存储到map集合里面。

      (1)单个map:

      mapper接口方法:

      1. //使用map集合返回参数
      2. Map selectByIdReturnMap(Long id);

      mapper映射文件:

      1. <select id="selectByIdReturnMap" resultType="java.util.Map">
      2. select id,
      3. brand,
      4. car_num as carNum,
      5. guide_price as guidingPrice,
      6. car_type as carType,
      7. produce_time as produceTime
      8. from t_car
      9. where id = #{id}
      10. select>

      测试类:

      1. //使用集合接收参数
      2. @Test
      3. public void test10(){
      4. SqlSession sqlSession = SqlSessionUtil.openSession();
      5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
      6. Map stringObjectMap = mapper.selectByIdReturnMap(179L);
      7. System.out.println(stringObjectMap);
      8. sqlSession.close();
      9. }
      (2)多个map:

       mapper接口方法:

      1. //获取多个map
      2. List> selectByPriceReturnListMap(Double price);

      mapper映射文件:

      1. <select id="selectByPriceReturnListMap" resultType="java.util.Map">
      2. select id,
      3. brand,
      4. car_num as carNum,
      5. guide_price as guidingPrice,
      6. car_type as carType,
      7. produce_time as produceTime
      8. from t_car
      9. where guide_price > #{price}
      10. select>

      测试类:

      1. //返回多个map
      2. @Test
      3. public void test11(){
      4. SqlSession sqlSession = SqlSessionUtil.openSession();
      5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
      6. List> list = mapper.selectByPriceReturnListMap(10.0);
      7. System.out.println(list);
      8. list.forEach(map -> {
      9. System.out.println(map);
      10. });
      11. sqlSession.close();
      (3)返回Map

        mapper接口方法:

      1. //返回信息为map存储信息 map的key是每条记录的主键,value 是每一条数据(map)
      2. @MapKey("id")//将查询结果的id值作为大map的key
      3. Map> selectAllReturnMapMap(Double price);

      mapper映射文件:

      1. <select id="selectAllReturnMapMap" resultType="java.util.Map">
      2. select id,
      3. brand,
      4. car_num as carNum,
      5. guide_price as guidingPrice,
      6. car_type as carType,
      7. produce_time as produceTime
      8. from t_car
      9. where guide_price > #{price}
      10. select>

      测试类:

      1. //返回多个map
      2. @Test
      3. public void test12(){
      4. SqlSession sqlSession = SqlSessionUtil.openSession();
      5. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
      6. Map> longMapMap = mapper.selectAllReturnMapMap(10.0);
      7. System.out.println(longMapMap);
      8. sqlSession.close();
      9. }

       总结:

              这里使用了@MapKey 的注解,使用这个的好处就是将查询结果的id值作为大Map的key,然后将其他的查询的结果作为map,Map>

      7、resultMap结果映射:

      查询结果的列名和java对象的属性名对应不上怎么办?

      • 第一种方式:as 给列起别名
      • 第二种方式:使用resultMap进行结果映射
      • 第三种方式:是否开启驼峰命名自动映射(配置settings)

              第一种方式的话已经写过啦,就不在这里进行叙述啦,然后下面就主要说明后面两种方式的使用方式。

      (1)resultMap进行结果映射
      1. <resultMap id="carResultMap" type="com.songzhishu.mybatis.pojo.Car">
      2. <id property="id" column="id"/>
      3. <result property="carNum" column="car_num"/>
      4. <result property="brand" column="brand" javaType="string" jdbcType="VARCHAR"/>
      5. <result property="guidingPrice" column="guide_price"/>
      6. <result property="produceTime" column="produce_time"/>
      7. <result property="carType" column="car_type"/>
      8. resultMap>

      解决方法就是在配置文件中配置resultMap ,然后就是使用

      1. <select id="selectAllUseResultMap" resultMap="carResultMap">
      2. select * from t_car
      3. select>

      这时候不在使用resultType而是使用resultMap。

      (2)开启驼峰命名自动映射:

              使用这种方式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。

      Java命名规范:首字母小写,后面每个单词首字母大写,遵循驼峰命名方式。

      SQL命名规范:全部小写,单词之间采用下划线分割。

    12. 相关阅读:
      BSCNews报告:Sui网络近期数据激增,生态发展良好
      玩玩“小藤”开发者套件 Atlas 200I DK A2 之VSCode远程连接
      Windows环境MySQL8忘记密码文件解决方案
      如何通过API接口获取item_get - 获得淘宝商品详情
      Java后端获取当前项目所在路径的方法(适用于Linux、Windows)
      java8:Collector集合方法
      PHP将word文件转为图片预览
      Ubuntu18.04搭建OpenGrok代码搜索工具
      C++中内存泄漏和智能指针
      html--心花怒放
    13. 原文地址:https://blog.csdn.net/keleID/article/details/133756831