mybatis,thymeleaf,shiro及基本用法
创建项目
创建SpringBoot项目,Java版本选择java8
依赖选择:
配置
把资源文件夹下面的application.properties文件后后缀改为.yml(也可以不改,但写法会不一样,个人觉得.yml比较方便)
在资源文件夹下新建mapper文件夹
application.yml里填写:
server:
port: 8081 #配置端口
spring:
#数据库连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: 123456
thymeleaf:
mode: HTML
cache: false
mybatis:
type-aliases-package: com.blog.demo.entity
mapper-locations: classpath:mapper/*.xml #映射文件存放的地方
configuration:
map-underscore-to-camel-case: true #开启驼峰命名
点击运行,浏览器访问localhost:8081出现下图则配置完成。
MyBatis基本用法
以用户和订单为例,一个用户对应多个订单,一个订单只有一个用户,
建表语句:
CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = INNODB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
CREATE TABLE `order` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`user_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = INNODB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
需要5个文件:java实体类,xml映射文件,java映射文件对应的接口,服务接口,服务接口的实现类。
在application启动类的同级包
新建dao包,新建接口UserDao,OrderDao,并加上注解@Mapper和@Repository
entity包,新建类User,Order
service包,新建接口UserService,OrderService并加上注解@Service
service包下新建Impl包,新建类实现接口service中的接口,名为UserServiceImpl,OrderServiceImpl
resource文件夹下新建mapper文件夹,新建UserMapper.xml,OrderMapper.xml
代码:
- UserDao:
import com.blog.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserDao {
User selectUserByuserName(String userName);
}
- OrderDao:
import com.blog.demo.entity.Order;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface OrderDao {
//只做增加和查询就好了,删除修改也差不多一样的
//增
void addOrder(Order order);
//查
List<Order> selectAllOrder();
}
Alt+Ins插入get和set和toString方法,太占篇幅了这里省略
- User:
public class User {
Long id;
String userName;
String password;
}
- Order:
public class Order {
Long id;
Long userId;
String name;
}
- UserService:
import com.blog.demo.entity.User;
public interface UserService {
User selectUserByuserName(String userName);
}
- OrderService:
import com.blog.demo.entity.Order;
import java.util.List;
public interface OrderService {
//增
void addOrder(Order order);
//查
List<Order> selectAllOrder();
}
- UserServiceImpl:
import com.blog.demo.dao.UserDao;
import com.blog.demo.entity.User;
import com.blog.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public User selectUserByuserName(String userName) {
return userDao.selectUserByuserName(userName);
}
}
- OrderServiceImpl:
import com.blog.demo.dao.OrderDao;
import com.blog.demo.entity.Order;
import com.blog.demo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
OrderDao orderDao;
@Override
public void addOrder(Order order) {
if(order!=null){
orderDao.addOrder(order);
}
}
@Override
public List<Order> selectAllOrder() {
return orderDao.selectAllOrder();
}
}
- UserMapper:
<?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.blog.demo.dao.UserDao">
<select id="selectUserByuserName" resultType="com.blog.demo.entity.User">
select * from test.user u where u.userName=#{userName}
</select>
</mapper>
- OrderMapper:
<?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.blog.demo.dao.OrderDao">
<insert id="addOrder" parameterType="com.blog.demo.entity.Order">
insert into test.order (name,user_id) values(#{name},#{userId})
</insert>
<select id="selectAllOrder" resultType="com.blog.demo.entity.Order">
select * from test.order
</select>
</mapper>
映射文件编写注意事项:
<?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="映射接口路径">
<!--如果需要返回的类型的数据与数据库中的表结构不一样,则需要写一个resultMap和建一个对应的类以及在Dao包和Service包下的映射方法,然后parameterType=该resultMap的id,例如要返回的是订单+用户名-->
<resultMap id="OrderAndUser" type="com.blog.demo.entity.OrderAndUserName">
<id property="id" column="id"/>
<result property="orderName" column="name"/>
<result property="username" column="username"/>
</resultMap>
<select id="getOrderAndUserName" resultMap="OrderAndUser">
select o.name,u.username from test.order o,test.user u where o.user_id=u.id
</select>
<insert(操作) id="接口中对应的方法名" parameterType="参数类型,像Java基本数据类型和String可以不指定" resultType="返回类型,是基本类型也要指定,如查询文章数 返回Long 需要指定为java.lang.Long">
查询语句
</insert>
</mapper>
public class OrderAndUserName {
int id;
String orderName;
String username;
}
用法:
@Autowrited
UserService userService;
userService.selectUserByuserName(userName);
shiro配置及基本用法:
引入shiro,pow文件添加:
<!-- 引入shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
anon | 不需要认证就可直接访问 |
---|---|
authc | 认证后才可访问 |
logout shiro | 退出登录 |
roles | 拥有某角色后才可以使用 |
在启动类同级目录下新建shiro包,新建两个类:
ShiroConfig:
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 {
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
Map<String,String> filterMap = new LinkedHashMap<String,String>();
//设置拦截
filterMap.put("/loginPage","anon");
filterMap.put("/tologin","anon");
filterMap.put("/index","authc");
//设置登录页面
shiroFilterFactoryBean.setLoginUrl("/loginPage");
//设置登陆成功页面
shiroFilterFactoryBean.setSuccessUrl("/index");
//设置登录失败页面
shiroFilterFactoryBean.setUnauthorizedUrl("/loginPage");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
@Bean(name = "getDefaultWebSecurityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean(name = "getRealm")
public UserRealm getRealm(){
return new UserRealm();
}
}
UserRealm:
import com.myblog.entity.User;
import com.myblog.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//执行授权逻辑
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑");
return null;
}
//执行认证逻辑
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String userName = token.getUsername();
//从数据库获取用户信息
User user=userService.selectUserByuserName(userName);
if(user==null){
return null;
}
//验证密码并保存当前登录用户
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
在templates文件夹下新建html页面:
login:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<div>
<form action="tologin" method="post">
<input name="username" placeholder="用户名">
<input name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
</div>
</body>
</html>
index:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
<div>
登录成功
</div>
</body>
</html>
在启动类同级包下新建controller包,新建IndexController类:
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class IndexController {
@GetMapping("loginPage")
String loginPage(){
return "login";
}
//这里参数名要和前端传进来的input的name值一样
@PostMapping("tologin")
String login(String username, String password){
if(username==null || password==null){
System.out.println("账号或密码为空");
return "redirect:loginPage";
}
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
try{
// 这里执行UserRealm里的认证方法
subject.login(token);
}catch (UnknownAccountException e){
System.out.println("用户不存在");
return "redirect:loginPage";
}catch (IncorrectCredentialsException e){
System.out.println("密码错误");
return "redirect:loginPage";
}
return "redirect:index";
}
@GetMapping("index")
String index(){
return "index";
}
}
在数据库插入一个用户信息:
INSERT INTO USER (username,PASSWORD) VALUES('WWFWT','123456');
运行项目,测试登录(端口没自己定义的话默认8080)
浏览器访问localhost:8081/index会访问到登录页面而不是登陆成功页面,只有账号密码正确才能访问到登陆成功页面
thymeleaf基本使用:
插入几个订单数据:
INSERT INTO `order` (NAME,user_id) VALUES('牙膏',2);
INSERT INTO `order` (NAME,user_id) VALUES('牙刷',2);
INSERT INTO `order` (NAME,user_id) VALUES('毛巾',2);
修改index页面:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
<div>
<h2>单表查询</h2>
<table border="1">
<tr bgcolor="#deb887">
<td>订单</td>
</tr>
<tr th:each="order:${orderList}">
<td th:text="${order.name}">菜刀</td>
</tr>
</table>
<h2>多表查询</h2>
<table border="1">
<tr bgcolor="#deb887">
<td>订单</td>
<td>用户</td>
</tr>
<tr th:each="orderInfo:${orderInfos}">
<td th:text="${orderInfo.orderName}">菜刀</td>
<td th:text="${orderInfo.username}">张三</td>
</tr>
</table>
<a href="#" th:href="@{https://www.ykhcomeon.top}" target="_blank">链接</a>
</div>
</body>
</html>
修改index方法:
@Autowired
OrderService orderService;
@GetMapping("index")
String index(Model model){
List<Order> orderList=orderService.selectAllOrder();
List<OrderAndUserName> orderAndUserNames=orderService.getOrderAndUserName();
//这里第一个参数名字要和前端的对应
model.addAttribute("orderList",orderList);
model.addAttribute("orderInfos",orderAndUserNames);
return "index";
}
其中:
th:元素属性(可以指定元素某些属性,如text,href,src)
th:each(遍历)
@{链接}
$ {值}
|字符串|(用法如:@{|$ {v1}+KaTeX parse error: Expected 'EOF', got '}' at position 6: {v2}|}̲,如果v1为https://,… {v1}+${v2}|}"最终得到的是 href=“https://www.ykhcomeon.top”)
运行登录结果: