day62 JavaWeb框架阶段—— Mybatis的注解开发&SSM框架整合(原始方式整合&Spring整合MyBatis& MyBatis的注解实现复杂映射开发)
今日内容
- Mybatis的注解开发
- SSM框架整合
今日源码:
链接:https://pan.baidu.com/s/1MNV1nB4F6s5KuF3MnqLVmw
提取码:g0er
Mybatis的注解开发
1.1 MyBatis的常用注解
这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper
映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
1.2 MyBatis的增删改查
我们完成简单的user表的增删改查的操作
private UserMapper userMapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testAdd() {
User user = new User();
user.setUsername("测试数据");
user.setPassword("123");
user.setBirthday(new Date());
userMapper.add(user);
}
@Test
public void testUpdate() throws IOException {
User user = new User();
user.setId(16);
user.setUsername("测试数据修改");
user.setPassword("abc");
user.setBirthday(new Date());
userMapper.update(user);
}
@Test
public void testDelete() throws IOException {
userMapper.delete(16);
}
@Test
public void testFindById() throws IOException {
User user = userMapper.findById(1);
System.out.println(user);
}
@Test
public void testFindAll() throws IOException {
List<User> all = userMapper.findAll();
for(User user : all){
System.out.println(user);
}
}
修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可
<mappers>
<!--扫描使用注解的类-->
<mapper class="cn.wbslz.mapper.UserMapper"></mapper>
</mappers>
或者指定扫描包含映射关系的接口所在的包也可以
<mappers>
<!--扫描使用注解的类所在的包-->
<package name="cn.wbslz.mapper"></package>
</mappers>
1.3 MyBatis的注解实现复杂映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置
1.4 一对一查询
1.4.1 一对一查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
1.4.2 一对一查询的语句
对应的sql语句:
select * from orders;
select * from user where id=查询出订单的uid;
查询的结果如下:
1.4.3 创建Order和User实体
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
1.4.4 创建OrderMapper接口
public interface OrderMapper {
List<Order> findAll();
}
1.4.5 使用注解配置Mapper
public interface OrderMapper {
/**
* 一对一查询
* 两张表分开查
* @return
*/
@Select("select * from orders")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "ordertime",property = "ordertime"),
@Result(column = "total",property = "total"),
@Result(
property = "user", //要封装的属性名称
column = "uid", //根据那个字段去查询user表的数据
javaType = User.class, //要封装的实体类型
//select属性 代表查询那个接口的方法获得数据
one = @One(select = "cn.wbslz.mapper.UserMapper.findById")
)
})
public List<Order> findAll();
}
public interface UserMapper {
@Select("select * from user where id=#{id}")
User findById(int id);
}
1.4.6 测试结果
@Test
public void testfindAll(){
List<Order> all = mapper.findAll();
for (Order order:all){
System.out.println(order);
}
}
1.5 一对多查询
1.5.1 一对多查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
1.5.2 一对多查询的语句
对应的sql语句:
select * from user;
select * from orders where uid=查询出用户的id;
查询的结果如下:
1.5.3 修改User实体
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List<Order> orderList;
}
1.5.4 创建UserMapper接口
List<User> findUserAndOrderAll();
1.5.5 使用注解配置Mapper
public interface UserMapper {
/**
* 一对多查询
* @return
*/
@Select("select * from user")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(
property = "orderList",
column = "id",//SELECT * FROM USER 查询结果的id作为查询条件参数
javaType = List.class,
many = @Many(select = "cn.wbslz.mapper.OrderMapper.findByUid")
)
}
)
public List<User> findUserAndOrderAll();
}
public interface OrderMapper {
@Select("select * from orders where uid=#{uid}")
List<Order> findByUid(int uid);
}
1.5.6 测试结果
@Test
public void findUserAndOrderAll(){
List<User> userAndOrderAll = mapper.findUserAndOrderAll();
for (User user:userAndOrderAll){
System.out.println(user);
}
}
1.6 多对多查询
1.6.1 多对多查询的模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色
1.6.2 多对多查询的语句
对应的sql语句:
select * from user;
select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=用户的id
查询的结果如下:
1.6.3 创建Role实体,修改User实体
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List<Order> orderList;
//代表当前用户具备哪些角色
private List<Role> roleList;
}
public class Role {
private int id;
private String rolename;
}
1.6.4 添加UserMapper接口方法
List<User> findUserAndRoleAll();
1.6.5 使用注解配置Mapper
public interface UserMapper {
/**
* 多对多查询
* @return
*/
@Select("SELECT * FROM USER")
@Results({
@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "password",property = "password"),
@Result(
property = "roleList",
column = "id",//SELECT * FROM USER 查询结果的id作为查询条件参数
javaType = List.class,
many = @Many(select = "cn.wbslz.mapper.RoleMapper.findByUid")
)
})
public List<User> findUserAndRoleAll();
public interface RoleMapper {
@Select("select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=#{uid}")
List<Role> findByUid(int uid);
}
1.6.6 测试结果
@Test
public void findUserAndRoleAll(){
List<User> userAndRoleAll = mapper.findUserAndRoleAll();
for (User user:userAndRoleAll){
System.out.println(user);
}
}
SSM框架整合
1.1 原始方式整合
1.准备工作
2.创建Maven工程
3.导入Maven坐标
<dependencies>
<!--数据库驱动和连接池-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--spring相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<!--Servlet和jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
<!--json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.8</version>
</dependency>
<!--文件上传和下载-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<!--日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--自定义类型处理相关-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.14</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
4.编写实体类
public class Account {
private int id;
private String name;
private double money;
//省略getter和setter方法
}
5.编写Mapper接口
public interface AccountMapper {
//保存账户数据
void save(Account account);
//查询账户数据
List<Account> findAll();
}
6.编写Service接口
public interface AccountService {
void save(Account account); //保存账户数据
List<Account> findAll(); //查询账户数据
}
7.编写Service接口实现
@Service("accountService")
public class AccountServiceImpl implements AccountService {
public void save(Account account) {
SqlSession sqlSession = MyBatisUtils.openSession();
AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);
accountMapper.save(account);
sqlSession.commit();
sqlSession.close();
}
public List<Account> findAll() {
SqlSession sqlSession = MyBatisUtils.openSession();
AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);
return accountMapper.findAll();
}
}
8.编写Controller
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping("/save")
@ResponseBody
public String save(Account account){
accountService.save(account);
return "save success";
}
@RequestMapping("/findAll")
public ModelAndView findAll(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("accountList");
modelAndView.addObject("accountList",accountService.findAll());
return modelAndView;
}
}
9.编写添加页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>保存账户信息表单</h1>
<form action="${pageContext.request.contextPath}/account/save" method="post">
用户名称<input type="text" name="name"><br/>
账户金额<input type="text" name="money"><br/>
<input type="submit" value="保存"><br/>
</form>
</body>
</html>
10.编写列表页面
<table border="1">
<tr>
<th>账户id</th>
<th>账户名称</th>
<th>账户金额</th>
</tr>
<c:forEach items="${accountList}" var="account">
<tr>
<td>${account.id}</td>
<td>${account.name}</td>
<td>${account.money}</td>
</tr>
</c:forEach>
</table>
11.编写相应配置文件(看源码)
•Spring配置文件:applicationContext.xml
<!--组件扫描 扫描service和mapper-->
<context:component-scan base-package="cn.wbslz">
<!--排除controller的扫描-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
•SprngMVC配置文件:spring-mvc.xml
<!--组件扫描 主要扫描controller-->
<context:component-scan base-package="cn.wbslz.controller"></context:component-scan>
<!--配置MVC注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--内部资源视图解析器-->
<bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--开放静态资源访问权限-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
•MyBatis映射文件:AccountMapper.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="cn.wbslz.mapper.AccountMapper">
<insert id="save" parameterType="account">
insert into account values(#{id},#{name},#{money})
</insert>
<select id="findAll" resultType="account">
select * from account
</select>
</mapper>
•MyBatis核心文件:sqlMapConfig.xml
<!--原始方式整合时所用文件-->
<!--通过properties标签加载外部properties文件-->
<properties resource="jdbc.properties"></properties>
<!--定义别名-->
<typeAliases>
<!--<typeAlias type="cn.wbslz.domain.Account" alias="account"></typeAlias>-->
<!--扫包方式 当前包下实体名称首字母小写-->
<package name="cn.wbslz.domain"/>
</typeAliases>
<!--数据源环境-->
<environments default="developement">
<environment id="developement">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射-->
<mappers>
<!-- <mapper resource="cn/wbslz/mapper/AccountMapper.xml"></mapper>-->
<!--扫包方式-->
<package name="cn/wbslz/mapper"/>
</mappers>
•数据库连接信息文件:jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=GMT%2B8&useSSL=false
jdbc.username=root
jdbc.password=密码
•Web.xml文件:web.xml
<!--spring监听器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--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:spring-mvc.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>
<!--乱码过滤器-->
<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>
•日志文件:[log4j.xml](
12.测试添加账户
13.测试账户列表
1.2 Spring整合MyBatis
1.整合思路
2.将SqlSessionFactory配置到Spring容器中
<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置MyBatis的SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
</bean>
3.扫描Mapper,让Spring容器产生Mapper实现类
<!--配置Mapper扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.wbslz.mapper"/>
</bean>
4.配置声明式事务控制
<!--配置声明式事务控制-->
<!--平台事务管理器-->
<bean id="transacionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务增强-->
<tx:advice id="txAdvice" transaction-manager="transacionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--事务aop织入-->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* cn.wbslz.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
5.修改Service实现类代码
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
public void save(Account account) {
accountMapper.save(account);
}
public List<Account> findAll() {
return accountMapper.findAll();
}
}
6.完成
上一篇: GO语言入门 - 开发环境搭建