尚硅谷-Spring5框架笔记(二)

本文深入解析了面向切面编程(AOP)的概念、原理及其在Spring框架中的应用,包括基于AspectJ的AOP操作、切入点表达式及通知类型的配置。同时,详细介绍了JdbcTemplate在数据库操作中的使用方法,如批量操作、查询返回对象或集合,以及事务处理。
摘要由CSDN通过智能技术生成

(1)、AOP:面向切面编程,对业务逻辑的各个部分进行隔离,从而降低耦合度,提高程序可重用性和开发效率;将日志记录,事务处理,异常处理、性能统计,安全控制等代码从业务逻辑代码中划分出来,改变这些行为的时候不影响业务逻辑代码。

通俗描述:在不修改源代码的情况下,在主干功能里面添加新的功能。

(2)、AOP底层原理

(2.1)动态代理:

有接口,使用JDK动态代理。创建接口实现类的代理对象,增强类的方法。

JDK动态代理,使用Proxy类,java.lang.reflect.Proxy代理类。

newProxyInstance(Classloader loader, 类<?>[ ]... interfaaces,InvocationHandler h)

返回指定接口的代理类实例;

三个参数,

第一个参数,类加载器

第二个参数,增强方法所在的类,这个类实现的接口,支持多个接口,

第三个参数,实现这个接口InvocationHandler,创建代理对象,写增强方法

//(1)创建接口,定义方法
public interface UserDao{
    public int add(int a,int b);
    public String display(String id);
}
//(2)接口实现类
public class UserDaoImpl implements UserDao{
    @override
    public int add(int a,int b){
        return a+b;
    }
    @override
    public String diaplay(String id){
        return id;
    }
}
//(3)使用proxy类创建接口代理对象
public class JDKProxy{
    //创建代理对象代码
    class UserDaoProxy implements InvocationHandler{
        //1、创建的谁的代理对象,把谁传进来
        //有参构造
        private Object obj;
        public UserProxy(Object obj){
            this.obj = obj;
        }
        //增强部分
        @override
        public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
    //方法之前执行
    System.out.println("方法之前执行。。。"+method.getName()+"传递的参数"+Arrays.toString(args));
    //被增强的方法执行
    Object res = menthod.invoke(obj,args);
    //方法之后执行
    System.out.println("方法之后执行。。。"+obj);
    return res;
}
    }
    public static void main(String[] args){
    //创建接口实现类代理对象
    Class[] interfaces = {UserDao.class};
    UserDaoImpl userDao = new UserDaoImpl();
    UserDao dao =    Proxy.newProcyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserProxy(userDao) );
    int result = dao.add(1,3);
    System.out.println(result);
}
}

无接口,使用CGLIB动态代理。创建子类的代理对象,增强类的方法。

AOP术语 

连接点:类里面可以被增强的方法。

切入点:实际被增强的方法。

通知(增强):实际增加的逻辑部分。

         通知有多种类型:前置通知,后置通知,环绕通知,异常通知,最终通知

切面:把通知应用到切入点的过程。

AOP操作(准备)

1、Spring 框架中一般都是基于AspectJ实现AOP操作

AspectJ,本身是单独的框架,不属于Spring组成部分,独立于AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作。

2、基于AspectJ实现AOP操作

     (1)基于xml配置文件实现

     (2)基于注解方式实现

3、项目里引入相关依赖

 4、切入点表达式

       (1)切入点表达式作用:知道对哪个类的哪个方法进行增强

       (2)语法结构

           execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))

举例1:对com.zhh.dao.BookDao类里的add进行增强

execution(* com.zhh.dao.BookDao.add(..))

举例2:对com.zhh.dao.BookDao类里的所有方法进行增强

execution(* com.zhh.dao.BookDao.*(..))

举例3:对com.zhh.dao包里的所有类,类里的所有方法进行增强

execution(* com.zhh.dao.*.*(..))

AOP操作(AspectJ注解)

1、创建类,再类里定义方法

2、

//1、创建类
@component
public class User{
    public void add(){
        System.out.println("add...");
    }
}
//2、创建增强类(增加功能)
//增强的类
@Component
@Aspect
public class UserProxy{
    //前置通知
     @Before("execution(* com.zhh.annocation_aop.User.add(..))")
     public void before(){
        System.ouot.println("before...."); 
     }
    //返回通知,有异常不执行
        @AfterReturning(value="execution(* com.zhh.annocation_aop.User.add(..))")
    public void afterReturning(){
        System.out.println("afterreturning...");
    }
    //后置通知,有没有异常都会执行
    @After(value="execution(* com.zhh.annocation_aop.User.add(..))")
    public void after(){
        System.out.println("after...");
    }
    //异常通知
        @AfterTrowing(value="execution(* com.zhh.annocation_aop.User.add(..))")
    public void AfterTrowing(){
        System.out.println("AfterTrowing...");
    }
    //环绕通知,之前,之后都执行
        @Around(value="execution(* com.zhh.annocation_aop.User.add(..))")
    public void around(ProceedingJontPoint proceedingJontPoint){
        System.out.println("around...");

    }
}
//3、进行通知的配置
//3.1,Spring配置文件中,开启注解扫描
 <!--开启扫描-->
