SSM 后端开发纪要

目录

引言

技术栈

知识点

        接口

       Static类

实现

        Spring

        MyBatis

       SpringMVC

       SpringBoot

问题


引言

        最近需要完成一个管理系统后端的开发,大二暑期实训期间学了后端框架,包括springBoot、mybatis、spring、springMVC等。但是学时很短,仅仅是对老师的笔记中的简单示例进行了测试,对后端中Dao层、Service层、Controller层的理解不够深刻,这次通过实际项目对之前所学的后端知识进行巩固与提高,下面是对后端各个框架的基础的复习,可能有不太恰当的地方,如果某些内容与你的问题相符,但刚好我没说清楚,请留言,我将尽力为你解决,共同学习。

技术栈

        spring boot:专注于spring开发减少配置

        mybatis:持久层的、轻量级的半自动化ORM框架

        springMVC:基于JAVA实现MVC的轻量级Web框架。

知识点

        接口

        在JAVA中接口是一个公共的抽象类,只有方法的特征没有方法的实现。可以由多个类来实现它,并且这些实现可以具有不同的行为。为JAVA无法实现多继承提供一种解决手段。一个接口可以在多个地方实现

       Static类

        static表示静态或者全局的意思,被static修饰的可以是一个变量、一个类或者一段代码块,在java中没有全局变量的说法,被static修饰的成员变量或者成员方法独立于该类的任何对象,它不依赖于类的特定实例,被所有实例所共享,当一个类被创建时,便能够访问到它。

实现

        Spring

        一个轻量级的控制反转与面向切面编程的框架。

        尝试传统实现一个简单功能的方式,在Dao层创建一个功能实现的接口,再创建一个该接口的实现类,而后在Service层创建一个接口并创建它的实现类。需要使用时,需要实例化Service层的实现类,当需要执行另外一个操作时马上又需要实例化另外一个实现类,这样的方式非常繁琐。

// userDao的实现类
package dao.Impl;
import dao.userDao;
public class userDaoImpl implements userDao{
    @Override
    public void getUser() {
        System.out.println("取得用户");
    }
}
// userDao的接口
package dao;

public interface userDao {
    public void getUser();
}
// userService的实现类
package service.Impl;

import dao.Impl.userDaoImpl;
import dao.userDao;
import service.userService;

public class userServiceImpl implements userService {
    private userDao userDao = new userDaoImpl();
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// userService的接口
package service;

public interface userService {
    public void getUser();
}

        如果我们尝试在Service的实现类中留出一个接口,而不是具体地实现某个功能,便能带来较大的便捷。

// 在service实现类中设置一个接口
package service.Impl;

import dao.Impl.userDaoImpl;
import dao.userDao;
import service.userService;

public class userServiceImpl implements userService {
//    该方式过度的耦合,使用set方式流出一个接口
//    private userDao userDao = new userDaoImpl();
    private userDao userDao;

    public void setUserDao(userDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// 当需要使用到某个功能的时候,直接将Dao层的实现类传入之前留出的接口
import dao.Impl.userDaoImpl;
import dao.Impl.userDaoMysqlImpl;
import service.Impl.userServiceImpl;
import service.userService;

public class Test {
    @org.junit.Test
    public void test(){
        // 先执行userDaoMysqlImpl
        userServiceImpl userService = new userServiceImpl();
        userService.setUserDao(new userDaoMysqlImpl());
        userService.getUser();

        // 此时又想执行另外一个功能
        userService.setUserDao(new userDaoImpl());
        userService.getUser();
    }
}

        通过set注入的方式,有效地解决了当使用数据层不同的功能时在Service层需要new不同的数据层的实现类,但是目前仍然存在只要使用数据层就要在服务层new一个实现类,当数据层改变时服务层也需要跟着改变,便调整由service主动new数据层的实现类为由外部提供Service层的需要,这便是控制反转(IOC)的思想。控制反转通过一个bean容器创建和初始化Dao层与Service层的类对象,虽然容器中有了Dao层与Service层的类对象,但是程序还不能执行,因为Service层提供服务需要依赖于Dao层,所以在bean容器中需要将Service层与Dao层建立依赖关系,这便是依赖注入(DI)。

// 添加spring依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

// 编写beans.xml文件
<bean id="hello" class="pojo.Hello" >
    <property name="name" value="spring"/>
</bean>

// 测试
@org.junit.Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

    Hello hello = (Hello) context.getBean("hello");

    System.out.println(hello.toString());

    hello.show();

}

        我们再将控制反转与依赖注入同时运用起来

<!--    依赖注入  -->
        <bean id="userDao" class="dao.Impl.userDaoImpl"/>
<!--    将userDaoService与userDao绑定   -->
        <bean id="userDaoService" class="service.Impl.userServiceImpl">
            <property name="userDao" ref="userDao"/>
        </bean>
// userServiceImpl通过set留出功能实现的接口 
package service.Impl;

import dao.Impl.userDaoImpl;
import dao.userDao;
import service.userService;

public class userServiceImpl implements userService {
//    该方式过度的耦合,使用set方式流出一个接口
//    private userDao userDao = new userDaoImpl();
    private userDao userDao;

    public void setUserDao(userDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// 测试
    @org.junit.Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        userServiceImpl userService = (userServiceImpl)context.getBean("userDaoService");
        userService.getUser();
    }
        MyBatis

