我亏一点 - Java
type: channel
link: https://000081.xyz/index.php/category/Java/
items: Java MyBatis实体类属性名与数据库字段表名称不一致解决办法
items: Java MyBatis代理开发
items: Java MyBatis快速入门
items: Java Spring IoC整体流程总结
items: Java Spring 生命周期
items: Java Spring Bean工厂后处理器
items: Java Spring Bean实例化的基本流程
items: Java Spring 配置非自定义Bean
items: Java Spring 获取Bean的三种方式
items: Java Spring beans的profile属性切换环境

Java MyBatis实体类属性名与数据库字段表名称不一致解决办法
type: item
date: 2023-03-12T10:35:18+00:00
description: AI摘要 MyBatis解决实体类属性名与数据库字段名不一致问题有两种方法。一是查询时使用别名，如`select 数据库字段 as 实体属性`，可结合SQL片段复用。二是使用`resultMap`进行映射，通过``将数据库字段映射到实体类属性。`resultMap`是更灵活且推荐的方式，尤其适用于复杂映射场景。 此内容根据文章生成，仅用于文章内容的解释与总结 MyBatis实体类属性名与数据库字段表名称不一致解决办法1. 查询字段时使用别名对不一样的列名起别名，让别名和实体类的属性名一样<mapper namespace="org.example.mapper.UserMapper"> select 数据库表字段名 as 实体类属性名 from user; </mapper>但是每次查询都需要重新定义一次别名使用sql片段的方式解决<mapper namespace="org.example.mapper.UserMapper"> <sql id="dataName"> 数据库表字段名 as 实体类属性名 </sql> select <include refid="dataName" /> from user; </mapper>但是此方法缺点不灵活2.使用resultMap映射别名<mapper namespace="org.example.mapper.UserMapper"> <resultMap id="dataName" type="user"> <id column="id" property="id"></id> <result column="数据库表字段名" property="实体类属性名"></result> </resultMap> select * from user; </mapper>id作为主键映射，result作为一般字段映射

