<?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.xsd">
<bean id="userDao" class="com.woniu.dao.impl.UserDaoImpl" />
<bean id="userService" class="com.woniu.service.impl.UserServiceImpl" />
</beans>
1.Mybatis注解开发-补充讲解
(1) SQL语句映射注解
@Insert @Select @Update @Delete
@Options
[略]
(2) 结果集映射注解
@Results @Result @ResultMap
@ResultMap注解用于引用@Results声明的id名
@Select("select * from smbms_user")
@Results(id="userResultMap",value={
@Result(column = "user_name",property = "userName")
})
List<User> queryUserList();
@Select("select * from smbms_user where id=#{id}")
@ResultMap("userResultMap") // 引用已有的userResultMap
User queryUserById(Integer id);
测试类 :
package com.woniu.dao.test;
import com.woniu.dao.UserDao;
import com.woniu.entity.User;
import com.woniu.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
private UserDao userDao = null;
private SqlSession sqlSession = null;
@Before
public void setUp(){
sqlSession = MyBatisUtil.getSession();
userDao=sqlSession.getMapper(UserDao.class);
}
@After
public void tearDown(){
sqlSession.commit();
System.out.println("执行OK... ");
sqlSession.close();
}
@Test
public void testAddUser(){
User user = new User();
user.setUserCode("Tom");
user.setUserName("汤姆");
user.setUserPassword("111");
user.setGender(1);
user.setBirthday("2000-11-15");
user.setRoleid(3);
userDao.add(user);
System.out.println("获取新增后的主键 id:"+user.getId());
}
@Test
public void testQueryUserList(){
List<User> userList = userDao.queryUserList();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testQueryUserById(){
User user = userDao.queryUserById(1);
System.out.println(user);
}
}
(3) 关系映射注解
@One ,@Many
一对一查询: 根据用户查询关联角色
public interface UserDao {
@Insert("insert into smbms_user(userCode,user_name,userPassword,gender,birthday,roleid) " +
"values(#{userCode},#{userName},#{userPassword},#{gender},#{birthday},#{roleid})")
@Options(useGeneratedKeys=true,keyProperty = "id",keyColumn = "id")
void add(User user);
@Select("select * from smbms_user")
@Results(id="userResultMap",value={
@Result(id=true,column = "id",property = "id"),
@Result(column = "userCode",property = "userCode"),
@Result(column = "user_name",property = "userName"),
@Result(property = "role",column = "roleid",
one=@One(select = "com.woniu.dao.RoleDao.getRoleById",fetchType = FetchType.LAZY))
})
List<User> queryUserList();
@Select("select * from smbms_user where id=#{id}")
@ResultMap("userResultMap") // 引用已有的userResultMap
User queryUserById(Integer id);
@Select("select * from smbms_user where roleid=#{roleid}")
@ResultMap("userResultMap")
List<User> queryUserListByRoleid(Integer roleid);
}
public interface RoleDao {
@Select("select * from smbms_role where id=#{id}")
@Results(id="roleResultMap",value={
@Result(id=true,column = "id",property = "id"),
@Result(column = "roleCode",property = "roleCode"),
@Result(column = "roleName",property = "roleName"),
@Result(property = "userList",column = "id",
many=@Many(select = "com.woniu.dao.UserDao.queryUserListByRoleid",fetchType = FetchType.LAZY))
})
public Role getRoleById(Integer id);
}
2.Spring-IOC
2-1 Spring入门
(1) Spring的基本概念
Spring生态 "Spring 全家桶" - 企业级应用实现的三层 -- SpringJDBC,Spring事务, AOP,SpringMVC表示层框架
背景
Spring 轻便、灵巧,易于开发、测试和部署的轻量级开发框架
Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版
一个轻量级的Java开发框架----Spring便兴起;其目的就是为了简化JavaEE的企业级应用开发。
Spring发展历程:
第一阶段:XML配置
|-在Spring1.x时代
第二阶段: 注解
|-Spring2.x 时代 大大减少了配置量
XML + 注解
第三阶段:Java配置 --- SpringBoot
|-spring3.x 以后 注解 + Java配置类 [@Configuration]
spring4.x --> spring5.x
Spring的定义与优点
定义:
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源open source框架,
Spring两大核心特性: IOC 和 AOP
以 IoC(Inverse Of Control:控制反转)和 AOP(Aspect Oriented Programming:面向切面编程)提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架
spring优点:
方便解耦,简化开发
AOP编程的支持
声明式事务的支持 --@Transactional
集成各种优秀的框架
Java 源码是经典学习范例
(2) Ioc概念与作用
a.什么是程序的耦合
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量
在软件工程中,耦合指的就是就是对象之间的依赖性 。对象之间的耦合越高,维护成本越高。
划分模块的一个准则就是高内聚低耦合。
b.降低程序间耦合的方式:
方式一: 反射
方式二: 工厂模式解藕
在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来 并存起来Map。在接下来的使用的时候,直接拿过来用就好了。那么,这个读取配置文件,创建和获取三层对象的类就是工厂。
c. 示例:环境代码
持久层接口与实现类
public interface UserDao {
public void save();
}
import com.woniu.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("保存了用户");
}
}
业务层接口与实现类
public interface UserService {
public void addUser();
}
/**
* 用户业务实现类
*/
public class UserServiceImpl implements UserService {
//创建数据层对象
private UserDao userDao = new UserDaoImpl();
public void addUser() {
//执行数据操作方法
userDao.save();
}
}
业务测试类--模拟表示层代码
/**
* 业务测试类 --模拟表示层
*/
public class UserServiceTest {
@Test
public void testAddUser(){
UserService userService = new UserServiceImpl();
userService.addUser();
}
}
创建bean.properties配置文件
userDao=com.woniu.dao.impl.UserDaoImpl
userService=com.woniu.service.impl.UserServiceImpl
创建工厂类
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 工厂类
*/
public class BeanFactory {
private static Map<String,Object> beansMap = null;
static{
try {
//读取属性配置文件
Properties props = new Properties();
InputStream inStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(inStream);
inStream.close();
//初始化容器
beansMap = new HashMap<>(); //创建容器对象
Enumeration<Object> keys = props.keys();
while(keys.hasMoreElements()){
String key = keys.nextElement().toString();
String className = props.getProperty(key);
//将对象添加到Map容器中
beansMap.put(key,Class.forName(className).newInstance());
}
System.out.println("初始化容器成功....");
} catch (Exception e) {
e.printStackTrace();
System.out.println("初始化容器失败!");
}
}
/**
* 获取容器中指定的对象
* @param name
* @return
*/
public static Object getBean(String name){
return beansMap.get(name);
}
}
业务测试类与业务类代码
/**
* 业务测试类 --模拟表示层
*/
public class UserServiceTest {
@Test
public void testAddUser(){
// UserService userService = new UserServiceImpl();
UserService userService = (UserService)BeanFactory.getBean("userService");
userService.addUser();
}
}
/**
* 用户业务实现类
*/
public class UserServiceImpl implements UserService {
//创建数据层对象
// private UserDao userDao = new UserDaoImpl();
private UserDao userDao = (UserDao)BeanFactory.getBean("userDao");
public void addUser() {
//执行数据操作方法
userDao.save();
}
}
结论: 被注释的部分就是我们程序中的耦合体现。而下面的通过 BeanFactory 中 getBean 方法获取对象就解决了我们代码中对具体实现类的依赖。降低代码的耦合性.
d.控制反转—Inversion Of Control
调用者对被调用者的使用时,不用去创建被调用者对象,而由统一容器来提供,这种编程思想我们称为控制反转IOC
IOC优点:降低了程序耦合
在Spring中实现IOC的技术手段为DI 【依赖注入】
(3) 搭建spring环境与bean的配置
step1: 创建 maven不选骨架的java项目模块
step2:pom.xml添加相关依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.woniu</groupId>
<artifactId>spring-demo01-ioc</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
step3:准备相关的dao,service层及业务测试类代码
/**
* 用户业务实现类
*/
public class UserServiceImpl implements UserService {
//创建数据层对象
private UserDao userDao;
public void addUser() {
//执行数据操作方法
userDao.save();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
step4:编写spring的核心配置文件: 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.xsd">
<bean id="userDao" class="com.woniu.dao.impl.UserDaoImpl" />
<bean id="userService" class="com.woniu.service.impl.UserServiceImpl" />
</beans>
step5:在业务测试类,创建BeanFactory工厂,并获取容器中的Bean对象
/**
* 业务测试类 --模拟表示层
*/
public class UserServiceTest {
@Test
public void testAddUser(){
//创建工厂Bean对象
BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml");
// UserService userService = new UserServiceImpl();
UserService userService = (UserService)beanFactory.getBean("userService");
UserService userService2 = (UserService)beanFactory.getBean("userService");
System.out.println(userService==userService2);
userService.addUser();
}
}
问题:上面的示例中,我们的执行时会发生NullPointerException空指针异常
解决办法:在applicationContext.xml配置setter依赖注入方式,为UserServiceImpl属性注入userDao 对象
<?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.xsd">
<bean id="userDao" class="com.woniu.dao.impl.UserDaoImpl" />
<bean id="userService" class="com.woniu.service.impl.UserServiceImpl">
<!--依赖注入 使用setter -->
<property name="userDao" ref="userDao" />
</bean>
</beans>