实训Day04

学习目标

数据持久层操作

1.复习JDBC(Java DataBase Connectivity)

​ java操作数据库的基本规范(API)

2.Spring整合Mybatis

3.SpringBoot整合Mybatis Plus

今日所学

更新项目目录

在这里插入图片描述

JDBC

Connection:连接接口

Statement:命令对象

PreparedStatement:预编译命令

ResultSet:结果集对象

public class JdbcDemo{
  Connection connection;
  PreparedStatement preparedStatement;
  
  @Before
  public void init(){
        
    //创建驱动

    Class.forName("com.sql.cj.jdbc.Driver");
    
    //建立连接
    String url = "";
    String username = "root";
    String password = "12345678";
    connection = DriverManager.getConnection(url,username,password);
  }
  
  /**
  *单元测试Junit
  */
  @Test
  public void Update() throws Exception{
    
    preparedStatement = connection.prepareStatement("insert into tb_**() values(?,?,?)");
    preparedStatement.setObject();
    
    int i = preparedStatement.executeUpdate();//修改
    System.out.println("影响的行数:"+i);
  }
}

DataSource

数据源

把URL+username+password封装

类型

数据源

定义位置

定义在javax.sql包

为什么要引入数据源对象

因为Spring框架的使用,用于管理bean

Spring通过对于DataBase类型的bean的创建和管理,完成对mysql数据库的连接

@Test
public void testDataSource(){
  MysqlDatasource mysqlDatasource = new MysqlDatasource();
  mysqlDatasource.setUrl(url);
  mysqlDatasource.setUser(username);
  mysqlDatasource.setPassword(password);
  
  Connection connection = mysqlDatasource.getConnection();
}

为了简化和封装对于数据库的操作提出:DAO和ORM

DAO:Data Access Object 数据访问对象

ORM:Object Relation Mapping 对象关系映射

Mybatis:就是一个ORM框架,此外还有HibernateJPA Java Persistent API)

Mybatis使用流程

1.建立数据表和实体类之间的映射关系(两种方式)

配置文件方式
<resultMap>
	
</resultMap>

注释方式
@TableName(tb_user)
@TableId(value="id")
@TableField("name")

2.创建DAO的接口

UserMapper

public interface UserMapper{
	User getByid(Integer id);
	Liat<User> list;
	List<User> page(Integer page,Integer size);
	void inser(User);
}
//mybatis的核心应用
//sqlSessionFactoryBuilder -> sqlSessionFactory -> sqlSession
UserMapper userMapper = sqlSession.getMapper(userMapper.class);

@Test
public void testsqlSession(){
  SqlSession sqlSession = null;
  UserMapper userMapper = sqlSession.getMapper(userMapper.class);
}
<select id="getByid" paramterType="it">
	select * from tb_user where id = #{id}
</select>

<insert>
	...
</insert>

动态代理

分类

jdk动态代理和cglib动态代理

目标

​ 动态生成接口或抽象类(类)的实例,同时对目标方法进行增强

区别

​ jdk动态代理是java自己提供的动态代理方式,cglib是第三方方案

​ jdk动态代理代理的目标是接口,cglib代理目标是接口或类

​ jdk动态代理的核心是通过Proxy代理类,cglib动态代理的核心是Enhancer

通过SpringBoot整合Mybatis-Plus

Mybatis和Mybatis- Plus的关系

Mybatis是框架

Mybatis- Plus是基于框架之上的增强技术 https://baomidou.com

注意事项

1.必须基于mybatis才是mp

2.mp的配置和mybatis的配置完全一样

3.mp的dao也需要声明Mapper

4.mp针对单表的crud提供了大量的API

使用方法

1.导入依赖
//mp的核心依赖
<dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.4.2</version>
</dependency>
2.配置工作
#mybatis- plus的相关配置
mybatis-plus:
  configuration:
		#开启驼峰命名的自动转换:将数据库中的user_id自动匹配到java中的userId(但其实这样并不符合java中命名规范)
		map-underscore-to-camel-case: true
		#将mybatis的执行过程(sql)打印在控制台上
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    #当所有字段值都为NULL时返回空对象,User(id=null,name=null)
    return-instance-for-empty-row: true
	#mapper映射文件所在的位置
  mapper-locations: classpath*:mapper/**/*.xml
	#别名所在的包,可以简化class属性的声明过程
  type-aliases-package: com.gxa.agriculture.entity.pojo
3.数据库连接池配置
导入依赖
<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>1.1.18</version>
</dependency>
准备实体类

通过实体类建立与数据表的映射关系

@Data
@TableName("tb_user")
public class User implements Serializable {
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Integer id;

    @TableField("name")
    private String name;

    @TableField("phone")
    private String phone;

    @TableField("pwd")
    private String pwd;