Java MyBatis代理开发
type: item
date: 2023-03-12T09:00:00+00:00
description: AI摘要 MyBatis代理开发通过定义Mapper接口和SQL映射文件实现。首先，创建与SQL映射文件同名的Mapper接口，并置于同一目录。将SQL映射文件的namespace设为Mapper接口的全限定名。在Mapper接口中定义与SQL语句id对应的方法，保持参数和返回值类型一致。配置mybatis-config.xml加载Mapper。最后，通过SqlSession的getMapper方法获取Mapper接口的代理对象，调用其方法执行SQL。也可使用包扫描简化Mapper加载。 此内容根据文章生成，仅用于文章内容的解释与总结 MyBatis代理开发0. 环境准备User.javapackage org.example; public class User { private Integer id; private String username; private String password; public Integer getId() { return id; } public void setId(Integer 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 getAll(){ return "id=" + id + " username=" + username + " password=" + password; } } 1. 定义与SQL映射文件同名的Mapper接口，并且将Mapper接口和SQL映射文件放置在同一目录下创建UserMapper.java空接口创建UserMapper.xml文件(IDEA中resources创建目录使用/代替.)2. 设置SQL映射文件的namespace属性为Mapper接口全限定名UserMapper.xml<?xml version="1.0" encoding="UTF-8" ?> <mapper namespace="org.example.mapper.UserMapper"> select * from user; </mapper>3. 在Mapper接口中定义方法，方法名就是SQL映射文件中sql语句的id，并保持参数类型和返回值类型一致UserMapper.javapackage org.example.mapper; import org.example.User; import java.util.List; public interface UserMapper { List<User> selectAll(); }mybatis-config.xml<?xml version="1.0" encoding="UTF-8" ?> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/java?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/example/mapper/UserMapper.xml"/> </mappers> </configuration>4.编码：通过 SqlSession的 getMapper方法获取 Mapper接口的代理对象调…

Java MyBatis快速入门
type: item
date: 2023-03-10T06:49:00+00:00
description: AI摘要 本文介绍了Java MyBatis快速入门流程：包括数据库准备、Maven依赖配置、编写MyBatis核心及映射配置文件、创建实体类，并最终通过SqlSession实现数据库查询操作。 此内容根据文章生成，仅用于文章内容的解释与总结 MyBatis 快速入门1.数据库准备1.1 数据库信息地址端口用户名密码localhost3306rootroot1.2 创建java数据库create database java;1.3 创建user数据表并且添加数据SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名', `password` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `user_username_unique`(`username`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'admin', '1ed1252369b609c48a93ea80b57f52ed'); SET FOREIGN_KEY_CHECKS = 1; 2.Java Maven项目2.1 配置pom.xml <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.20</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.9</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.9</version> </dependency> </dependencies>2.2 在resources添加logback.xml文件（日志：可选）<?xml version="1.0" encoding="UTF-8"?> <configuration scan="false" scanPeriod="60 seconds" debug="false"…

Java Spring IoC整体流程总结
type: item
date: 2023-03-04T09:08:00+00:00
description: AI摘要 本文总结了Java Spring IoC的整体流程，重点涵盖了Spring Bean的基本实例化过程、BeanFactory后处理器的执行逻辑以及Bean生命周期的各个阶段。通过对核心环节的梳理，清晰展示了Spring容器管理Bean的完整机制。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring IoC整体流程总结1. 整体流程2. SpringBean基本实例化过程3. BeanFactory后处理器过程4. Bean生命周期阶段

Java Spring 生命周期
type: item
date: 2023-03-04T07:20:00+00:00
description: AI摘要 Spring Bean生命周期分为实例化、初始化和完成阶段。实例化后，在初始化阶段进行属性填充、Aware接口注入及BeanPostProcessor回调。针对循环依赖，Spring通过三级缓存机制解决。最终，完整Bean存入单例池完成生命周期。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring 生命周期1. 概述Spring Bean的生命周期是从 Bean 实例化之后，即通过反射创建出对象之后，到Bean成为一个完整对象，最终存储到单例池中，这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为三个阶段:Bean的实例化阶段: Spring框架会取出BeanDefinition的信息进行判断当前Bean的范围是否是sinaleton的是否不是延迟加载的，是否不是FactoryBean等，最终将一个普通的singleton的Bean通过反射进行实例化;Bean的初始化阶段: Bean创建之后还仅仅是个"半成品”，还需要对Bean实例的属性进行填充、执行一些Aware接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化init方法等。该阶段是Spring最具技术含量和复杂度的阶段，Aop增强功能，后面要学习的Spring的注解功能等spring高频面试题Bean的循环引用问题都是在这个阶段体现的:Bean的完成阶段: 经过初始化阶段，Bean就成为了一个完整的Spring Bean，被存储到单例池singletonObjects中去了，即完成了Spring Bean的整个生命周期2. 初始化阶段2.1 Bean的初始化阶段涉及过程Spring Bean的初始化过程涉及如下几个过程Bean实例的属性填充Aware接口属性注入BeanPostProcessor的before()方法回调InitializingBean接口的初始化方法回调自定义初始化方法init回调BeanPostProcessor的after()方法回调2.2 Bean实例属性填充Spring在进行属性注入时，会分为如下几种情况:注入普通属性，String、int或存储基本类型的集合时，直接通过set方法的反射设置进去;注入单向对象引用属性时，从容器中getBean获取后通过set方法反射设置进去，如果容器中没有，则先创建被注入对象Bean实例(完成整个生命周期)后，在进行注入操作;注入双向对象引用属性时，就比较复杂了，涉及了循环引用(循环依赖)问题2.2.1 propertyValuesBeanDefinition 中有对当前Bean实体的注入信息通过属性propertyValues进行了存储PersonDao.javapackage org.example; public interface PersonDao { }UserDao.javapackage org.example; public interface UserDao { }UserDaoImpl.javapackage org.example; public class UserDaoImpl implements UserDao { }PersonDaoImpl.javapackage org.example; public class PersonDaoImpl implements PersonDao{ public String getName() { return name; } public void setName(String name) { this.name = name; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } private String name; private UserDao userDao; } beans.xml<bean class="org.example.UserDaoImpl" id="userDao"/> <bean class="org.example.PersonDaoImpl" id="personDao"> <property name="userDao" ref="userDao"/> <property name="name" value="名字"/> </bean>主函数调用ClassPathXmlApplicationContext applicationContext = new ClassPathXml…

Java Spring Bean工厂后处理器
type: item
date: 2023-03-02T08:21:00+00:00
description: AI摘要 本文介绍了Spring两大核心扩展点：BeanFactoryPostProcessor用于在Bean实例化前动态修改或注册BeanDefinition；BeanPostProcessor则在Bean初始化前后介入，常用于属性填充或通过动态代理实现功能增强。两者为开发者提供了介入Bean生命周期的灵活机制。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring Bean工厂后处理器Spring的后处理器是Spring对外开发的重要扩展点，允许我们介入到Bean的整个实例化流程中来，以达到动态注册BeanDefinition，动态修改BeanDefinition，以及动态修改Bean的作用。Spring主要有两种后处理器:BeanFactoryPostProcessor: Bean工厂后处理器，在BeanDefinitionMap填充完毕，Bean实例化之前执行；BeanPostProcessor: Bean后处理器，一般在Bean实例化之后，填充到单例池singletonObjects之前执行。1. BeanFactoryPostProcessor1.1 快速入门BeanFactoryPostProcessor是一个接口规范，实现了该接口的类只要交由Spring容器管理的话，那么Spring就会回调该接口的方法，用于对BeanDefinition注册和修改的功能。实例化流程MyBeanFactoryPostProcessor.javapackage processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("beanDefinitionMap填充完毕后回调该方法"); } } beans.xml<bean class="processor.MyBeanFactoryPostProcessor"/>主函数断点调试public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); }执行结果beanDefinitionMap填充完毕后回调该方法1.2 强制修改BeanDefinition其他设置基于上文MyBeanFactoryPostProcessor.javapublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("beanDefinitionMap填充完毕后回调该方法"); BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition("userService"); beanDefinition.setBeanClassName("org.example.UserDaoImpl"); } }主函数调用public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml…