         mybatis针对持久层的一个框架,回忆一下,传统操作数据的方式大概如下,配置连接数据库、使用sql语句执行具体的操作、封装结果使用对象承接,这些操作都需要自己手动完成。而mybatis能够大大简化这些操作,通过下面两幅图片对边便能感觉到mybatis的方便。

        编写实体类

public class User {
    private long id;
    private String username;
    private String password;
    private String name;
    private String phone;
    private String head_url;
    private long dept_id;
    private long post_id;
    private String description;
    private int status;
    private Date create_time;
    private Date update_time;
    private int is_deleted;
    public User (){

    }
    public User(long id, String username, String password, String name, String phone, String head_url, long dept_id, long post_id, String description, int status, Date create_time, Date update_time, int is_deleted) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.name = name;
        this.phone = phone;
        this.head_url = head_url;
        this.dept_id = dept_id;
        this.post_id = post_id;
        this.description = description;
        this.status = status;
        this.create_time = create_time;
        this.update_time = update_time;
        this.is_deleted = is_deleted;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getHead_url() {
        return head_url;
    }

    public void setHead_url(String head_url) {
        this.head_url = head_url;
    }

    public long getDept_id() {
        return dept_id;
    }

    public void setDept_id(long dept_id) {
        this.dept_id = dept_id;
    }

    public long getPost_id() {
        return post_id;
    }

    public void setPost_id(long post_id) {
        this.post_id = post_id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    public Date getUpdate_time() {
        return update_time;
    }

    public void setUpdate_time(Date update_time) {
        this.update_time = update_time;
    }

    public int getIs_deleted() {
        return is_deleted;
    }

    public void setIs_deleted(int is_deleted) {
        this.is_deleted = is_deleted;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", head_url='" + head_url + '\'' +
                ", dept_id=" + dept_id +
                ", post_id=" + post_id +
                ", description='" + description + '\'' +
                ", status=" + status +
                ", create_time=" + create_time +
                ", update_time=" + update_time +
                ", is_deleted=" + is_deleted +
                '}';
    }
}

        编写Dao接口

public interface userDao {
    List<User> getUserList();
}

        编写mapper具体实现 

<mapper namespace="dao.userDao">
    <select id="getUserList" resultType="pojo.User">
        select * from user;
    </select>
</mapper>

        在mybatis-config.xml核心配置文件中注册

    <mappers>
        <mapper resource="dao/mapper/userDaoMapper.xml"></mapper>
    </mappers>

         创建一个sqlSessionFacrory工具类

public class MybatisUtils {
    // 定义一个工厂
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            // 使用mybatis获取sqlsessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

         测试

    public void test4(){
        // 获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 执行sql
        userDao mapper = sqlSession.getMapper(userDao.class);
        List<User> userList = mapper.getUserList();
        userList.forEach(System.out::println);
        // 关闭sqlSession
        sqlSession.clearCache();
    }
       SpringMVC

        使用内置的tomcat无法启动,后面再解决

       SpringBoot

        springboot只需要极少量的配置,便能够运行起来一个web程序。

<properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
​
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

        主启动

@SpringBootApplication
public class SpringBoot01Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBoot01Application.class, args);
    }
}

        控制类

@RestController   //  @Controller  + @ResponseBody
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping("/h1")
    public String hello(){
        return "Hello~ SpringBoor,你用起来真的太香了";
    }


}

问题

        1. idea连接阿里云mysql数据库,使用idea自动下载数据库连接驱动,下载不下来,主机使用了代理,但是idea没有设置,所以还是会很慢,使用auto detect proxy 解决了。猜测使用该设置后idea会自动寻找主机的代理。

        2. idea使用kotlin,交付过来的后端代码idea的版本是23版本的,默认的kotlin为1.9x版本,在maven中也是设置也是1.9。我的idea是21版本,最高支持1.6版本,尝试将maven中的关于kotlin的版本的配置降低,发现并不管用,显示mybatis中有依赖与1.9版本的kotlin,于是尝试安装idea23版本,再次装在maven配置。可能也是需要配置idea代理,虽然在maven中设施了使用阿里云的maven仓库,但是还是速度很慢,挂了2小时后终于下载完成了。

         3. 配置mybatis出现:

                (1)org.apache.ibatis.binding.BindingException: Type interface dao.userDao is not known to the MapperRegistry.

                出现这种问题大概是因为没有在mybatis-config.xml中注册userDaoMapper.xml

                (2)Caused by: java.io.IOException: Could not find resource com/lxyk/dao/UserMapper.xml,这个报错很可能有两种原因,一个是设置的Pojo类或者Dao类的路径不对,还有一种原因就是没有在pom.xml中加入下面的这段代码。

    <!--在build中配置resources  来防止我们资源导出失败的问题-->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>

        4. 使用Spring Boot启动最简单的web,配置好了启动类以及需要访问的控制类,但是一直出现Whitelabel Error Page,查阅资料发现是启动类与控制类不在同一个包下,如果不使用@ComponentScan就会出现启动类找不到控制类的情况。下面呈现正确的组织方式,两个类需要在同一个主包下面。

        也可以在启动类使用@ComponentScan("控制类的路径")

猜你喜欢

转载自blog.csdn.net/2201_75875170/article/details/133901505
ssm