spring
//依赖导入
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--springAOP aspects的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
1.spring的优点:
1.1.spring 是工厂,用于生产java实体bean。(方便解耦,简化开发 ;IOC控制翻转)
1.2.支持AOP(面向切面编程);通过横向拦截,对程序进行优化(权限拦截、运行监控功能等。。。)
1.3.支持事务的声明式管理;即通过简单的配置就可以对事物进行管理。
1.4.支持优秀框架的集成。
2.IOC 控制反转
这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,。
3.依赖注入
3.1.基于xml文件注入(基本不用)
3.1.1.setter 方法注入
3.1.2 构造器注入
<!--普通数据注入-->
setter:
<!--property 中有三个属性 name(被注入的属性的名字) ref(引用数据) value(普通属需要注入的值)-->
<bean id="userImpl" class="com.dooool.service.impl.UserServiceImpl">
<!--将dao 通过set 方法 设置给service:bookService.setBookDao(bookDao);DI
没有设置 UserServerImpl 就会报 NullPointerException
name 的值是UserServerImpl中定义的private UserDao userDao
ref 是引用bean-->
<property name="userDao" ref="userDaoId"></property>
<property name="tel" value="911"></property>
</bean>
构造方法注入:
<!-- 构造方法注入 constructor-arg中有五个属性
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
-->
<bean id="userId" class="com.itheima.f_xml.a_constructor.User" >
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
<!--集合数据注入
集合的注入都是给<property>添加子标签 <array> <list> <set> <map> Properties:<props> -->
<property name="arrayData">
<array>
<value>aa</value>
<value>bb</value>
</array>
</property>
<property name="listData">
<list>
<value>安安</value>
<value>宝宝</value>
</list>
</property>
<property name="setData">
<set>
<value>存储</value>
<value>钉钉</value>
</set>
</property>
<property name="mapData">
<map>
<entry key="jack" value="杰克"></entry>
<entry>
<key><value>aa</value></key>
<value>安安</value>
</entry>
</map>
</property>
<property name="propsData">
<props>
<prop key="aa">1</prop>
<prop key="bb">a</prop>
</props>
</property>
2.2.基于注解注入(最常使用)
使用时,在xml 文件中添加命名空间
2.2.1.类注入
@Component : 有三个衍生注解 :@Repository :dao层;@Service:service层;@Controller:web层
2.2.2.属性注入
//普通值
@Value(" ")
//引用值
@Autowired
@Qualifier("名字") //引用值起别名 可以不起(通常不使用),使用默认的名字
@Resource("名字") //等价于 @Autowired+@Qualifier("名字") 通常不使用
4.切面编程(AOP)
通俗讲,把程序运行比作是一条自高向低流动的小河,切面编程就是在需要的地方把小河断开,然后加入你自己的东西,最后让小河继续流动。
4.1.AOP实现方式
4.1.1.手动方式
(UserService + UserServiceImpl ) 目标类 + (MyAspect)切面类:通知 + 工厂类:编写工厂生成代理
MyAspect:
public class MyAspect {
public void before(){
System.out.println("鸡首");
}
public void after(){
System.out.println("牛后");
}
}
工厂类:
public class MyBeanFactory {
public static UserService createUserService(){
//目标类
final UserService userService = new UserServiceImpl();
//切面类
final MyAspect myAspect = new MyAspect();
UserService pxUserService = (UserService)Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(
Object o, Method method, Object[] objects) throws Throwable {
myAspect.befter();
Object obj = method.invoke(userService, objects);
myAspect.after();
return obj;
}
}
);
return pxUserService;
}
}
//测试
@Test
public void test2(){
UserService userService = MyBeanFactory.createUserService();
userService.insertUser();
}
4.1.2.半自动方式
spring 创建代理对象,从spring容器中手动的获取代理对象 (工厂类)
//MyAspect2
public class MyAspect2 implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("qian");
Object obj = mi.proceed();//目标方法
System.out.println("后");
return obj;
}
}
//spring.xml 配置
<!-- 1 创建目标类 -->
<bean id="impl" class="com.dooool.service.impl.UserServiceImpl"></bean>
<!-- 2 创建切面类 -->
<bean id="myAspect" class="com.dooool.aspect.MyAspect2"></bean>
<!-- 3 创建代理类 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="com.dooool.service.UserService"></property>
<property name="target" ref="impl"></property>
<property name="interceptorNames" value="myAspect"></property>
</bean>
//测试:
@Test
public void test3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(MXLPATH);
UserService userService =(UserService) applicationContext.getBean("proxyFactoryBean");
userService.insertUser();
}
4.1.3.全自动方式
<!-- 1 创建目标类-->
<bean id="userServiceImplID" class="com.dooool.service.impl.UserServiceImpl"></bean>
<!-- 2 创建切面类 -->
<bean id="myAspect" class="com.dooool.aspect.MyAspect2"></bean>
<aop:config proxy-target-class="true">
<aop:pointcut id="myPointCut" expression="execution(* com.dooool.service.impl.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"></aop:advisor>
</aop:config>
@Test
public void test4(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(MXLPATH);
UserService userService =(UserService) applicationContext.getBean("userServiceImplID");
userService.insertUser();
}
5.Spring JDBC 框架
处理Dao层 连对数据库操作(以后会被Mybatis框架取代)
传统的 JDBC 需要处理许多底层的细节 例如:加载驱动、创建连接、获取数据库操作对象、定义SQL语句、执行数据库操作、获取并操作结果集关闭对象,回收数据库资源(关闭结果集–>关闭数据库操作对象–>关闭连接)、处理异常、处理事务。
Spring JDBC 框架负责所有的低层细节,从开始打开连接,准备和执行 SQL 语句,处理异常,处理事务,到最后关闭连接都由springJDBC处理。
步骤1:
pom
<!--数据库的包 根据自己的数据库选择-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- Spring 事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
步骤:2 根据数据库字段建立实体类
步骤:3 根据数据库字段建立查询结果的返回类
/**
* 这个类定义 StudentDaoImpl_JDBCTemplate 类中的返回值
*/
public class StudentMapper implements RowMapper<Student> {
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setSid(rs.getInt("sid"));
student.setName(rs.getString("name"));
return student;
}
}
步骤:4 建立dao(可省略 ,但为了结构完整,建议保存)
public interface StudentDao {
//setter 方法的依赖注入
public void setDataSource(DataSource dataSource);
public void insertStudent(String name);
public List<Student> getListStudent();
public Student getStudent(Integer sid);
public void updateStudent(Integer sid,String name);
public void deleteStudent(Integer sid);
步骤:5 建立daoImpl_jdbcTemplate
public class StudentDaoImpl_JDBCTemplate implements StudentDao {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Override
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public void insertStudent(String name) {
String sql = "insert into student(name) values(?)";
jdbcTemplate.update(sql,name);
System.out.println("Created Record Name = " + name );
}
@Override
public List<Student> getListStudent() {
String sql = "select * from student";
List<Student> studentList = jdbcTemplate.query(sql, new StudentMapper());
return studentList;
}
@Override
public Student getStudent(Integer sid) {
String SQL = "select * from student where sid = ?";
Student student = jdbcTemplate.queryForObject(SQL, new Object[]{sid}, new StudentMapper());
return student;
}
@Override
public void updateStudent(Integer sid, String name) {
String SQL = "update student set name = ? where sid = ?";
jdbcTemplate.update(SQL, name, sid);
System.out.println("Updated Record with ID = " + sid );
}
@Override
public void deleteStudent(Integer sid) {
String SQL = "delete from student where sid = ?";
jdbcTemplate.update(SQL, sid);
System.out.println("Deleted Record with ID = " + sid );
}
}
步骤:6 配置spring.xml文件
<!-- 定义数据库连接 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
<property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=test"></property>
<property name="username" value="sa"></property>
<property name="password" value="root"></property>
</bean>
<!-- 把数据库注入到类中 -->
<bean id="studentDaoImpl_JDBCTemplate" class="com.dooool.dao.impl.StudentDaoImpl_JDBCTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
步骤:7 测试
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentDaoImpl_JDBCTemplate sj = (StudentDaoImpl_JDBCTemplate) applicationContext.getBean("studentDaoImpl_JDBCTemplate");
sj.insertStudent("张三");
sj.insertStudent("lisi");
System.out.println("===insert");
Student student1 = sj.getStudent(1);
System.out.println(student1.getSid() + student1.getName());
System.out.println("===get");
List<Student> listStudent = sj.getListStudent();
for(Student student : listStudent){
System.out.println(student.getSid());
System.out.println(student.getName());
}
System.out.println("===getlist");
}
6.事务管理
1.按管理范围分:
1.1.局部事务管理(集中的环境,如一个系统)
1.2.全局事务管理(分布式环境,多个系统)
2.按管理方式:
2.1.编程式:自己编写程序进行 事务管理 (一般不使用)
2.2.声明式 : 使用注释或XML配置事务管理 (推荐使用)
编程式事务管理拥有极大的灵活性,可以根据自己的意愿进行管理,但维护起来困难。
声明式事务管理把代码抽取出来,通过配置,使操作更为简单。
声明式:
步骤 1:创建两个数据库a,b,a的主键为b的外键;
步骤 2:创建a、b的实体类,a和b 的属性都放在一个实体类中;
public class StudentScore {
private Integer sid;
private String name;
private Integer cid;
private Integer csno;
private Integer math_score;
private Integer chinese_score;
}//省略get、set
步骤 3:根据数据库字段建立查询结果的返回类(参考Spring JDBC步骤3)
步骤 4:定义Dao层;
public interface StudentScoreDao {
void setDataSource(DataSource dataSource);
void insertStudentScore(String name, Integer math_score,Integer chinese_score);
List<StudentScore> getListStudentScore();
}
步骤 5:实现Dao
public class SCDaoImpl_JDBCTemplate implements StudentScoreDao {
private JdbcTemplate jdbcTemplate;
@Override
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public void insertStudentScore(String name, Integer math_score, Integer chinese_score) {
try {
String sql1 = "insert into student(name) values(?)";
jdbcTemplate.update(sql1,name);
String sql2 = "select max(sid) from student";
//把String类型的数据转换为int类型
// int a = 10/0;
int csno = jdbcTemplate.queryForObject(sql2,Integer.class);
String sql3 = "insert into score(csno,math_score,chinese_score) values(?,?,?)";
jdbcTemplate.update(sql3,csno,math_score,chinese_score);
} catch (Exception e) {
System.out.println("Error in creating record, rolling back");
throw e;
}
}
@Override
public List<StudentScore> getListStudentScore() {
return null;
}
步骤 6:配合Spring.XML 文件
注意:在xml文件头添加约束
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
<!-- 连接数据库 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
<property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=test"></property>
<property name="username" value="sa"></property>
<property name="password" value="root"></property>
</bean>
<!-- 声明式事务管理 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insertStudentScore"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="insert" expression="execution(* com.dooool.dao.impl.SCDaoImpl_JDBCTemplate.insertStudentScore(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="insert"></aop:advisor>
</aop:config>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="scDaoImpl_jdbcTemplate" class="com.dooool.dao.impl.SCDaoImpl_JDBCTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
步骤 7 : 测试:
@Test
public void test2(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
//注意:此处使用Dao层的接口
StudentScoreDao sj = (StudentScoreDao)
applicationContext.getBean("scDaoImpl_jdbcTemplate");
sj.insertStudentScore("孙海东",100,100);
sj.insertStudentScore("孙海东1",100,100);
sj.insertStudentScore("孙海东2",100,100);
System.out.println("===insert");
}
在集合SSM框架后就只用配置XML文件就可以了。
在学习中参考了https://www.w3cschool.cn/wkspring/by1r1ha2.html。