首页
统计
4K壁纸
留言
Search
1
自动采集头像+壁纸+流量主小程序
935 阅读
2
【腾讯云】低价服务器活动和新用户活动
507 阅读
3
Spring MVC 结构体系
426 阅读
4
Spring Di依赖注入环境
384 阅读
5
springboot
341 阅读
技术分享
学习笔记
jsp
Maven
Mybatis
Spring
Hibernate
系统源码
网站源码
APP源码
微信程序
小程序
登录
/
注册
Search
标签搜索
学习笔记
Hibernate
小程序
Mybatis
源码
教程
笔记
Ajax
微信
活动
福利
MyEclipse 10
笔记fen'x
壁纸小程序
微信程序
HQL
笔记分享
Mybatis-Plus
小新
累计撰写
44
篇文章
累计收到
48
条评论
首页
栏目
技术分享
学习笔记
jsp
Maven
Mybatis
Spring
Hibernate
系统源码
网站源码
APP源码
微信程序
小程序
页面
统计
4K壁纸
留言
搜索到
31
篇与
学习笔记
的结果
2022-05-04
Mybatis-Plus 笔记总结
快速入门搭建步骤创建数据库mybatis_pluscreate database mybatis_plus use mybatis_plus CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com');编写项目这里是spring-boot 框架导入依赖<!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--spring-plus的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency>导入了没有batis-plus 就不用导入mybatis了 ,这样容易冲突连接数据库 ! 和mybatis相同(properties文件)spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root创建pojo实体类package com.xin.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class User { private Long id; private String name; private Integer age; private String email; }Mapper接口package com.xin.Mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xin.pojo.User; import org.apache.ibatis.annotations.Mapper; @Mapper //在对应的Mapper上继承基本的类 BaseMapper public interface UserMapper extends BaseMapper<User> { //所以的增删改查已经完成了! }测试_使用:@SpringBootTest class MybatisPlus01ApplicationTests { //所有的方法来源它的父类BaesMapper @Autowired private UserMapper userMapper; @Test void contextLoads() { //查询全部用户 List<User> userList = userMapper.selectList(null); for (User user : userList) { System.out.println(user); } } }配置日志为了查看执行的SQL 语句 ,所以我们必须看日志# 日志配置 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImplCURD扩展 /*测试添加方法*/ @Test public void textinsert(){ User user = new User(); user.setName("迪迦"); user.setAge(21); user.setEmail("123131314@qq.com"); int i = userMapper.insert(user); //自动生成ID System.out.println(i); }
2022年05月04日
20 阅读
0 评论
1 点赞
2022-04-11
HQL连接查询
暂无简介
2022年04月11日
28 阅读
0 评论
0 点赞
2022-04-09
HQL实用技术
HQL查询语言是一种面向对象的查询语言,没有表和字段的概念,只要类和对象的概念。我们查询的时候 是查询 实体类HQL语句HibernateUtil.currentSession().beginTransaction(); Session session = HibernateUtil.currentSession(); String hql = "from Emp"; Query query = session.createQuery(hql); // 适用createQuery()方法执行Query对象构建好后,有两种方式执行查询语句并获取查询结果,list() , iterate()两个方法参数绑定第一种显示参数方式HibernateUtil.currentSession().beginTransaction(); Session session = HibernateUtil.currentSession(); String hql = "from Emp where ENAME like concat('%',?,'%')"; Query query = session.createQuery(hql); //setParameter是任意类型参数 , 占位符下标从0开始 query.setParameter(0, "王"); List<Emp> list = query.list();如果参数为字符串类型,可调用setString()方法,整数类型调用setInteger() 依次类推setParameter是任意类型参数,还可以传递数组作为参数 ,对象第二种显示参数方式String hql = "from Emp where ENAME like concat('%',:ename,'%')";动态查询把对象作为参数 有参数作为判断条件,这里我是使用的字符串代替Map<String, Object> map = new HashMap<String, Object>(); String job = "CLERK"; Double sal = 1000.0; String startDt ="1981-4-1"; String endDt = "1985-9-9"; str.append("from Emp where 1 = 1 "); if(job !=null ){ str.append("and job = :job "); map.put("job", job); } if(sal !=null){ str.append("and sal > :sal "); map.put("sal", sal); } if(startDt !=null){ str.append("and HIREDATE >=to_date(:startDt,'yyyy-MM-dd') "); map.put("startDt", startDt); } if(endDt !=null){ str.append("and HIREDATE < to_date(:endDt,'yyyy-MM-dd') "); map.put("endDt", endDt); } Query query = session.createQuery(str.toString()); query.setProperties(map); List<Emp> list = query.list(); System.out.println(list);uniqueResult()方法Query接口提供的list(),iterate()方法获取查询结果集合,使用uniquerResult()方法是或缺唯一的 ,返回一条数据Query query = session.createQuery("select ename from Emp where empno=1944"); Object obs = query.uniqueResult();需要注意的是:当查询结果不是唯一的时候 , 不能使用 nuiqueResult()方法,否则会报错误!分页查询分页查询非常简单,只需要设置两个方法String hql = "from Emp"; Query query = session.createQuery(hql); //表示当前页数 query.setFirstResult(0); //每页显示的数据 query.setMaxResults(2); 投影查询有时候我们只需要展示数据,不需要获取对象的全部属性,比如结果聚合函数等方式得到某个结果,此时可以使用投影查询,下面是投影查询获取的几种方式//1. 单个投影值 Query query = session.createQuery("select ename from Emp where empno=1944"); Object obs = query.uniqueResult(); System.out.println(obs); //2. 单行投影值 Query query = session.createQuery("select empno ,ename, sal from Emp where empno=1944"); Object[] objs = (Object[])query.uniqueResult(); System.out.println(objs[0]); System.out.println(objs[1]); System.out.println(objs[2]); //3.多行投影值 Query query = session.createQuery("select empno ,ename, sal from Emp"); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(objects[0]); System.out.println(objects[1]); System.out.println(objects[2]); } //4. 构造方法投影 Query query = session.createQuery("select new Emp(empno ,ename, sal) from Emp"); List<Emp> list = query.list(); System.out.println(list);总结HQL是面向对象的查询语言,在Hibernate提供的各种查询方式中,HQL是使用最广的一种查询方式执行HQL语句需要Query接口,Query也是Hibernate的核心接口之一,执行HQL的两种常用的方法是list()方法 和 iterate()方法HQL语句中绑定的参数的形式有两种,按参数位置绑定,按参数名称绑定。HQL支持投影查询,灵活的参数查询,分页查询等功能.可以使用反向工具生成持久化类和映射文件
2022年04月09日
91 阅读
0 评论
0 点赞
2022-04-09
Hibernate入门
Hibernate的优点:1、对象化。hibernate可以让开发人员以面相对象的思想来操作数据库。jdbc只能通过SQL语句将元数据传送给数据库,进行数据操作。而hibernate可以在底层对元数据和对象进行转化,使得开发者只用面向对象的方式来存取数据即可。2、更好的移植性。hibernate使用xml或JPA的配置以及数据库方言等等的机制,使得hibernate具有更好的移植性,对于不同的数据库,开发者只需要使用相同的数据操作即可,无需关心数据库之间的差异。而直接使用JDBC就不得不考虑数据库差异的问题。3、开发效率高。hibernate提供了大量的封装(这也是它最大的缺点),很多数据操作以及关联关系等都被封装的很好,开发者不需写大量的sql语句,这就极大的提高了开发者的开发效率。4、缓存机制的使用。hibernate提供了缓存机制(session缓存,二级缓存,查询缓存),对于那些改动不大且经常使用的数据,可以将它们放到缓存中,不必在每次使用时都去查询数据库,缓存机制对提升性能大有裨益。hibernate的缺点主要有以下几点:一、由于对持久层封装过于完整,导致开发人员无法对SQL进行优化,无法灵活使用JDBC的原生SQL,Hibernate封装了JDBC,所以没有JDBC直接访问数据库效率高。要使用数据库的特定优化机制的时候,不适合用Hibernate二、框架中使用ORM原则,导致配置过于复杂,一旦遇到大型项目,比如300张表以上,配置文件和内容是非常庞大的,另外,DTO满天飞,性能和维护问题随之而来三、如果项目中各个表中关系复杂,表之间的关系很多,在很多地方把lazy都设置false,会导致数据查询和加载很慢,尤其是级联查询的时候。四、Hibernate在批量数据处理时有弱势,对于批量的修改,删除,不适合用Hibernate,这也是ORM框架的弱点使用Hibernate操作数据库(1) 读取并解析配置文件及映射文件。Configuration conf = new Configuration().configure();(2) 依据配置文件和映射文件中的信息,创建SessionFactory对象。SessionFactory sf = conf.buildSessionFactory();(3) 打开SessionSession session = sf.getCurrentSession(); //或者使用 sf.openSession() : 使用这个需要关闭;(4) 开始一个事务Transaction tx = session.beginTransaction();(5) 数据库操作session.sava(user); //保存方法(6) 结束事务tx.commit(); //提交事务 或 tx.rollback(); // 回滚封装步骤package com.xyh.util; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; public class HibernateUtil { private static Configuration configuration; private final static SessionFactory sessionFactory; static{ try { configuration = new Configuration().configure(); sessionFactory = configuration.buildSessionFactory(); } catch (HibernateException e) { e.printStackTrace(); throw new ExceptionInInitializerError(e); } } public HibernateUtil() {} public static Session currentSession(){ return sessionFactory.getCurrentSession(); } } 这里直接打开了Session 调用直接使用!使用Hibernate API向hibernate.cfg.xml文件中配置映射文件<property name="show_sql">true</property> <property name="format_sql">true</property> <!--配后才能使用session=sessionFactory.getCurrentSession(); --> assigend:忽略自增长,添加时需手动指定主键 native:采用数据库已有的自增长规则 <property name="current_session_context_class">thread</property>按主键查询在进行修改或删除操作时,应县加载对象,然后再执行修改或删除操作, 主键查询对象:get(类 , id)load(类, id){tabs}{tabs-pane label="get方法"}@Test public void test(){ try { Transaction tx = HibernateUtil.currentSession().beginTransaction(); //这里可以转换为对象 Object object = HibernateUtil.currentSession().get(Emp.class, (short)1944); System.out.println(object); //打印数据 tx.commit(); } catch (HibernateException e) { e.printStackTrace(); } } {/tabs-pane}{tabs-pane label="load方法"}@Test public void test(){ try { Transaction tx = HibernateUtil.currentSession().beginTransaction(); //这里可以转换为对象 Object object = HibernateUtil.currentSession().load(Emp.class, (short)1944); System.out.println(object); //打印数据 tx.commit(); } catch (HibernateException e) { e.printStackTrace(); } } {/tabs-pane}{/tabs}这两个方法的区别之一:get方法如果没有查询出数据,就会返回nullload方法如果没有查询出数据,就会抛出异常实现修改,删除修改和删除操作之前,要先获取到数据{tabs}{tabs-pane label="修改"}Transaction tx = HibernateUtil.currentSession().beginTransaction(); Emp emp = (Emp) HibernateUtil.currentSession().get(Emp.class, (short)1944); emp.setEname("小新"); //获取数据后:直接set修改 tx.commit(); // 提交事务{/tabs-pane}{tabs-pane label="删除"}Transaction tx = HibernateUtil.currentSession().beginTransaction(); Emp emp = (Emp) HibernateUtil.currentSession().get(Emp.class, (short)1944); HibernateUtil.currentSession().delete(emp); //执行delete删除方法即可 tx.commit(); // 提交事务{/tabs-pane}{/tabs}Hibernate对象三种状态临时状态、持久状态、游离状态 临时状态(Transient):当new一个实体对象后,这个对象处于临时状态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被jre垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save或者SaveOrUpdate把临时对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久对象。持久状态(Persistent): 持久化对象的实例在数据库中有对应的记录,并拥有一个持久化表示(ID)。对持久化对象进行delete操作后,数据库中对应的记录将被删除,那么持久化对象与数据库记录不再存在对应关系,持久化对象变成临时状态。持久化对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。在同步之前,持久化对象是脏的(Dirty)。游离状态(Detached):当Session进行了Close、Clear或者evict后,持久化对象虽然拥有持久化标识符和与数据库对应记录一致的值,但是因为会话已经消失,对象不在持久化管理之内,所以处于游离状态(也叫:脱管状态)。游离状态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。三种状态之间的转换脏检查与刷新缓存脏检查Transaction tx = HibernateUtil.currentSession().beginTransaction(); //获取部门对象,emp对象处于持久化状态 Emp emp = (Emp) HibernateUtil.currentSession().load(Emp.class, (short)1944); //修改后,部门信息和之前不同,此时emp对象成为所谓的 脏对象 emp.setEname("小新"); // 提交事务 tx.commit();刷新缓存当刷新缓存(调用Session的flush()方法)时,Hiberante会对Session 中持久状态的对象进行监测 ,判断对象的数据是否发生了改变commit() 方法会首先刷新缓存刷新缓存机制刷新缓存就是将数据库同步为与Session缓存一致刷新缓存时会执行脏检查Session 会在以下时间点刷新缓存Session 的flush()方法调用Transaction的commit()方法
2022年04月09日
121 阅读
0 评论
1 点赞
2022-03-24
Oracle
表空间全局数据库名 用于区分一个数据库的内部标识 全局数据库名 = 数据库名+域名 使数据库的取名在整个网络环境中唯一模式和模式对象 模式和模式对象的集合 每个用户对应一个模式 模式对象是用户拥有的对象 非模式对象与用户无关,如表空间数据库服务OracleService<SID>:数据库服务OracleOraDb11g_hom1TNSListener:数据库监听服务OracleDBConsole<SID>: 企业管理服务配置客户端网络服务oracle 客户端 tnsnames.oraoracle 服务器 listener.ora连接数据库sys 和 system 用户sys 和system 用户都是Oracle 的系统用户 都使用system表空间,sys拥有更大的权限 SYS用户SYSTEM用户地位Oracla的一个超级用户Oracle默认的系统管理员,拥有DBA权限作用主要用来维护系统信息和管理实例通常用来管理Oracle数据库的用户,权限和存储等登录身份只能以SYSDBA或SYSOER角色登录只能以Normal方式登录数据类型 数据类型描述字符数据类型char;varchar2;nchar和nvarchar2;存储固定长度的字符串存储可变长度的字符串存储Unicode字符集类型数值数据类型number;存储整数和浮点数,格式为Number(p,s)日期时间数据类型DATE;TIMESTAMPDATE:存储日期和时间数据TIMESTAMP:秒值精确到小数点后6位 Oracle 中伪列就像一个表列,但是它没有存储在表中伪列可以从表中查询,但不能插入,更新和删除他们的值常用的伪列有ROWID 和 ROWNUMROWID 是表中行的存储地址,该地址可以唯一地标识数据库中的一行,可以使用ROWID伪列快速地定位表中的一行ROWNUM是查询返回的结构集中行的序号,可以使用它来限制查询返回的行数分页查询select * from (select ename,rownum as nu from emp) where nu>=5 and nu <=10SQL语言数据定义语言(DDL)createalertdroptruncate数据操作语言(DML)insert , update,delete,select 事务控制语言(TCL)commit 、 savepoint 、rollback数据控制语言(DCL)grantrevoke数据操纵语言不重复显示所有学员姓名和年龄select <span style="color:red">distinct </span>利用现有的表创建新表create table newStuInfo as select [指定数据] from studnet [where 1=2 只留表结构,不留数据]取出两列不存在重复数据的记录HAVING(COUNT(stuName||stuAge) <2);创建表时 同时赋值-- 插入多行数据 create table Student as select 1 as stunno,'张浩' as stuname,18 as sage from dual union select 2 as stuno ,'海波东' as stuname, 49 as sage from dual union select 3 as stuno ,'萧炎' as stuname, 20 as sage from dual union select 4 as stuno ,'药老' as stuname, 69 as sage from dual union select 5 as stuno ,'美杜莎' as stuname, 50 as sage from dual事务控制语言Set transaction --> 设置事物属性Set constrains --> 设置事物的约束模式约束模式是指:在事务中修改数据时,数据库中的约束立即应用于数据,还是将约束推迟到当前事务结束后应用。Savepoint --> 在事务中建立一个存储的点.当事务处理发生异常而回滚事务时,可指定事务回滚到某存储点.然后从该存储点重新执行。Release savepoint --> 删除存储点Rollback 回滚事务 --> 取消对数据库所作的任何操作Commit 提交事务 --> 对数据库的操作做持久的保存。集合操作符UNION:将多个查询的结果组合到一个查询结果之中,并去掉反复值UNION ALL:将多个查询结果组合到一个查询结果中。可是包括反复值INTERSECT:返回多个查询结果同样的部分MINUS:返回两个查询结果的差集SQL函数单行函数每一行只返回一个值,可以出现在select 子句和where子句中字符函数:对字符串操作。数字函数:对数字进行计算,返回一个数字。日期函数:对日期和时间进行处理。转换函数:可以将一种数据类型转换为另外一种数据类型。SELECT TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日" HH24:MI:SS') "date" FROM dual; SYSDATE:当前日期 字符串转换 钱格式 select to_char(1231.6,'$9,999,00') from dual 字符串转日期 select to_date('2004-1-1','yyyy-MM-dd') from dual 字符串转数据 select to_number('100') from dual其他单行函数1、NVL(X,VALUE)如果X为空,返回value,否则返回Xdecode : 百度select ename,job,sal+nvl(comm,0) as 实发工资, nvl2(comm,sal+comm,sal) as 显示方式2 ,decode(to_char(hiredate,'MM'),1,'1月','下半年') as 入职 from emp分组函数根据分钟的情况,返回每组里的一个结果值 , 可以在使用order by和 having子句中使用。分析函数分析函数根据一组行来计算聚合值,分析函数为每组记录返回多个行二、数据库应用会创建表空间会创建用户并授权掌握序列的使用方法理解同义词的使用方法了解索引,会创建常用索引了解分区表表空间分类类别举例说明永久性表空间SYSTEM,USERS一般保存表,视图,过程和索引等的数据临时性表空间TEMP只用于保存系统中短期活动的数据撤销表空间UNDO用来帮助回退未提交的事务数据一般不需要建临时和撤销空间,除非把它们转移其他磁盘中以提高性能创建表空间(库)基于应用性能和管理方面的考虑,最好未不用的子系统创建独立的表空间语法: create tablespace tablespacename create tablespace tp_hr datafile 'D:\Oracle\test\tp_hr02.dbf' size 5M;删除表drop tablespace tp_hr --删除空的表空间,但是不包含物理文件 drop tablespace tablespace_name; --删除非空表空间,但是不包含物理文件 drop tablespace tablespace_name including contents; --删除空表空间,包含物理文件 drop tablespace tablespace_name including datafiles; --删除非空表空间,包含物理文件 drop tablespace tablespace_name including contents and datafiles; --如果其他表空间中的表有外键等约束关联到了本表空间中的表的字段,就要加上CASCADE CONSTRAINTS drop tablespace tablespace_name including contents and datafiles CASCADE CONSTRAINTS;修改表空间方法一: 更改数据文件的大小alter database datafile 'D:\Oracle\test\tp_hr02.dbf' resize 10M;方法二:向表空间内添加数据文件alter tablespace tp_hr add datafile 'D:\Oracle\test\tp_hr01.dbf' size 10M autoextend on创建用户#创建用户 create user yxh3039 identified by"123123" default tablespace tp_hr权限和角色用户必须赋予相应的权限权限指执行特定类型SQL 命令或访问其他对象的权利系统权限和对象权限系统权限允许用户执行某些数据库操作对象权限允许用户对某一特定对象执行特定的操作为了简化权限管理,引入了角色的概念角色是具有名称的一组权限的组合常用系统预定义角色connect: 临时用户resource:更为可靠和正式的用户dba:数据库管理角色,拥有管理数据库的最高权限分配权限和角色-- 分配权限或角色 grant priviieges or role to user #priviieges or role 标识定义角色 如: grant connect to yxh3039 -- 撤销权限或角色 revoke connect from userinfo序列(主键)序列是用于生成唯一,连续序号的对象序列可以是升序的,也可以是降序create sequence toys_seq start with 1 #指定第一个序号从1开始 increment by 1 #指定序号之间的间隔为1 maxvalue 200 表示序列的最大值为200 minvalue 10 表示序列的最小值为10 nocycle 达到最大值后停止生成以一个 cache 10 指定内存中预先分配的徐磊号SYS_GUID函数生成32位的唯一编码 可以作为主键select sys_guid() from dual访问序列select userinfo_seq.nextval from dual #获取索引 ,可赋值到id中更改和删除序列更新alter sequence toys_seq maxvalue 500 cycle删除drop sequence toys_seq同义词(表别名)同义词是现有对象的一个别名简化SQL语句隐藏对象的名称和所有者提供对对象的公共访问同义词共有两种类型私有同义词 : 私有同义词只能在其模式内访问,且不能与当前模式的对象同名create or replace synonym emp for scott.emp公有同义词 :公有同义词可被所有的数据库用户访问create public synonym public_sy_dept for scott.dept删除同义词drop synonym emp;drop public synonym emp_syn;索引索引分类物理分类分区或非分区索引B树索引正常或反向键索引位图索引逻辑分类单列或组合索引唯一或非唯一索引基于函数索引B树索引create index index_id on t(id[,name])反向键索引create index index_reverse_empno ON emp(empno) REVERSE位图索引create bitmap index index_bit_job ON emp(Job)管理索引索引使用原则表中导入数据后再创建索引,否则每次表中插入数据时,都必须更新索引在适当的表和字段上创建索引限制表中索引的数目
2022年03月24日
108 阅读
0 评论
0 点赞
2022-03-20
springboot
spring-boot Web开发配置静态文件可以使用以下方式处理静态资源webjars : http://localhost:8080/webjarsresourcesstaticpublichttp://localhost:8080/以上文件可直接存放优先级 :resources > static (默认) > public模板引擎templates 只能controller 层访问 : 需要模板引擎的支持 需要 Thymeleaf 依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>页面存放在templates文件中首页配置:所有页面的静态资源都需要使用Thymeleaf接管;@{}加上xmlns:th="http://www.thymeleaf.org"配置跳转@Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { //类似于@RequestMapping("/") registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); } }拦截器package com.xin.config; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /*登录拦截器*/ public class LoginHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取用户的sessoin Object loginUser = request.getSession().getAttribute("loginUser"); //判断是否登录 if(loginUser == null){ request.setAttribute("msg","未监测登录,请重新登录"); //转发 request.getRequestDispatcher("/index.html").forward(request,response); return false; }else { return true; } } }配置拦截器config 包下@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/","/user/login"); }addPathPatterns:需要拦截excludePathPatterns:不需要拦截 注意: 还需要填写css , js 资源等.Thymeleaf 语法spring.thymeleaf.cache=false //关闭模板引擎缓存1. 标签复用th:fragment="topbar" 需要重复的标签th:insert="~{dashboard::topbar}" 插入标签th:replace="~{存放公共标签的地址 :: topbar}"th:include 和 th:replace都是加载代码块内容,但是还是有所不同th:include:加载模板的内容: 读取加载节点的内容(不含节点名称),替换div内容th:replace:替换当前标签为模板中的标签,加载的节点会整个替换掉加载他的div<!-- th:fragment 定义用于加载的块 --> <span th:fragment="pagination"> the public pagination </span>================= th:include 和 th:replace============================ <!-- 加载模板的内容: 读取加载节点的内容(不含节点名称),替换<div>的内容 --> <div th:include="pagination::pagination">1</div> <!-- 替换当前标签为模板中的标签: 加载的节点会整个替换掉加载他的<div> --> <div th:replace="pagination::pagination">2</div>结果:<!-- 加载模板的内容: 读取加载节点的内容(不含节点名称),替换<div>的内容 --> <div> the public pagination</div> <!-- 替换当前标签为模板中的标签: 加载的节点会整个替换掉加载他的<div> --> <span> the public pagination</span>if-- 判断空 例:<!--如果msg等于null 就不显示--> <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>restFul 获取参数@PathVariable("变量")异常错误页面templates文件 ==> error文件==> 页面lombok 实体类注解是一个在Java开发过程中用注解的方式,简化了 JavaBean 的编写,避免了冗余和样板式代码而出现的插件,让编写的类更加简洁。JDBC配置教程导入依赖 : 使用idea 创建的时候就可以直接导入 JDBC , MySql Driver首先配置yaml 配置文件spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.jdbc.DriverController 层测试package com.xin.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.Map; @RestController public class JDBCController { @Autowired JdbcTemplate jdbcTemplate; //查询全部用户 (这里没有用实体类,用的map代替) @RequestMapping("/userList") public List<Map<String,Object>> userList(){ String sql = "select * from user"; List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql); return maps; } //添加一条数据 @RequestMapping("/addUser") public String addUser(){ String sql = "insert into user(name,pwd) values('小新','123123')"; jdbcTemplate.update(sql); return "添加成功!"; } //更新一条数据 @RequestMapping("/updeUser/{id}") public String updeUser(@PathVariable("id") int id){ String sql = "update user set name=?,pwd=? where id ="+id; Object[] objects = new Object[2]; objects[0] = "小新2号"; objects[1] = "123456"; jdbcTemplate.update(sql,objects); return "修改成功!"; } //删除一条数据 @RequestMapping("/delUser/{id}") public String delUser(@PathVariable("id") int id){ String sql = "delete from user where id =?"; jdbcTemplate.update(sql,id); return "删除成功!"; } }Druid 数据库连接池这里没有做笔记,去网上直接找Mybatis 整合导入相对应的包配置文件mybatis配置编写sqlservice层调用dao层controller 调用service层需要整合包mybatis-spring-boot-starter配置文件 (application.properties)spring.datasource.username=root spring.datasource.password=root spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #整合mybatis mybatis.type-aliases-package=com.xin.pojo mybatis.mapper-locations=classpath:mybatis/mapper/*.xml实体类 注解package com.xin.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class User { private int id; private String name; private String pwd; }其余步骤和之前mybatis 一样注意: Mapping包下的类 需要注解@Mapper @Repository public interface UserMapper { /** * 查询全部信息 * @return */ List<User> selUserList(); /** * 查询单个 * @param id * @return */ User selUserById(int id); }Mapper.xml<?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.xin.mapper.UserMapper"> <select id="selUserList" resultType="user"> select * from user </select> <select id="selUserById" resultType="user"> select * from user where id = #{id} </select> </mapper>springSecurity(安全)shiroshiro主要有三大功能模块Subject:主体,一般指用户。SecurityManager:安全管理器,管理所有Subject,可以配合内部安全组件。(类似于SpringMVC中的DispatcherServlet)Realms:用于进行权限信息的验证,一般需要自己实现。细分功能Authentication:身份认证/登录(账号密码验证)。Authorization:授权,即角色或者权限验证。Session Manager:会话管理,用户登录后的session相关管理。Cryptography:加密,密码加密等。Web Support:Web支持,集成Web环境。Caching:缓存,用户信息、角色、权限等缓存到如redis等缓存中。Concurrency:多线程并发验证,在一个线程中开启另一个线程,可以把权限自动传播过去。Testing:测试支持;Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问。Remember Me:记住我,登录后,下次再来的话不用登录了。springboot 和shiro + JDBC 整合的步骤创建依赖<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xin</groupId> <artifactId>springboot-shiro</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-shiro</name> <description>springboot-shiro</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- mybatis-spring-boot-starter --> <!--自研--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>权限对应的实体类这里不做笔记展示 还要写Mapper 、Service自定义Realm用于查询用户的角色和权限信息并保存到权限管理器:package com.xin.config; import com.xin.pojo.User; import com.xin.service.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; //自定义的Realm public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行了授权"); //SimpleAuthorizationInfo SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //拿到当前用户对象 Subject subject = SecurityUtils.getSubject(); User currentUser = (User) subject.getPrincipal(); //拿到User对象 ,强转 //设置当前用户的权限 info.addStringPermission(currentUser.getPerms()); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken Token) throws AuthenticationException { System.out.println("执行了认证"); //前端传输 封装的 UsernamePasswordToken token = (UsernamePasswordToken) Token; //连接数据,取数据 User user = userService.selUserByName(token.getUsername()); if(user==null){ return null; } //密码认证, shiro做 ,加密了 //这里的user参数传递 是为了让授权获取到 return new SimpleAuthenticationInfo(user,user.getPwd(),""); } }ShiroConfig.javapackage com.xin.config; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { //3.shiroFilterFactorybean @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); //添加shiro的内置过滤器 /* anon:无需认证就可以访问 authc:必须认证了才能访问 user:必须拥有 记住我 功能才能用 perms:拥有对某个资源的权限才能访问 role:拥有某个角色权限才能访问 */ //拦截 Map<String, String> filterMap = new LinkedHashMap<>(); //授权拦截 filterMap.put("/user/add","perms[user:add]"); filterMap.put("/user/upda","perms[user:upda]"); filterMap.put("/user/*","authc");//user下页面必须要认证后才能拿访问 bean.setFilterChainDefinitionMap(filterMap); //设置登录页面的跳转 bean.setLoginUrl("/toLogin"); //设置没有权限跳转页面 bean.setUnauthorizedUrl("/perms"); return bean; } //2.DafaultWebSecurityManger @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager SecurityManager = new DefaultWebSecurityManager(); //关联userRealm SecurityManager.setRealm(userRealm); return SecurityManager; } //1.创建 realm 对象,需要自定义 @Bean public UserRealm userRealm(){ return new UserRealm(); } }Controllerpackage com.xin.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @RequestMapping({"/","/index"}) public String toindex(Model model){ model.addAttribute("msg","Hello,shiro"); return "index"; } @RequestMapping("user/add") public String add(){ return "user/add"; } @RequestMapping("user/upda") public String upda(){ return "user/upda"; } @RequestMapping("/toLogin") public String toLogin(){ return "login"; } @RequestMapping("login") public String login(String username,String password,Model model){ //获取当前用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登录数据 UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { //执行登录方法, 如果没有异常就直接登录 subject.login(token); return "index"; }catch (UnknownAccountException e){ model.addAttribute("msg","用户名不存在"); return "login"; }catch (IncorrectCredentialsException e){ model.addAttribute("msg","密码错误!"); return "login"; } } @RequestMapping("/perms") @ResponseBody public String perms(){ return "对不起,你没有访问权限"; } }目录结构图shiro 整合 Thymeleaf导入整合依赖<dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.1.0</version> </dependency>ShiroConfig 中配置整合//整合shiro : 用来整合shiro 和 thymeleaf @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); }html页面中加上xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"前端代码<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>首页</h1> <div th:if="${session.loginUser==null}"> <a th:href="@{/toLogin}">登录</a> </div> <p th:text="${msg}"></p> <hr> <div shiro:hasPermission="user:add"> <a th:href="@{/user/add}">add</a> </div> <div shiro:hasPermission="user:upda"> <a th:href="@{user/upda}">upda</a> </div> </body> </html>
2022年03月20日
341 阅读
0 评论
0 点赞
2022-02-15
SSM框架整合
SSM框架搭建1. 新建Web Project ,导入相关jar文件{cloud title="ssmjar包" type="lz" url="https://ksxx.lanzouo.com/iQU4j006dbfg" password=""/}切面类(com.xyh.aspect)类名:ServiceAsperct.java {collapse}{collapse-item label="代码展示"}package com.xyh.aspect; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import java.util.Arrays; @Component //注入ioc容器 @Aspect //声明当前类为切面类 public class ServiceAspect { Logger logger = Logger.getLogger(ServiceAspect.class); @Pointcut("execution(* com.xyh.service..*.*(..))") public void pc(){} @Around("pc()") public Object around(ProceedingJoinPoint jp){ Object obj = null; try { logger.info("前置增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,传递的参数是:"+ Arrays.toString(jp.getArgs())); obj = jp.proceed(); logger.info("后置增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,返回的参数是:"+obj); } catch (Throwable e) { logger.info("异常抛出增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,发生的异常是"+e.getMessage()); }finally { logger.info("最终增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,主要用于是释放资源"); } return obj; } } {/collapse-item}{/collapse}实体类(com.xyh.pojo)类名:User.java {collapse}{collapse-item label="User代码"}package com.xyh.pojo; import java.util.Date; import java.util.List; public class User { private List<Address> AddressList; public List<Address> getAddressList() { return AddressList; } public void setAddressList(List<Address> addressList) { AddressList = addressList; } private Role role; public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } private int id; private String userRoleName; private String userCode; private String userName; private String userPassword; private int gender; private Date birthday; private String phone; private String address; private int userRole; private String createdBy; private String creationDate; private String modifyBy; private String modifyDate; public String getUserRoleName() { return userRoleName; } public void setUserRoleName(String userRoleName) { this.userRoleName = userRoleName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getUserRole() { return userRole; } public void setUserRole(int userRole) { this.userRole = userRole; } public String getCreatedBy() { return createdBy; } public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } public String getCreationDate() { return creationDate; } public void setCreationDate(String creationDate) { this.creationDate = creationDate; } public String getModifyBy() { return modifyBy; } public void setModifyBy(String modifyBy) { this.modifyBy = modifyBy; } public String getModifyDate() { return modifyDate; } public void setModifyDate(String modifyDate) { this.modifyDate = modifyDate; } public User() { super(); } @Override public String toString() { return "User [AddressList=" + AddressList + ", role=" + role + ", id=" + id + ", userRoleName=" + userRoleName + ", userCode=" + userCode + ", userName=" + userName + ", userPassword=" + userPassword + ", gender=" + gender + ", birthday=" + birthday + ", phone=" + phone + ", address=" + address + ", userRole=" + userRole + ", createdBy=" + createdBy + ", creationDate=" + creationDate + ", modifyBy=" + modifyBy + ", modifyDate=" + modifyDate + "]"; } } {/collapse-item}{/collapse}converter(com.xyh.converter)类名:StringToDateConverter.java {collapse}{collapse-item label="代码展示"}package com.xyh.converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; public class StringToDateConverter implements Converter<String, Date>{ private static SimpleDateFormat[] sdfs= { new SimpleDateFormat("yyyy-MM-dd"), new SimpleDateFormat("yyyy.MM.dd"), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), new SimpleDateFormat("yyyy/MM/dd"), new SimpleDateFormat("yyyy年MM月dd日"), new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"), }; @Override public Date convert(String arg0) { Date dt = null; for (int i = 0; i < sdfs.length; i++) { try { dt = sdfs[i].parse(arg0); break; } catch (ParseException e) { } } return dt; } } {/collapse-item}{/collapse}mapper(com.xyh.mapper)接口:UserMapper.java {collapse}{collapse-item label="UserMapper接口"}package com.xyh.mapper; import java.util.List; import com.xyh.pojo.User; public interface UserMapper { /** * 查询所有的用户数据 * @return */ public List<User> UserList(); } {/collapse-item}{/collapse}UserMapper.xml {collapse}{collapse-item label="UserMapper.xml"}<?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"> <!-- namespace:对应dao接口的全类名 --> <mapper namespace="com.xyh.mapper.UserMapper"> <!-- sql的id在当前文件中唯一 相当于接口的方法名 --> <select id="UserList" resultType="user"> select * from smbms_user </select> </mapper>{/collapse-item}{/collapse}service(com.xyh.service){collapse}{collapse-item label="UserService.java"} package com.xyh.service; import java.util.List; import com.xyh.pojo.User; public interface UserService { /** * 查询所有的用户数据 * @return */ public List<User> UserList(); } {/collapse-item}{/collapse}(com.xyh.service.impl){collapse}{collapse-item label="UserServiceimpl"}package com.xyh.serviceImpl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.xyh.mapper.UserMapper; import com.xyh.pojo.User; import com.xyh.service.UserService; @Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override @Transactional(propagation=Propagation.SUPPORTS,readOnly=true) public List<User> UserList() { return userMapper.UserList(); } } {/collapse-item}{/collapse}controller(com.xyh.controller)类名:Usercontroller.javapackage com.xyh.controller; import java.util.HashMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.alibaba.fastjson.JSON; import com.xyh.pojo.User; import com.xyh.service.UserService; @Controller public class UserController { @Autowired private UserService userService; @RequestMapping("selUserlist") @ResponseBody public Object selUserList(){ return userService.UserList(); } @RequestMapping(value="/userCodeYz"/*,method=RequestMethod.GET,produces={"application/json;charset=UTF-8"}*/) @ResponseBody public Object userCodeYz(@RequestParam String userCode,User user){ HashMap<String,Object> map = new HashMap<String, Object>(); if("admin".equals(userCode)){ map.put("msg", "用户名已存在!"); }else { map.put("msg", "用户名可用"); } map.put("user", user); return map; } } 2. 配置web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 处理post请求参数乱码的过滤器 --> <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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- springmvc的核心控制器 --> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- spring和springmvc整合步骤:1.设置spring上下文参数 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:ApplicationContext*.xml</param-value> </context-param> <!-- 2.监听上下文参数中的contextConfigLocation(spring配置文件路径) --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> 3. 配置文件(resources)创建resources资源文件夹创建Mybatis-config.xml文件<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置mybatis的全局属性 --> <settings> <!-- 设置自动映射级别为最高层级别 --> <setting name="autoMappingBehavior" value="FULL"/> <setting name="logImpl" value="LOG4J"/> </settings> <!-- 配置pojo全类名别名 --> <typeAliases> <!-- 指定实体类的包,其包下所有类名则均成为类型别名 --> <package name="com.xyh.pojo"/> </typeAliases> <!-- 配置mapper映射文件所在位置 --> <!-- <mappers> <mapper resource="com/xyh/mapper/UserMapper.xml"/> </mappers> --> </configuration>创建applicationContext.xml文件<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- 开启ioc注解 --> <context:component-scan base-package="com.xyh.mapper,com.xyh.service,com.xyh.serviceImpl"></context:component-scan> <!-- 配置JNDI数据源 --> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/smbms"></property> </bean> <!-- 配置sqlsessionfactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:Mybatis-config.xml"></property> <property name="mapperLocations"> <list> <value>classpath:com/xyh/mapper/*.xml</value> </list> </property> </bean> <!-- 配置dao(mapper)接口扫描,自动为其下所有接口生成mapperfactorybean实例,实例名为首字母小写的接口名 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xyh.mapper"></property> </bean> <!-- 声明事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 添加事务注解驱动 --> <tx:annotation-driven/> </beans>创建springmvc.xml文件<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- ioc注解扫描包 --> <context:component-scan base-package="com.xyh.controller"></context:component-scan> <!-- 配置格式转换器 --> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.xyh.converter.StringToDateConverter"></bean> </set> </property> </bean> <!-- mvc相关注释驱动 --> <mvc:annotation-driven conversion-service="conversionService"> <mvc:message-converters> <!-- 处理当使用json字符串返回值时,json格式中乱码问题 --> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json;charset=utf-8"></property> <property name="features"> <list> <value>WriteDateUseDateFormat</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="WEB-INF/jsp"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 配置静态资源解析器 --> <mvc:resources location="/statics/" mapping="/statics/**"/> </beans>index.jsp页面代码<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <script type="text/javascript" src="statics/js/jquery-1.8.2.min.js"></script> <script type="text/javascript"> $(function(){ $.getJSON("selUserlist","",function(userlist){ var str = ""; $(userlist).each(function(i,o){ str+="<tr>"; str+="<td>"+o.userCode+"</td>"; str+="<td>"+o.userName+"</td>"; str+="<td>"+o.birthday+"</td>"; str+="</tr>"; }) $("tbody").html(str); }) }) </script> </head> <body> <table border="1"> <thead> <tr> <th>用户编号</th> <th>用户姓名</th> <th>用户生日</th> </tr> </thead> <tbody></tbody> </table> </body> </html>
2022年02月15日
194 阅读
1 评论
0 点赞
2022-01-07
spring 结合 Mybatis
Spring和MyBatis的整合步骤1. 建立Web工程,加入Spring和MyBatis的有关jar包 {collapse} {collapse-item label="IDEA导包代码"} <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.3</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency> </dependencies>{/collapse-item} {/collapse}2. 建立开发目录结构,创建实体类 {collapse} {collapse-item label="User"}package com.xyh.pojo; import java.util.Date; import java.util.List; public class User { private List<Address> AddressList; public List<Address> getAddressList() { return AddressList; } public void setAddressList(List<Address> addressList) { AddressList = addressList; } private Role role; public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } private int id; private String userRoleName; private String userCode; private String userName; private String userPassword; private int gender; private Date birthday; private String phone; private String address; private int userRole; private String createdBy; private String creationDate; private String modifyBy; private String modifyDate; public String getUserRoleName() { return userRoleName; } public void setUserRoleName(String userRoleName) { this.userRoleName = userRoleName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getUserRole() { return userRole; } public void setUserRole(int userRole) { this.userRole = userRole; } public String getCreatedBy() { return createdBy; } public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } public String getCreationDate() { return creationDate; } public void setCreationDate(String creationDate) { this.creationDate = creationDate; } public String getModifyBy() { return modifyBy; } public void setModifyBy(String modifyBy) { this.modifyBy = modifyBy; } public String getModifyDate() { return modifyDate; } public void setModifyDate(String modifyDate) { this.modifyDate = modifyDate; } public User() { super(); } @Override public String toString() { return "User [AddressList=" + AddressList + ", role=" + role + ", id=" + id + ", userRoleName=" + userRoleName + ", userCode=" + userCode + ", userName=" + userName + ", userPassword=" + userPassword + ", gender=" + gender + ", birthday=" + birthday + ", phone=" + phone + ", address=" + address + ", userRole=" + userRole + ", createdBy=" + createdBy + ", creationDate=" + creationDate + ", modifyBy=" + modifyBy + ", modifyDate=" + modifyDate + "]"; } } {/collapse-item} {/collapse}3. 创建数据访问接口 {collapse} {collapse-item label="UserMapper.java"} package com.yxh.dao; import java.util.List; import com.xyh.pojo.User; public interface UserMapper { List<User> selUserlist(); }{/collapse-item} {/collapse}4. 创建数据访问接口的实现类 {collapse}{collapse-item label="UserMapperImpl实现类" }package com.yxh.dao; import java.util.List; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.xyh.pojo.User; @Repository public class UserMapperImpl implements UserMapper{ @Autowired private SqlSessionTemplate sqlSession; @Override public List<User> selUserlist() { return sqlSession.getMapper(UserMapper.class).selUserlist(); } }{/collapse-item}{/collapse}5. 配置SQL映射语句文件 {collapse}{collapse-item label="UserMapper.xml" }<?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.yxh.dao.UserMapper"> <select id="selUserlist" resultType="com.xyh.pojo.User"> select * from smbms_user </select> </mapper>{/collapse-item}{/collapse}6. 配置MyBatis应用配置文件 {collapse}{collapse-item label="Mabatis-config.xml"}<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置mybatis的全局属性 --> <settings> <!-- 设置自动映射级别为最高层级别 --> <setting name="autoMappingBehavior" value="FULL"/> <setting name="logImpl" value="LOG4J"/> </settings> <!-- 配置pojo全类名别名 --> <typeAliases> <!-- 指定实体类的包,其包下所有类名则均成为类型别名 --> <package name="com.xyh.pojo"/> </typeAliases> <!-- 配置mapper映射文件所在位置 --> <mappers> <mapper resource="com/yxh/dao/UserMapper.xml"/> </mappers> </configuration> {/collapse-item}{/collapse}7. 配置Spring应用配置文件 注意:spring可以配置mybatis配置文件{collapse}{collapse-item label="ApplicationContext.xml"}<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- 开启注解 --> <context:component-scan base-package="com.yxh.dao"></context:component-scan> <!-- 获取properties文件中的属性 --> <context:property-placeholder location="mysqlConn.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${driver}"></property> <property name="url" value="${url}"></property> <property name="username" value="${uname}"></property> <property name="password" value="${password}"></property> </bean> <!-- 配置sqlsessionfactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="Mybatis-config.xml"></property> </bean> <!-- 配置sqlsession --> <!-- <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg> </bean> --> <!-- 配置自动生成mapper实现类 --> <!-- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.yxh.dao.UserMapper"></property> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> --> <!-- 配置dao接口扫描,自动为其包下所有生成mapperfactorybean实例,实例名为首字母小写的接口名 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.yxh.dao"></property> </bean> </beans>{/collapse-item}{/collapse}8. 测试类 {collapse}{collapse-item label="MyTest.java"} import java.util.List; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.xyh.pojo.User; import com.yxh.dao.UserMapper; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); UserMapper usermapper = (UserMapper) context.getBean("userMapper"); List<User> selUserlist = usermapper.selUserlist(); for (User user : selUserlist) { System.out.println(user); } } } {/collapse-item}{/collapse}采用数据库映射器(MapperFactoryBean)的方式完成对数据库操作感觉Mapper接口获取Mapper对象,它封装了原有的SqlSession.getMapper()功能的实现<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!--指定映射器,只能是接口类型--> <property name="mapperInterface" value="com.yxh.dao.UserMapper"></property> <!--注入SqlSessionFactory以提供SqlSessionTemplate实例--> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>MapperScannerConfiguser自动扫描指定包下的Mapper接口,并将它们直接注册为MapperFactoryBean<!-- 配置dao接口扫描,自动为其包下所有生成mapperfactorybean实例,实例名为首字母小写的接口名 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.yxh.dao"></property> </bean>
2022年01月07日
263 阅读
0 评论
0 点赞
2022-01-06
spring IOC 和 AOP 扩展
本章目标理解构造注入理解不同数据类型的注入方法掌握p命名空间注入理解更多增强类型的使用方法掌握使用注解实现Ioc的方法掌握使用注解实现AOP的方法构造注入 编写带参构造方法后,java虚拟机不再提供默认的无参构造方法,为了保证使用的灵活性,建议自行添加一个无参构造方法Dao包public class UserDao { public void add(){ System.out.println("正在调用UserDao的add方法"); } } serivce 类package com.xyh.serivce; import com.xyh.dao.UserDao; public class UserSerivce { private UserDao userDao; private String msg; public UserSerivce() { } public UserSerivce(UserDao userDao, String msg) { this.userDao = userDao; this.msg = msg; } public void add(){ userDao.add(); System.out.println(msg); } }ApplicationContext.xml<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="userDao" class="com.xyh.dao.UserDao"></bean> <bean id="userSerivce" class="com.xyh.serivce.UserSerivce"> <constructor-arg name="msg" value="调用msg的方法"></constructor-arg> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean> </beans>{message type="success" content="设值注入"/}通过setter访问器实现灵活性好 ,但setter方法数量较多时效性差通过无参构造实例化{message type="success" content="构造注入"/}通过构造方法实现灵活性差,仅靠重载限制太多时效性好通过匹配的构造方法实例化,但建议保留无参构造{message type="warning" content="使用p命名空间注入属性值"/}p命名空间的特点:使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码使用前要先在Spring配置文件中引入p命名空间xmlns:p="http://www.springframework.org/schema/p"使用p命名空间注入属性值<!--p命令--> <bean id="userSerivce" class="com.xyh.serivce.UserSerivce" p:msg="你好!" p:userDao-ref="userDao"></bean>异常抛出增强异常抛出增强的特点 在目标方法抛出异常时织入增强处理可拔插的异常处理方案<aop:after-throwing>元素:定义异常抛出增强package com.xyh.aspect; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import java.util.Arrays; public class SerivceAspect { Logger logger = Logger.getLogger(SerivceAspect.class); public void before(JoinPoint jp){ System.out.println("前置增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,传递的参数是:"+ Arrays.toString(jp.getArgs())); } public void afterReturning(JoinPoint jp,Object res){ System.out.println("后置增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,返回的参数是:"+res); } public void afterThrowing(JoinPoint jp,Exception ex){ System.out.println("异常抛出增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,发生的异常是"+ex.getMessage()); } } xml配置 <bean id="serivceAspect" class="com.xyh.aspect.SerivceAspect"></bean> <aop:config> <aop:pointcut id="pc" expression="execution(* com.xyh.serivce..*.*(..))"/> <aop:aspect ref="serivceAspect"> <aop:before method="before" pointcut-ref="pc"/> <aop:after-returning method="afterReturning" pointcut-ref="pc" returning="res"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pc" throwing="ex"/> </aop:aspect> </aop:config>最终增强最终增强的特点:无论方法是否抛出异常,都会在目标方法最后织入增强处理 即:该增强都会的到执行类似于异常处理机制中的finally块的作用,一般用于释放资源,可以为各功能模块提供统一的,可拔插的处理方案<aop:after> 元素:定义最终增强public void after(JoinPoint jp){ System.out.println("最终增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,主要用于是释放资源"); }<aop:after method="after" pointcut-ref="pc"/>环绕增强 (强大 :结合前面的增强)特点:目标方法前后都可织入增强处理功能最强大的增强处理可获取或修改目标方法的参数,返回值,可对它进行异常处理,甚至可以决定目标方法是否执行<aop:around>元素:定义环绕增强Logger logger = Logger.getLogger(SerivceAspect.class); public Object around(ProceedingJoinPoint jp){ Object obj = null; try { logger.info("前置增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,传递的参数是:"+ Arrays.toString(jp.getArgs())); obj = jp.proceed(); logger.info("后置增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,返回的参数是:"+obj); } catch (Throwable e) { logger.info("异常抛出增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,发生的异常是"+e.getMessage()); }finally { logger.info("最终增强:进入了"+jp.getTarget()+"对象的"+jp.getSignature().getName()+"()方法,主要用于是释放资源"); } return obj; }<aop:config> <aop:pointcut id="pc" expression="execution(* com.xyh.serivce..*.*(..))"/> <aop:aspect ref="serivceAspect"> <aop:around method="around" pointcut-ref="pc"/> </aop:aspect> </aop:config> 运行截图<aop:aspectj-autoproxy> 启动@AspectJ注解驱动的切面
2022年01月06日
97 阅读
0 评论
1 点赞
1
2
...
4