JAVA学习笔记
文章目录
前言
本人java程序员小白一枚,内容解决的问题比较低级
Ⅰ.诸多问题以及解决方法
问题描述:导入文件乱码
解决方法:https://www.bilibili.com/video/BV1PY411e7J6?t=1466.3&p=61
一、字符流,字节流
1.文件写入时续写或者覆盖的问题
在学习字符流字节流的时候路径问题时常发生,目前作者只遇到几个的问题,所以只记录了几种情况的发生。
第一,BufferedWriter创建对象时不能直接赋值文件目录,需要在参数里面创建一个FileWriter
第二,如果想要写入时不涵盖以前的内容,需要在FileWriter里面创建文件目录的同时,后面也应该加上ture,格式为 new BufferedWriter(new FileWriter(“文件路径”,true)
2.文件路径中的 / 和 \ 的情况
两个写法运行都是正常,应该可以在文件路径中两者是一样的
二、servlet
1.tomcat同时运行多个模块
代码如下(示例):
点击加号就能自动添加新模块,但要求是同一个项目的
2.读入数据
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。
三.cookie
1.cookie属性
—
四. MySQL
1.事务
事务的隔离级别
修改数据库隔离级别
-- 标准语法
SET GLOBAL TRANSACTION ISOLATION LEVEL 级别字符串;
-- 修改数据库隔离级别为read uncommitted
SET GLOBAL TRANSACTION ISOLATION LEVEL read uncommitted;
-- 查看隔离级别
SELECT @@TX_ISOLATION; -- 修改后需要断开连接重新开
2.Mycat
①主从复制
- 主服务器的配置
-
在第一个服务器上,编辑mysql配置文件
// 编辑mysql配置文件
vi /etc/my.cnf// 在[mysqld]下面加上:
// log-bin代表开启主从复制,server-id代表主从服务器的唯一标识
log-bin=mysql-bin
server-id=1
innodb_flush_log_at_trx_commit=1
sync_binlog=1 -
查看主服务器的配置
// 重启mysql
service mysqld restart// 登录mysql
mysql -u root -p// 查看主服务的配置
show master status;
需要记住 File 列和 Position 列的数据,将来配置从服务器需要使用
- 从服务器的配置
-
在第二个服务器上,编辑mysql配置文件
// 编辑mysql配置文件
vi /etc/my.cnf// 在[mysqld]下面加上:
server-id=2 -
登录mysql
// 登录mysql
mysql -u root -p// 执行
use mysql;
drop table slave_master_info;
drop table slave_relay_log_info;
drop table slave_worker_info;
drop table innodb_index_stats;
drop table innodb_table_stats;
source /usr/share/mysql/mysql_system_tables.sql; -
重启mysql,重新登录,配置从节点
// 重启mysql
service mysqld restart// 重新登录mysql
mysql -u root -p// 执行
change master to master_host=‘192.168.59.143’,master_port=3306,master_user=‘root’,master_password=‘itheima’,master_log_file=‘mysql-bin.000001’,master_log_pos=154;// 开启从节点
start slave;// 查询结果
show slave status\G;
//Slave_IO_Running和Slave_SQL_Running都为YES才表示同步成功。 -
测试
在主服务器上创建一个db1数据库,查看从服务器上是否自动同步
四.JDBC
1.MySQL注入攻击解决方案
操作前
Connection conn = null;
Statement st = null;
ResultSet rs = null;
User user = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//2.定义SQL语句
String sql = "SELECT * FROM user WHERE loginname='"+loginName+"' AND password='"+password+"'";
System.out.println(sql);
//3.获取操作对象,执行sql语句,获取结果集
st = conn.createStatement();
rs = st.executeQuery(sql);
操作后(更改变量st和sql语句)
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
User user = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//2.定义SQL语句
String sql = "SELECT * FROM user WHERE loginname=? AND password=?";
//3.获取操作对象,执行sql语句,获取结果集
st = conn.prepareStatement(sql);
st.setString(1,loginName);
st.setString(2,password);
rs = st.executeQuery();
2.连接池动态代理
/*
类加载器:和被代理对象使用相同的类加载器
接口类型Class数组:和被代理对象使用相同接口
代理规则:完成代理增强的功能
*/
public Connection getConnection() throws SQLException {
if(pool.size() > 0) {
Connection con = pool.remove(0);
Connection proxyCon = (Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
/*
执行Connection实现类连接对象所有的方法都会经过invoke
如果是close方法,归还连接
如果不是,直接执行连接对象原有的功能即可
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("close")) {
//归还连接
pool.add(con);
return null;
}else {
return method.invoke(con,args);
}
}
});
return proxyCon;
}else {
throw new RuntimeException("连接数量已用尽");
}
}
五.MyBatis
1.SqlSession相关API
2.MyBatis 映射配置文件
①.查询功能
③.新增功能(增删改都需要将openSession改为true或者手动提交)
3.MyBatis核心配置文件
①.起别名
<typeAliases>
<typeAlias type="domain.Student" alias="student"/>
</typeAliases>
4.1 多表操作(配置文件实现)
!!!!
在xml配置文件中,一定要在mapper 后面加上namespace的地址!!!!
①.一对一
<mapper namespace="table01.OneToOneMapper">
<resultMap id="oneToOne" type="card">--这里的card小写是因为在起别名中将domain包里的所有类
<id column="cid" property="id"/> 都成为小写
<result column="number" property="number"/>
<association property="p" javaType="person">--在Card类中,定义了Person p
<id column="pid" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
</association>
</resultMap>
<select id="selectAll" resultMap="oneToOne">
SELECT c.id cid,number,pid,NAME,age FROM card c,person p WHERE c.pid=p.id
</select>
</mapper>
下面代码是MyBatisConfig.xml起别名
<typeAliases>
<package name="domain"/>
</typeAliases>
②.一对多
与一对一不同的是,一对一是,一对多和多对多都是。
③.多对多
4.2 多表操作(注解开发)
①.一对一
CardMapper接口的注解,这里还需要调用PersonMapper中的注解
//查询全部
@Select("SELECT * FROM card")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "number",property = "number"),
@Result(
property = "p",
javaType = Person.class,
column = "pid",
one=@One(select = "one_to_one.PersonMapper.selectById")
)
})
public abstract List<Card> selectAll();
将CardMapper中的pid作为PersonMapper中根据id查询的变量
//根据id查询
@Select("SELECT * FROM person WHERE id=#{id}")
public abstract Person selectById(Integer id);
并且还要在xml填写映射关系,这里制定"包路径"
<!--配置映射关系-->
<mappers>
<package name="one_to_one"/>
</mappers>
②.一对多
5.MyBatis接口代理方式实现
6.MyBatis注解开发
StudentMapper接口的方法
@Select("SELECT * FROM student")
public abstract List<Student> selectAll();
xml中的代码
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心根标签-->
<configuration>
<!--引入数据库连接的配置文件-->
<properties resource="jdbc.properties"/>
<!--配置LOG4J-->
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
<!--起别名-->
<typeAliases>
<package name="domain"/>
</typeAliases>
<!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
<environments default="mysql">
<!--environment配置数据库环境 id属性唯一标识-->
<environment id="mysql">
<!-- transactionManager事务管理。 type属性,采用JDBC默认的事务-->
<transactionManager type="JDBC"></transactionManager>
<!-- dataSource数据源信息 type属性 连接池-->
<dataSource type="POOLED">
<!-- property获取数据库连接的配置信息 -->
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!--配置映射关系-->
<mappers>
<package name="mapper"/>
</mappers>
</configuration>
测试类中的代码
@Test
public void selectAll() throws IOException {
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = mapper.selectAll();
for (Student student : list) {
System.out.println(student);
}
is.close();
sqlSession.close();
}
MyBatis构建SQL语句
六.Redis
1.key常用指令
pttl指令返回的为毫秒值,ttl指令返回的是秒。
2.jedis
idea配置jedis变量时,应该将redis的conf配置文件的bind改成虚拟机的网络地址,并且重启redis
3.缓存穿透,缓存击穿,缓存雪崩
①.缓存穿透
问题描述:redis命中率降低,查询不到数据库
出现很多非正常的url访问
解决方法:
②.缓存击穿
问题描述:key对应的数据存在,但在redis中过期。此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮
问题情景:1.数据库访问压力瞬间增加
2.redis里面没有出现大量key过期
3.redis正常运行
解决方法:
③.缓存雪崩
4.分布式锁
UUID解决锁误删,在锁的添加语句中增加一个uuid,每次解锁的时候都要先和uuid比较,是自己的uuid才可以解锁
LUA脚本保证删除的原子性:先判断uuid是否一致,一致则调用lua脚本
七.maven
八.Spring
1.常用注解
2.2)bean的定义
-
名称:@Component @Controller @Service @Repository
-
类型:类注解
-
位置:类定义上方
-
作用:设置该类为spring管理的bean
-
范例:
@Component public class ClassName{}
-
说明:
- @Controller、@Service 、@Repository是@Component的衍生注解,功能同@Component
-
相关属性
- value(默认):定义bean的访问id
2.3)bean的作用域
-
名称:@Scope
-
类型:类注解
-
位置:类定义上方
-
作用:设置该类作为bean对应的scope属性
-
范例:
@Scope public class ClassName{}
-
相关属性
- value(默认):定义bean的作用域,默认为singleton
2.4)bean的生命周期
-
名称:@PostConstruct、@PreDestroy
-
类型:方法注解
-
位置:方法定义上方
-
作用:设置该类作为bean对应的生命周期方法
-
范例:
@PostConstruct public void init() { System.out.println("init..."); }
2.5)加载第三方资源
-
名称:@Bean
-
类型:方法注解
-
位置:方法定义上方
-
作用:设置该方法的返回值作为spring管理的bean
-
范例:
@Bean("dataSource") public DruidDataSource createDataSource() { return ……; }
-
说明:
-
因为第三方bean无法在其源码上进行修改,使用@Bean解决第三方bean的引入问题
-
该注解用于替代XML配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态或非静态
-
@Bean所在的类必须被spring扫描加载,否则该注解无法生效
-
-
相关属性
- value(默认):定义bean的访问id
2.6)bean的非引用类型属性注入
-
名称:@Value
-
类型:属性注解、方法注解
-
位置:属性定义上方,方法定义上方
-
作用:设置对应属性的值或对方法进行传参
-
范例:
@Value("${jdbc.username}") private String username;
-
说明:
-
value值仅支持非引用类型数据,赋值时对方法的所有参数全部赋值
-
value值支持读取properties文件中的属性值,通过类属性将properties中数据传入类中
-
value值支持SpEL
-
@value注解如果添加在属性上方,可以省略set方法(set方法的目的是为属性赋值)
-
-
相关属性
- value(默认):定义对应的属性值或参数值
2.7)bean的引用类型属性注入
-
名称:@Autowired、@Qualifier
-
类型:属性注解、方法注解
-
位置:属性定义上方,方法定义上方
-
作用:设置对应属性的对象或对方法进行引用类型传参
-
范例:
@Autowired(required = false) @Qualifier("userDao") private UserDao userDao;
-
说明:
- @Autowired默认按类型装配,指定@Qualifier后可以指定自动装配的bean的id
-
相关属性
- required:定义该属性是否允许为null
2.8)bean的引用类型属性注入
-
名称:@Primary
-
类型:类注解
-
位置:类定义上方
-
作用:设置类对应的bean按类型装配时优先装配
-
范例:
@Primary public class ClassName{}
-
说明:
-
名称:@Inject、@Named、@Resource
-
说明:
- @Inject与@Named是JSR330规范中的注解,功能与@Autowired和@Qualifier完全相同,适用于不同架构场景
- @Resource是JSR250规范中的注解,可以简化书写格式
-
@Resource相关属性
-
name:设置注入的bean的id
-
type:设置注入的bean的类型,接收的参数为Class类型
-
2.10)加载properties文件
-
名称:@PropertySource
-
类型:类注解
-
位置:类定义上方
-
作用:加载properties文件中的属性值
-
范例:
@PropertySource(value = "classpath:filename.properties") public class ClassName { @Value("${propertiesAttributeName}") private String attributeName; }
-
说明:
- 不支持*通配格式,一旦加载,所有spring控制的bean中均可使用对应属性值
-
相关属性
-
value(默认):设置加载的properties文件名
-
ignoreResourceNotFound:如果资源未找到,是否忽略,默认为false
-
2.11)纯注解格式
-
名称:@Configuration、@ComponentScan
-
类型:类注解
-
位置:类定义上方
-
作用:设置当前类为spring核心配置加载类
-
范例:
@Configuration @ComponentScan("scanPackageName") public class SpringConfigClassName{ }
-
说明:
-
核心配合类用于替换spring核心配置文件,此类可以设置空的,不设置变量与属性
-
bean扫描工作使用注解@ComponentScan替代
-
AnnotationConfigApplicationContext
-
加载纯注解格式上下文对象,需要使用AnnotationConfigApplicationContext
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
2.12)第三方bean配置与管理
-
名称:@Import
-
类型:类注解
-
位置:类定义上方
-
作用:导入第三方bean作为spring控制的资源
-
范例:
@Configuration @Import(OtherClassName.class) public class ClassName { }
-
说明:
-
@Import注解在同一个类上,仅允许添加一次,如果需要导入多个,使用数组的形式进行设定
-
在被导入的类中可以继续使用@Import导入其他资源(了解)
-
@Bean所在的类可以使用导入的形式进入spring容器,无需声明为bean
-
3)bean加载控制
3.1)依赖加载
(1)@DependsOn
-
名称:@DependsOn
-
类型:类注解、方法注解
-
位置:bean定义的位置(类上或方法上)
-
作用:控制bean的加载顺序,使其在指定bean加载完毕后再加载
-
范例:
@DependsOn("beanId") public class ClassName { }
-
说明:
-
配置在方法上,使@DependsOn指定的bean优先于@Bean配置的bean进行加载
-
配置在类上,使@DependsOn指定的bean优先于当前类中所有@Bean配置的bean进行加载
-
配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载
-
-
相关属性
- value(默认):设置当前bean所依赖的bean的id
(2)@Order
-
名称:@Order
-
类型:配置类注解
-
位置:配置类定义的位置(类上)
-
作用:控制配置类的加载顺序
-
范例:
@Order(1) public class SpringConfigClassName { }
(3)@Lazy
-
名称:@Lazy
-
类型:类注解、方法注解
-
位置:bean定义的位置(类上或方法上)
-
作用:控制bean的加载时机,使其延迟加载
-
范例:
@Lazy public class ClassName { }
3.2)依赖加载应用场景
@DependsOn
-
微信订阅号,发布消息和订阅消息的bean的加载顺序控制
-
双11活动期间,零点前是结算策略A,零点后是结算策略B,策略B操作的数据为促销数据。策略B加载顺序与促销数据的加载顺序
@Lazy
- 程序灾难出现后对应的应急预案处理是启动容器时加载时机
@Order
- 多个种类的配置出现后,优先加载系统级的,然后加载业务级的,避免细粒度的加载控制
九.springMVC
1.编码过滤器–web.xml
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>