Java Spring Bean实例化的基本流程
type: item
date: 2023-02-28T03:00:00+00:00
description: AI摘要 Spring Bean实例化流程如下：首先解析配置文件，将Bean信息封装为BeanDefinition并存入beanDefinitionMap；随后容器遍历该Map，通过反射创建Bean实例并存入singletonObjects集合；最终调用getBean方法时，直接从singletonObjects中获取并返回对应的Bean实例。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring Bean实例化的基本流程Spring容器在进行初始化时，会将xml配置的<bean>的信息封装成一个BeanDefinition对象，所有的BeanDefinition存储到一个名为beanDefinitionMap的Map集合中去，Spring框架在对该Map进行遍历，使用反射创建Bean实例对象，创建好的Bean对象存储在一个名为singletonObjects的Map集合中，当调用getBean方法时则最终从该Map集合中取出Bean实例对象返回。流程：加载xml配置文件，解析获取配置中的每个<bean>的信息，封装成一个个的BeanDefinition对象将BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中;ApplicationContext底层遍历beanDefinitionMap，创建Bean实例对象 创建好的Bean实例对象，被存储到一个名为singletonObjects的Map<String,Object>中;当执行applicationContext.getBean(beanName)时，从singletonObjects去匹配Bean实例返回beans.xml <bean class="org.example.UserDaoImpl" id="userDao"/> <bean class="org.example.UserServiceImpl" id="userService"/>主函数断点调试运行 public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); }Bean信息定义对象-BeanDefinitionBeanDefinition.class// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.beans.factory.config; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.MutablePropertyValues; import org.springframework.core.AttributeAccessor; import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; void setParentName(@Nullable String var1); @Nullable String getParentName(); void setBeanClassName(@Nullable String var1); @Nullable String getBeanClassName(); void setScope(@Nullable String var1); @Nullable String getScope(); void setLazyInit(boolean var1); boolean isLazyInit(); void setDependsOn…

