Java开发笔记

Mybatis项目的构建过程#

项目总目录

项目的代码参考https://github.com/KeeyC/MybatisStart

初步构建步骤#

  1. 导入项目所需的依赖

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.2</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </dependency>
    
    </dependencies>
    
  2. 编写mybatis核心配置文件applicationCongfig.xml

    <?xml version="1.0" encoding="UTF8" ?>
    <!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.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/Student?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
    
            </environment>
        </environments>
    
    <mappers>
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>
    
    </configuration>
    

    需要注意的是resource不要写错⚠️

  3. 根据官方文档https://mybatis.org/mybatis-3/zh/getting-started.html编写mybatis的工具类StudentMapperUtil

    package com.example.StudentMapperUtils;
    
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class StudentMapperUtil {
        private static SqlSessionFactory sqlSessionFactory;
    
        static{
            try {
                String resource = "applicationConfig.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }//获取sqlSession
    
    
    
    }
    
  4. 编写实体类--对应数据库

    通过lombok简化代码

    package com.example.User;
    
    
    import lombok.Data;
    
    import java.sql.Timestamp;
    
    @Data
    public class Student {
        private Long id;
        private String name;
        private int age;
        private String address;
        private Timestamp creat_time;
    }
    
    
  5. 编写Mapper接口

    package com.example.Mapper;
    
    import com.example.User.Student;
    
    import java.util.List;
    
    public interface StudentMapper {
        List<Student> getStudentList();
    }
    
    
  6. 编写Mapper.xml文件,可以放在Mapper层,也可以放在resources层

    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.Mapper.StudentMapper">
        <select id="getStudentList" resultType="com.example.User.Student">
            select * from Student
        </select>
    </mapper>
    

    select id="xxx",xxx的内容对应了Mapper接口中的方法名,注意命名空间对应了StudentMapper类

  7. 编写测试类进行测试

    package com.example;
    
    
    import com.example.User.Student;
    import com.example.Mapper.StudentMapper;
    import com.example.StudentMapperUtils.StudentMapperUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.util.List;
    
    public class TestStudent {
        @Test
        public void test(){
            SqlSession sqlSession= StudentMapperUtil.getSqlSession();
    
            StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class);
            List<Student> studentList=studentMapper.getStudentList();
            for(Student student:studentList){
                System.out.println(student);
            }
    
        }
    }
    

    --------------到此一个简单的mysql的查询功能已经实现----------------

CRUD操作#

Select操作#

在select操作中有很多属性来配置SQL

最常用的三个

  • id:接口中的方法名与id一一对应,即id对应Mapper接口中的方法

  • parameterType: 传入SQL语句中过的参数类型

  • resultType: SQL语句的返回值类型,一般为类名或其别名

查询可以像上面 所写的查询所有的,也可以设置条件查询,不如通过id查询甚至通过map来查询。

<select id="selectStudentListById" parameterType="Long" resultType="Student">
        select * from Student WHERE id=${id}
    </select>
    <select id="selectStudentByMap" parameterType="map" resultType="Student">
        select * from Student WHERE name=#{username} and id=#{id}
    </select>

如上是xml文件中SQL语句的编写。

还有一种操作是模糊查询,与精准查询相反,模糊查询可设置查询名字中的部分字或者字符串中的部分符号,比如:

查询名字中带字符i的Student

  <!--模糊查询-->
    <select id="selectLike" resultType="Student">
        select * from Student WHERE name like #{mingzi}
    </select>
/*
        模糊查询
     */
    @Test
    public void testSelectLike(){
        String name="%i%";
        SqlSession sqlSession=mapperUtils.getSqlSession();
        studentMapper=sqlSession.getMapper(StudentMapper.class);
       List<Student> studentList= studentMapper.selectLike(name);
        for (Student students:studentList
        ) {System.out.println(students);
        }
    }

查询结果

Delete操作#

根据id进行删除

 <select id="deleteStudentById" parameterType="Long" >
        delete from Student Where id=#{id}
    </select>

Update操作#

根据id进行更新

 <select id="updateStudent" parameterType="Student" >
        update  student set name=#{name},address=#{address} WHERE id=#{id}
    </select>

Insert操作#

将student以map类型插入表中

<select id="insertStudent" parameterType="map">
        INSERT INTO Student (id,name,age,address)VALUES (#{id},#{name},#{age},#{address})
    </select>

Mybatis的配置问题#

由官方文档,Mybatis配置文档的顶层结构如下:

环境配置(environments)#

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。官方文档中这样写:

在实际操作中,代码为:

 private static SqlSessionFactory sqlSessionFactory;
  static {
      try {
          String resource = "mybatis-config.xml";
          InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

enviroments元素定义了如何配置环境

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

注意一些关键点:

  • 默认使用的环境 ID(比如:default="development")。
  • 每个 environment 元素定义的环境 ID(比如:id="development")。
  • 事务管理器的配置(比如:type="JDBC")。
  • 数据源的配置(比如:type="POOLED")。

默认环境和环境 ID 顾名思义。 环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。

属性(properties)#

即可包含数据库的一些属性信息

  1. 现在resources目录下创建一个xxx.properties文件,然后在上面写上数据库所需要的配置信息

    url=jdbc:mysql://localhost:3306/Student?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    driver=com.mysql.cj.jdbc.Driver
    name=root
    password=123456key
    
  2. 然后在mybatis-config.xml文件中导入properties配置文件

      <properties resource="dateBase.properties"></properties>
    

    resource名字要与配置文件名字一致。

类型别名(typeAliases)#

类型别名可以为java类型提供一个缩写的名字,仅用于xml文件中的配置。例如在项目中编写SQL语句时,有时resultType="com.example.User.Student",如果每次都这样写十分的麻烦,可以为com.example.User.Student设置一个别名,这样就可以简化开发

<typeAliases>
    <typeAlias alias="Student" type="com.example.User.Student"/>
</typeAliases>

这一段代码时写在mybatis-config.xml文件中的

同样也可以指定一个包名,mybatis会在其包名下面搜索所需要的java Bean,比如

<typeAliases>
 <package name="com.example.User"/>
  <typeAliases></typeAliases>

这样每一个在包com.example,User中的java Bean,都可以直接使用Bean的首字母小写的非限定类名作为它的别名。比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:

@Alias("author")
public class Author {
    ...
}

更多的java类型内建的类型别名参照Mybatis官方文档

设置(settings)#

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

一个配置完整的settings元素的实例如下:

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

具体内容参照Mybatis官方文档

生命周期#

作用域理解

  • SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,而不要让其长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
  • SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。
  • 由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。
  • 因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域。
  • 如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try…catch…finally… 语句来保证其正确关闭。
  • 所以 SqlSession 的最佳的作用域是请求或方法作用域。

关于junit测试#

  • 如果使用org.junit.Test,则必须配合@RunWith(SpringRunner.class)(org.junit.runner.RunWith)(org.springframework.test.context.junit4.SpringRunner)才能完成注入
  • 如果使用的org.junit.jupiter.api.Test(需使用spring-boot-starter-test依赖),完成正常注入。

关于连接mysql时的配置问题#

  • 连接mysql数据库时,mysql8的驱动配置设置为com.mysql.cj.jdbc.Driver

  • 连接mysql数据库时,mysql的url应设置为jdbc:mysql://localhost:3306/数据库名?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8"

  • 若碰到

    Cause: java.lang.ClassNotFoundException: Cannot find class: com.mysql.cj.jdbc.Driver
    

    的报错,则错误原因是没有导入mysql的依赖,导入mysql的依赖即可。

Mybatis项目中xml文件的注册问题#

在mybatis项目构建的过程中,先后碰到了ExceptionInInitializerErrorType interface xxxx is not known to the MapperRegistry问题,我的具体操作步骤是:

  • StudentMapper.xml文件移到了resources目录下面,其实不移动好像也可以

  • 然后mapper的命名空间从<mapper namespace="com.example">改成了<mapper namespace="com.example.Mapper.StudentMapper">,然后在applicationConfig.xml文件末尾加上了

  • <mappers>
        <mapper resource="StudentMapper.xml"/>
    </mappers>
    

    这步操作解决了Type interface. xxx is not known to the MapperRegistry的问题

  • 一般将xml文件放到resources目录下后,经过如上的操作问题基本解决了,如果还没有解决或者mapper.xml文件放在java目录下,可以尝试在pom.xml中添加

  • <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
    
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
    
        </resources>
    </build>
    

父项目和子项目中都要添加,添加后记得刷新maven.

Swagger启动时碰到的问题#

如果Springboot即成swagger后出现了:Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

可以尝试在启动类上增加一个注解:@EnableWebMvc

Springboot#

java注解:#

  • @Controller :对应Spring MVC控制层,主要用户接受用户请求并调用Service层返回数据给前端界面。
  • @Respository :对应持久层即Dao层,主要用于数据库相关操作。
  • @Autowired :自动导入对象到类中,被注入的类同样也要被Spring容器管理。
  • @ComponentScan: 扫描被@Component(@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
  • @Configuration:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类
  • @RestController :@RestController注解是@Controller@ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值直 接填入 HTTP 响应体中,是 REST 风格的控制器。
  • @Configuration :一般用于声明配置类,可以用@Component注解替换。

前后端传值:

  • @PathVariable@RequestParam
    @PathVariable用于获取路径参数,@RequestParam用于获取查询参数。

    @GetMapping("/klasses/{klassId}/teachers")
    public List<Teacher> getKlassRelatedTeachers(
             @PathVariable("klassId") Long klassId,
             @RequestParam(value = "type", required = false) String type ) {
    ...
    }
    
  • @RequestBody :用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的 body 中的 json 字符串转换为 java 对象。

  • @ConfigurationProperties :通过@ConfigurationProperties读取配置信息并与bean绑定。

  • @RequestMapping :URL的映射。

ResponseEntity#

  @AuthenticationPrincipal User user) {
    return ResponseEntity.ok(articleQueryService.findUserFeed(user, new Page(offset, limit)));
  }

ResponseEntity标识整个http响应:状态码,头部信息以及相应体内容

多模块配置问题#

  • 多模块开发下,在创建子模块后,若访问接口404则需要检查模块依赖是否正确
  • ![image-20220909191644783](/Users/criskey/Library/Application Support/typora-user-images/image-20220909191644783.png)
    碰到这个问题时,检查目录名称

关闭8080端口#

lsof -i tcp:8080   //查看8080端口的PID

Kill PID //根据PID关闭进程

当直接导入jar包出现程序包不存在情况解决#

当在引入百度的ocr识别时发现程序包找不到

java:程序包com.baidu.api.ocr不存在

解决方法:

作者:KeySv

出处:https://www.cnblogs.com/cc-coding/p/16690036.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   我只有一天的回忆  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu