(day2-spring和mybatis学习)-->重点增删改查
在how2j上学SSM,整理一下笔记
Spring是一个基于IOC和AOP的结构J2EE系统的框架
(1).IOC 反转控制 是Spring的基础,Inversion Of Control
简单说就是创建对象由以前的程序员自己new 构造方法来调用,变成了交由Spring创建对象
DI 依赖注入 Dependency Inject. 简单地说就是拿到的对象的属性,已经被注入好相关值了,直接使用即可。
(2).AOP 即 Aspect Oriented Program 面向切面编程
首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。
所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
所谓的周边功能,比如性能统计,日志,事务管理等等
周边功能在Spring的面向切面编程AOP思想里,即被定义为切面
(3).在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发
然后把切面功能和核心业务功能 “编织” 在一起,这就叫AOP
- 功能分两大类,辅助功能和核心业务功能
- 辅助功能和核心业务功能彼此独立进行开发
- 比如登陆功能,即便是没有性能统计和日志输出,也可以正常运行
- 如果有需要,就把"日志输出" 功能和 “登陆” 功能 编织在一起,这样登陆的时候,就可以看到日志输出了
- 辅助功能,又叫做切面,这种能够选择性的,低耦合的把切面和核心业务功能结合在一起的编程思想,就叫做切面编程
mybatis
测试文件做增删改查操作
增
package com.how2java;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 com.how2java.pojo.Category;
public class TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
Category c = new Category();
c.setName("新增加的Category");
session.insert("addCategory",c);
listAll(session);
session.commit();
session.close();
}
private static void listAll(SqlSession session) {
List<Category> cs = session.selectList("listCategory");
for (Category c : cs) {
System.out.println(c.getName());
}
}
}
删
Category c = new Category();
c.setId(6);
session.delete("deleteCategory",c);
listAll(session);
session.commit();
session.close();
获取
Category c= session.selectOne("getCategory",3);
System.out.println(c.getName());
// listAll(session);
session.commit();
session.close();
改
Category c= session.selectOne("getCategory",3);
c.setName("修改了的Category名稱");
session.update("updateCategory",c);
listAll(session);
session.commit();
session.close();
查
listAll(session);
session.commit();
session.close();
Category的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.pojo">
<insert id="addCategory" parameterType="Category" >
insert into category_ ( name ) values (#{name})
</insert>
<delete id="deleteCategory" parameterType="Category" >
delete from category_ where id= #{id}
</delete>
<select id="getCategory" parameterType="_int" resultType="Category">
select * from category_ where id= #{id}
</select>
<update id="updateCategory" parameterType="Category" >
update category_ set name=#{name} where id=#{id}
</update>
<select id="listCategory" resultType="Category">
select * from category_
</select>
</mapper>
模糊查询
SELECT 字段 FROM 表 WHERE 某字段 Like 条件
其中关于条件,SQL提供了四种匹配模式:
1,% :表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
比如 SELECT * FROM [user] WHERE u_name LIKE '%三%'
将会把u_name为“张三”,“张猫三”、“三脚猫”,“唐三藏”等等有“三”的记录全找出来。
另外,如果需要找出u_name中既有“三”又有“猫”的记录,请使用and条件
SELECT * FROM [user] WHERE u_name LIKE '%三%' AND u_name LIKE '%猫%'
若使用 SELECT * FROM [user] WHERE u_name LIKE '%三%猫%'
虽然能搜索出“三脚猫”,但不能搜索出符合条件的“张猫三”。
2,_ : 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:
比如 SELECT * FROM [user] WHERE u_name LIKE '_三_'
只找出“唐三藏”这样u_name为三个字且中间一个字是“三”的;
再比如 SELECT * FROM [user] WHERE u_name LIKE '三__';
只找出“三脚猫”这样name为三个字且第一个字是“三”的;
3,[ ] :表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
比如 SELECT * FROM [user] WHERE u_name LIKE '[张李王]三'
将找出“张三”、“李三”、“王三”(而不是“张李王三”);
如 [ ] 内有一系列字符(01234、abcde之类的)则可略写为“0-4”、“a-e”
SELECT * FROM [user] WHERE u_name LIKE '老[1-9]'
将找出“老1”、“老2”、……、“老9”;
4,[^ ] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
比如 SELECT * FROM [user] WHERE u_name LIKE '[^张李王]三'
将找出不姓“张”、“李”、“王”的“赵三”、“孙三”等;
SELECT * FROM [user] WHERE u_name LIKE '老[^1-4]';
将排除“老1”到“老4”,寻找“老5”、“老6”、……
什么是sql注入
SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库。
【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译
sql注入原文链接
mybatis多对一修改代码:
package com.how2java;
import com.how2java.pojo.Category;
import com.how2java.pojo.Product;
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 TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
// List<Product> ps = session.selectList("listProduct");
// for (Product p : ps) {
// System.out.println(p+" ��Ӧ�ķ����� \t "+ p.getCategory());
// }
Category c1 = session.selectOne("getCategory",1);
System.out.println(c1.getName());
System.out.println(c1.getProducts());
Product p5 = session.selectOne("getProduct",5);
System.out.println(p5);
System.out.println(p5.getCategory());
p5.setCategory(c1);
session.update("updateProduct",p5);
session.commit();
session.close();
}
}
CRUD:增删改查。
注意点:需要提交事务,session.commit()
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.how2java.pojo">
<insert id="addCategory" parameterType="Category">
insert into category_ (name)values(#{name})
</insert>
使用注解开发
1.注解在接口上实现
@Select(“select* from category_”)
public List list();
2.需要在核心配置文件中绑定接口
绑定接口
3.测试
public class TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
//add(mapper);
//delete(mapper);
//get(mapper);
//update(mapper);
listAll(mapper);
session.commit();
session.close();
}
private static void update(CategoryMapper mapper){
Category c = mapper.get(8);
c.setName("修改了Category的名称");
mapper.update(c);
listAll(mapper);
}
private static void get(CategoryMapper mapper){
Category c = mapper.get(8);
System.out.println(c.getName());
}
private static void delete(CategoryMapper mapper){
mapper.delete(2);
listAll(mapper);
}
private static void add(CategoryMapper mapper){
Category c = new Category();
c.setName("新增加的Category");
mapper.add(c);
//调用listAll方法,传入mapper接口
//调用此方法会打印数据库内对象的名字
//这样就能看到add之后的变化
listAll(mapper);
}
private static void listAll(CategoryMapper mapper){
List<Category> cs = mapper.list();
for (Category c : cs) {
System.out.println(c.getName());
}
}
}
本质:反射机制实现
底层:动态代理
Log4j
为了应对这种情况,我们使用Log4j来进行日志输出。 采用如下代码,执行雷同的输出。 可以看到输出结果有几个改观:
- 知道是log4j.TestLog4j这个类里的日志
- 是在[main]线程里的日志
- 日志级别可观察,一共有6个级别 TRACE DEBUG INFO WARN ERROR FATAL
- 日志输出级别范围可控制, 如代码所示,只输出高于DEBUG级别的,那么TRACE级别的日志自动不输出
- 每句日志消耗的毫秒数(最前面的数字),可观察,这样就可以进行性能计算
缓存
1.什么是缓存【Cache】?
存在内存中的临时数据,将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题
2.为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率
3.什么样的数据可以使用缓存?
经常查询并且不经常改变的数据 【可以使用缓存】