<context:component-scan base-package="com.zhh.annocation_aop"></context:component-scan>
//3.2,使用注解创建User和UserProxy对象@Component
//3.3,在增强类上面添加注解@Aspect
//3.4, spring配置文件中开启生成代理对象
 <!--生成代理对象-->
<aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
//4 配置不同的类型
//4.1 在增强类的里面,在作为通知发放上面添加通知类型注解,使用切入点表达式配置
@Before("execution(* com.zhh.annocation_aop.User.add(..))")
//5 测试类
@test
public void testAopAnno(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beanl.xml");
User user = context.getBean("user",User.class);
user.add();

相同接入点抽取 

//抽取出来的方法
@Pointcut(value="execution(* com.zhh.spring5.aopanno.User.add(..) )")
public void pointdemo(){
}
//使用公共方法
@Before(value="pointdemo()")
public void before(){
    System.out.println("before........");
}

 有多个增强类对同一个方法进行增强,设置增强类的优先级,在增强类上面添加注解@Order(数字类型值),数字类型值越小优先级越高

@Component
@Aspect
@Order(1)
public class PersonProxy{
}

完全注解方式

@Configuration
@ComponentScan(basePackages={"com.zhh"})
@EnableAspectJAutoproxy(proxyTargetClass=true)
public class ConfigAop{
}

AOP操作(AspectJ配置文件)

1、创建被增强类和增强类,以及方法

2、在spring配置文件中常见两个对象

3、在spring配置文件中配置切入点

//被增强类
public class Book{
    public void buy(){
        System.out.println("buy.......");
    }
}
//增强类
public class BookProxy{
    public void before(){
        System.out.println("before.......");
    }
}
//创建对象
<bean id ="book" class="com.zhh.spring5.Book"></bean>
<bean id ="bookProxy" class="com.zhh.spring5.BookProxy"></bean>
<!--配置AOP的增强-->
<aop:config>
    <!--切入点-->
    <aop:pointcut id="p" expression="execution(* com.zhh.spring5.Book.buy(..))"/>
     <!--配置切面-->
    <aop:aspect ref="bookProxy">
        <aop:before method="before" ponitcut-ref="p"/>
    </aop:aspect>

</aop:config>

jdbcTemplate

1、什么是jdbcTemplate

(1)Spring框架对JDBC进行封装,使用jdbcTemplate方便对数据库操作

2、准备工作

(1)引入相关的jar包

2、spring配置文件中配置数据库连接池

3、配置JdbcTemplate对象,注入DataSource

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name ="url" value="jdbc:mysql:///user_db"/>
    <property name="username" value="root">
    <property name = "password" value="root">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <bean id="jdbcTemplate"class="org.springframe">
        <property name="dataSource"  ref="dataSource"></property>
    </bean>

</bean>

4、创建service类,创建dao类。在dao里注入jdbcTemplate

<context:component-scan base-package ="com.zhh"></context:component-scan>
@Service
public class BookService{
    @Autowired
    private BookDao bookDao;
}
public interface BookDao{

}
public class BookdaoImpl implements BookDao{
    @AutoWired
    private JdbcTemplate jdbcTempalte;
}

jdbcTemplate 操作数据库
1、对应数据库的实体类

public class User{
    private String userId;
    private String userName;
    private String userStates;
    public void setUserId(String userId){
        this.userId = userId;
    }
    public void setUserName(String UserName){
        this.UserName = UserName;
    }
    public void setuserStates(String userStates){
        this.userStates = userStates;
    }
    public String getUserId(){
        return userId;
    }
    public String getuserName(){
        return userName;
    }
    public String getUuserStates(){
        return userStates;
    }
}

2、编写service和dao

(1)、在dao进行数据库添加操作

(2)、调用JdbcTemplate对象里的update方法实现添加操作

         update(String sql, Object args)有两个参数,一个是sql语句,第二个参数是可变参数,设置sql的值

@service
public class BookService{
    //注入dao
    @Autowired
    private BookDao bookDao;
    //添加的方法
    public void addBook(Book book){
        bookDao.add(book);
    }
    //修改的方法
    public void updateBook(Book book){
        bookDao.updateBook(book);
    }
    //删除的方法
    public void deleteBook(String id){
        bookDao.deleteBook(id);
    }
}

public interface BookDao{
    //添加的方法
    void add(Book book);
    //添加的方法
    void updateBook(Book book);
    //添加的方法
    void delete(String id);
}

@repository
public class BookDaoImpl implements BookDao{
    //注入jdbcTemplate
    public JdbcTemplate jdbcTemplate;
    
    //添加的方法
    @Override
    public void add(Book book){
        //创建sql语句
        String sql = "insert into t_book values(?,?,?)";
        //创建sql语句参数
        Object[] args = {book.getUserId(),book.getUserName(),book.getUserStates()};
        int update = jdbcTemplate.update(sql,args);
        System.out.println(update);
    }
    //添加的方法
    @Override
    public void update(Book book){
        //创建sql语句
        String sql = "update t_book vset userName =?,ustatus=? where user_id=?";
        //创建sql语句参数
        Object[] args = {book.getUserId(),book.getUserName(),book.getUserStates()};
        int update = jdbcTemplate.update(sql,args);
        System.out.println(update);
    }
    //添加的方法
    @Override
    public void delete(String id){
        //创建sql语句
        String sql = "delete from t_book where user_id=?";
        //创建sql语句参数
        int update = jdbcTemplate.update(sql,id);
        System.out.println(update);
    }
}

public class Test{
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    BookServoce bookservice = context.getBean("bookservice",bookService.class);
    Book book = new Book();
    book.setUserId("1");
    book.setUserName("java");
    book.setUserStatues("a");
    bookService.addBook(book);
    }
}