    @TableField("points")
    private Integer points;

    @TableField("reg_time")
    private Date regTime;

    @TableField("deleted")
    private Boolean deleted;
}
准备Mapper

声明业务所需的Mapper接口,并基层Mp提供的BaseMapper父接口

public interface UserMapper extends BaseMapper<User> {
    
}
4.在Spring中声明@MapperScan

声明在主启动类中

@MapperScan(basePackages = "com.gxa.agriculture.mapper")
public class MainApp(){
  ...
}
5.测试UserMapper调用API
导入依赖

这样就可以使用@Test注解

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
测试代码
@SpringBootTest(classes = MainApp.class)
@RunWith(SpringRunner.class)
class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

  	//查询测试
    @Test
    public void testSelectById(){
        User user = userMapper.selectById(1);
        System.out.println(user);
    }
  
  	//删除测试
    @Test
    public void testDelete(){
        int i = userMapper.deleteById(100);
        System.out.println(i);
    }
  
  	//增加测试
    @Test
    public void testInsert(){
        User user = new User();
        user.setName("肖恩");
        user.setId(100);
        user.setPhone("1234321");
        user.setPwd("123456");
        int insert = userMapper.insert(user);
        System.out.println(insert);
    }
  
  	//修改测试
    @Test
    public void testUpdate(){
        User user = new User();
        user.setName("小羊肖恩");
        user.setId(100);
        user.setPhone("1234321");
        user.setPwd("123456");

        int i = userMapper.updateById(user);
        System.out.println(i);
    }
}

在这个测试类中,使用了Spring Framework的@SpringBootTest注解来指定要加载的Spring应用程序的主类MainApp,并使用@RunWith(SpringRunner.class)注解来指定使用Spring的测试运行器来运行测试。

  1. @SpringBootTest(classes = MainApp.class): 这个注解用于指定要加载的Spring应用程序的主类,即MainApp类。通过这个注解,测试类可以加载整个Spring应用程序上下文,以便在测试中能够使用Spring的依赖注入和其他功能。
  2. @RunWith(SpringRunner.class): 这个注解指定了使用Spring的测试运行器来运行测试。SpringRunner是Spring提供的一个JUnit运行器,用于在测试中提供Spring的功能支持,如依赖注入、事务管理等。
  3. @Autowired: @Autowired注解用于自动装配接口类型时,Spring会根据接口的实现类来注入实际的对象,从而实现依赖注入的功能。在这段代码中,UserMapper是一个接口,而具体的实现类(可能是通过MyBatis或其他ORM框架生成的)会在运行时被Spring容器实例化。通过@Autowired注解,Spring会自动查找UserMapper接口的实现类,并将其注入到测试类中的userMapper字段。这样,测试类就可以直接调用UserMapper接口中定义的方法来进行数据库操作,而无需关心具体的实现类是什么。

需要注意的是,UserMapper接口本身并不是一个实例化对象,而是一个接口定义,定义了对用户数据的操作方法。要让UserMapper接口的方法与数据库建立连接并执行相应的操作,通常需要使用ORM框架(如MyBatis)来提供具体的实现。在这种情况下,通过配置ORM框架,Spring会自动为UserMapper接口创建一个代理对象,该代理对象会实现UserMapper接口定义的方法,并与数据库进行交互。

因此,通过@Autowired注入的userMapper对象实际上是ORM框架生成的代理对象,通过这个代理对象可以调用UserMapper接口定义的方法(如getById()deleteById()等),从而与数据库进行交互。ORM框架会负责将方法调用转换为对应的SQL操作,并执行数据库操作。

综上所述,通过@Autowired注解注入UserMapper接口的实例化对象,实际上是通过ORM框架提供的代理对象与数据库建立连接,并可以使用UserMapper接口定义的方法来操作数据库。

可能存在的错误
使用@Autowired即可解决

在这里插入图片描述

使用@SpringBootTest(classes = MainApp.class)@RunWith(SpringRunner.class)解决

此外,需要注意的是因为我当时Junit依赖的版本的写的3.8.1,版本过低所以无法写@Runwith注释,所以需要提高pom.xml中Junit版本

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

在这里插入图片描述

拓展

了解Hibernate的特点