Java Spring 配置非自定义Bean
type: item
date: 2023-02-27T08:52:00+00:00
description: AI摘要 本文介绍了如何在Spring中配置非自定义Bean（第三方类）。通过Druid数据源、JDBC连接、日期对象及MyBatis的SqlSessionFactory等实例，展示了利用无参构造、静态工厂方法及实例工厂方法三种方式，实现第三方Bean的实例化与属性注入，从而将其纳入Spring容器管理。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring 配置非自定义Bean0.介绍实际开发中会使用第三方jar包中的功能类，这些Bean要想让Spring进行管理，也需要对其进行配置两个问题：被配置的Bean实例化方式是什么被配置的Bean是否需要注入必要属性1.配置Druid数据源交由Spring管理maven配置文件导入相应jar包pom.xml <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.23</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency>beans.xml <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/java"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean>主函数调用 public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); Object dataSource = applicationContext.getBean("dataSource"); System.out.println(dataSource); }运行结果{ CreateTime:"2023-02-26 17:23:51", ActiveCount:0, PoolingCount:0, CreateCount:0, DestroyCount:0, CloseCount:0, ConnectCount:0, Connections:[ ] }2.配置Connection交由Spring管理Connection的产生是通过DriverManager的静态方法getConnection获取的，所以我们要用静态工厂的方式配置beans.xml（getConnection报红不用管） <bean id="connection" class="java.sql.DriverManager" factory-method="getConnection" scope="prototype"> <constructor-arg name="url" value="jdbc:mysql://localhost:3306/java"/> <constructor-arg name="user" value="root"/> <constructor-arg name="password" value="root"/> </bean>主函数调用 public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); Object connection = applicationContext.getBean("connection"); System.out.println(connection);; }执行结果（报错不用管，看到有类字节码地址输出即可）com.mysql.jdbc.JDBC4Connection@42a15bdc3.配置日期对象交由Spring管理原生使用日期对象 Sim…

Java Spring 获取Bean的三种方式
type: item
date: 2023-02-26T09:03:00+00:00
description: AI摘要 本文介绍了在Java Spring框架中获取Bean的三种主要方式：一是通过ApplicationContextAware接口手动获取；二是通过注解@Autowired或@Resource进行自动注入；三是利用BeanFactory或ApplicationContext直接从容器中根据名称或类型检索Bean。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring 获取Bean的三种方式

Java Spring beans的profile属性切换环境
type: item
date: 2023-02-26T08:16:00+00:00
description: AI摘要 Spring通过在``标签中使用`profile`属性，可实现不同环境下的Bean配置切换。激活环境可通过命令行参数`-Dspring.profiles.active`或代码中设置`System.setProperty`实现，从而灵活加载特定环境所需的Bean。 此内容根据文章生成，仅用于文章内容的解释与总结 Java Spring beans的profile属性切换环境<beans>标签，除了经常用的作为根标签外，还可以嵌套在根标签内，使用profile属性切换开发环境可以使用以下两种方式指定被激活的环境（dev为环境名）：使用命令行动态参数，虚拟机参数位置加载 -Dspring.profiles.active=dev使用代码的方式设置环境变量System.setProperty("spring.profiles.active","dev")beans.xml <bean class="org.example.UserDaoImpl" id="userDao"/> <bean class="org.example.UserServiceImpl" id="userService"/> <beans profile="dev"> <bean id="userService1" class="org.example.UserServiceImpl"/> </beans> <beans profile="test"> <bean id="userDao1" class="org.example.UserDaoImpl"/> </beans>主函数调用 public static void main(String[] args) { // 指定环境 System.setProperty("spring.profiles.active","dev"); ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); System.out.println(((UserService) applicationContext.getBean("userService"))); System.out.println(((UserDao) applicationContext.getBean("userDao"))); System.out.println(((UserService) applicationContext.getBean("userService1"))); System.out.println(((UserDao) applicationContext.getBean("userDao1"))); }执行结果org.example.UserServiceImpl@589b3632 org.example.UserDaoImpl@45f45fa1 org.example.UserServiceImpl@4c6e276e Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDao1' available