查询返回某个值

1、查询表里有多少条记录,返回某个值

2、使用iJdbcTemplate实现查询返回某个值的代码

queryForObject(String sql,Class<T> requiredType )

两个参数,第一个参数,sql语句,第二个参数,返回类型Class

@Override
public int selectCount(){
    String sql = "select count(*) from t_book";
    Integer count = jdbcTemplate.queryForObject(sql,Integer.class);
    return count;
}

查询返回对象

1、场景:查询图书详情

2、JdbcTemplate实现查询返回对象

queryForObject(String sql, RowMapper<T> rowMapper, Object... args)

三个参数:

第一个参数,sql语句,

 第二哥参数,RowMapper,是接口,返回不同类型数据,使用这个接口里面实现完成数据封装

第三个参数,sql语句值

@Override
public Book findBOOKInfo(String id){
    String sql = "select * from t_book where user_id=?";
    Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class),id);
    return book;
}

查询返回集合

1、场景:查询图书列表分页

2、JdbcTemplate实现查询返回集合

query(String sql, RowMapper<T> rowMapper, Object... args )

三个参数:

第一个参数,sql语句,

 第二哥参数,RowMapper,是接口,返回不同类型数据,使用这个接口里面实现完成数据封装

第三个参数,sql语句值

@Override
public List<Book> findAllBook(){
    String sql = "select * from t_book ";
    List<Book> booklist = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
    return booklist;
}

JdbcTemplate操作数据库(批量操作)

1、批量操作:操作表里的多项记录

2、JdbcTemplate实现批量操作 

batchUpdate(String sql,List<Object[]> batchArgs)\

有两个参数:

第一个参数: sql语句,

第二个参数:List集合,添加多条记录数据

@Override
public void batchAdd(List<Object[]> batchArgs){
    String sql = "insert into t_book values(?,?,?)";
    int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
    System.out.println(Arrays.toString(ints));
}
//批量添加测试
List<Object[]> batchArgs = new ArrayList<>();
Object[] o1 = {"3","java","a"};
Object[] o2 = {"4","c++","b"};
Object[] o3 = {"5","mysql","c"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchAdd(batchArgs);

JdbcTemplate操作数据库(批量修改)

@Override
public void batchUpdateBook(List<Object[]> batchArgs){
    String sql = "update t_book set username =?,where user_id=?";
    int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
    System.out.println(Arrays.toString(ints));
}
//批量添加测试
List<Object[]> batchArgs = new ArrayList<>();
Object[] o1 = {"java","a","3"};
Object[] o2 = {"c++","b","4"};
Object[] o3 = {"mysql","c","5"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchUpdate(batchArgs);

JdbcTemplate操作数据库(批量删除)

@Override
public void batchDeleteBook(List<Object[]> batchArgs){
    String sql = "delete from t_book where user_id=?";
    int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
    System.out.println(Arrays.toString(ints));
}
//批量添加测试
List<Object[]> batchArgs = new ArrayList<>();
Object[] o1 = {"3"};
Object[] o2 = {"4"};
Object[] o3 = {"5"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchUDeleteBook(batchArgs);

事务概念

1、什么是事务

(1)事务是数据库操作最近本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败

(2)典型场景:银行转账

2、事物的四个特性(ACID)

(1)原子性:要么都成功。要么都失败

(2)一致性:操作之前和操作之后总量不变

(3)隔离性:多事务操作之间不会相互影响

(4)持久性:事务提交之后,表中数据发生变化保存起来

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值