Hibernate是一个开源的对象关系映射(ORM)框架,它提供了将Java对象映射到关系型数据库表的功能,简化了在Java应用程序中操作数据库的过程。Hibernate具有以下特点:

  1. 简化数据库操作:Hibernate通过对象关系映射(ORM)的方式,将Java对象和数据库表进行映射,使得开发人员可以直接操作Java对象,而不需要编写复杂的SQL语句。

  2. 提供对象导航:Hibernate允许在对象之间建立关联关系,通过对象导航可以方便地访问和操作相关联的对象。

  3. 自动维护对象状态:Hibernate可以自动跟踪对象的状态(持久态、游离态、临时态),并在合适的时机同步到数据库中,简化了数据持久化的管理。

  4. 支持事务管理:Hibernate提供了事务管理功能,可以保证数据库操作的原子性、一致性、隔离性和持久性(ACID特性)。

  5. 支持缓存机制:Hibernate提供了一级缓存和二级缓存机制,可以提高数据库访问性能,减少数据库访问次数。

  6. 支持延迟加载:Hibernate支持延迟加载(Lazy Loading)机制,可以在需要时才加载相关联的对象,提高系统性能。

  7. 跨数据库平台:Hibernate支持多种数据库平台,可以在不同的数据库系统中使用相同的Hibernate代码。

  8. 提供查询语言HQL:Hibernate提供了Hibernate Query Language(HQL),类似于SQL语句,用于查询数据库中的数据,支持面向对象的查询。

Hibernate和Mybatis对比

Hibernate和MyBatis都是Java中常用的持久层框架,但它们在设计理念、使用方式和特点上有一些区别。下面是Hibernate和MyBatis的对比:

  1. 设计理念
    • Hibernate是一个全自动的ORM框架,它通过对象关系映射将Java对象和数据库表进行映射,开发人员可以直接操作Java对象,而不需要编写SQL语句。
    • MyBatis是一个半自动的ORM框架,它使用XML文件注解来配置SQL语句和映射关系,开发人员需要编写SQL语句,但可以更细粒度地控制SQL语句的执行。
  2. 灵活性
    • MyBatis相对于Hibernate更加灵活,开发人员可以自由地编写SQL语句,控制SQL的执行过程,适用于需要定制化SQL操作的场景。
    • Hibernate提供了更高级的抽象,隐藏了大部分SQL细节,适用于快速开发和简单的CRUD操作。
  3. 性能
    • MyBatis在性能上通常比Hibernate更好,因为开发人员可以优化SQL语句,避免不必要的查询,提高数据库访问效率。
    • Hibernate的自动化查询和关联处理可能会导致性能损失,特别是在处理复杂查询和大量数据时。
  4. 适用场景
    • MyBatis适用于需要定制SQL语句和对SQL有较高要求的场景,适合对SQL熟悉的开发人员。
    • Hibernate适用于快速开发和简单的CRUD操作,适合对对象关系映射和ORM概念熟悉的开发人员。
  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的C语言万年历的实训报告,供您参考: 一、实训目的 本次实训的主要目的是通过编写一个简单的C语言万年历程序,巩固C语言基本语法和编程思想,提高编程能力和解决问题的能力。 二、实训要求 1、能够使用C语言基本语法和控制语句编写程序。 2、能够使用数组来存储和操作数据。 3、能够使用函数来实现模块化编程。 4、能够使用指针来操作内存中的数据。 5、能够使用文件来读取和写入数据。 三、实训内容 1、程序功能 本程序实现了一个简单的万年历功能,可以通过输入年份和月份来显示该月的日历。 2、程序实现 以下是本程序的主要代码实现: ```c #include <stdio.h> // 判断是否为闰年 int is_leap_year(int year) { if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { return 1; } else { return 0; } } // 获取某个月份的总天数 int get_days(int year, int month) { int days[] = {31, 28 + is_leap_year(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; return days[month - 1]; } // 获取某个日期是星期几 int get_weekday(int year, int month, int day) { if (month == 1 || month == 2) { year--; month += 12; } int c = year / 100; int y = year % 100; int w = y + y / 4 + c / 4 - 2 * c + 26 * (month + 1) / 10 + day - 1; w = (w % 7 + 7) % 7; return w; } // 显示日历 void show_calendar(int year, int month) { int days = get_days(year, month); int weekday = get_weekday(year, month, 1); printf(" 日 一 二 三 四 五 六\n"); int i; for (i = 0; i < weekday; i++) { printf(" "); } for (i = 1; i <= days; i++) { printf("%2d ", i); if ((weekday + i) % 7 == 0) { printf("\n"); } } if ((weekday + days) % 7 != 0) { printf("\n"); } } int main() { int year, month; printf("请输入年份:"); scanf("%d", &year); printf("请输入月份:"); scanf("%d", &month); if (month < 1 || month > 12) { printf("月份输入错误!\n"); return 1; } printf(" %d年%d月\n", year, month); show_calendar(year, month); return 0; } ``` 四、实训总结 通过本次实训,我学会了如何使用C语言来编写一个简单的万年历程序,巩固了C语言基本语法和编程思想,加强了对函数、数组、指针、文件等概念和用法的理解,提高了编程能力和解决问题的能力。同时,我也意识到在编程过程中需要注重代码的规范、可读性和可维护性,这对于日后的开发工作非常重要。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值