SpringBoot讲解一:搭建SSM项目+Thymeleaf+HikariCP

本次技术使用Springboot框架开发项目,具体使用到了国内项目开发中常见的SSM框架,springboot推荐使用的Thymeleaf模板引擎和HikariCP数据库连接池。

本次业务上做一个简单的员工管理系统,完成员工与部门的关联关系,具备基本的展示与新增功能,旨在通过本项目切入以上技术的项目搭建与使用。

首先使用IDEA创建springboot项目

选中devtools,springmvc即可,也可以直接选上mybatis、mysql、thymeleaf
在这里插入图片描述

pom.xml加入Mybatis依赖

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

这里要注意,项目中加入了mybatis依赖,启动项目会报没有配置数据源的错:
在这里插入图片描述
解决以上问题,需要在yml中配置数据源,先把Thymeleaf依赖都加上,HikariCP在Springboot2.0后自带了,不需要在pom中加入,配置声明式事务需要用到@Aspect,所以还要加入spring的AOP依赖,此时完整的pom.xml依赖为:

   <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>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

项目结构:
在这里插入图片描述
yml:

spring:
  datasource:
    username: root
    password: 123
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/company?serverTimezone=UTC&characterEncoding=UTF-8
    #数据库连接池
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimum-idle: 8
      maximum-pool-size: 20
      auto-commit: true
      idle-timeout: 30000
      pool-name: DatebookHikariCP
      max-lifetime: 1800000
      connection-timeout: 3000000
      connection-test-query: select 1
#热部署
  thymeleaf:
    cache: false
    mode: HTML5
  #热部署
  devtools:
    restart:
      enabled: true
    #mvc:
    #static-path-pattern: /static/**
server:
  port: 8090
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.qr.empboot.entity

初学者如果不想用数据库连接池,可以直接去以上关于Hikari配置去掉即可,不影响使用。

启动类,需要注意的是要加上@MapperScan注解,告诉要扫表的MyBatis的Mapper文件所在位置:

@SpringBootApplication
//@ComponentScan("com.qr.empboot")
@MapperScan("com.qr.empboot.dao")
public class EmpbootApplication {
	public static void main(String[] args) {
	    SpringApplication.run(EmpbootApplication.class, args);
	}
}

实体类

public class Employee {
    private int id;
    private String name;
    private String sex;
    private int age;
    private Department dep;
    public Employee() {
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Department getDep() {
        return dep;
    }
    public void setDep(Department dep) {
        this.dep = dep;
    }
}
public class Department {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

springmvc

@Controller
public class EmployeeController {
    @Autowired
    EmployeeService empService;
    @Autowired
    DepartmentService departmentService;
    @RequestMapping("add")
    private String add(Employee emp) {
        boolean flag = empService.add(emp);
        if (flag) {
            return "redirect:emp";
        } else {
            return "redirect:showAdd";
        }

    }

    @RequestMapping("update")
    private String update(Employee emp) {
        boolean flag = empService.update(emp);
        if (flag) {
            return "redirect:emp";
        } else {
            return "redirect:showUpdate";
        }
    }

    @RequestMapping("delete")
    private String delete(int id) {
        boolean flag = empService.delete(id);
        return "redirect:emp";


    }
    @RequestMapping("showAdd")
    private ModelAndView showAdd(ModelAndView mv) {
        List<Department> deps = departmentService.search();
        mv.setViewName("add");
        mv.addObject("deps",deps);
        return mv;
    }
    @RequestMapping("showUpdate")
    private ModelAndView showUpdate(int id) {
        ModelAndView mv = new ModelAndView("update");
        List<Department> depList = departmentService.search();
        //Employee emp = empService.search(id);
        Employee emp = empService.searchEmpAndDep2(id);
        mv.addObject("emp", emp);
        return mv;
    }

    @RequestMapping("search")
    public ModelAndView search() {
        ModelAndView mv = new ModelAndView("emp");
        List<Employee> list = empService.search();
        list.add(new Employee());
        mv.addObject("list", list);
        return mv;
    }

    @RequestMapping("testJson")
    @ResponseBody
    public List<Employee> testJson() {
        List<Employee> list = empService.search();
        return list;
    }
}

dao层

@Repository
public interface EmployeeDao {
    public List<Employee> search();
    public Employee  searchEmpAndDep(int id);
    public int add(Employee emp);
    public Employee searchById(int id);
    public int update(Employee emp);
    public int delete(int id);
    Employee searchEmpAndDep2(int id);
}
public interface DepartmentDao {
    public List<Department> search();
    public Department searchById(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.qr.empboot.dao.EmployeeDao">
    <select id="search" resultType="Employee">
		select *  from
		employee
	</select>

    <select id="searchById" resultType="Employee">
		select * from
		employee  where id=#{id}
	</select>

    <insert id="add">
		insert into
		employee(name,sex,age)values(#{name},#{sex},#{age})
	</insert>

    <update id="update">
		update employee set
		name=#{name},age=#{age},sex=#{sex} where
		id=#{id}
	</update>
    <delete id="delete">
		delete from employee where
		id=#{id}
	</delete>
    <select id="searchEmpAndDep" resultType="Employee">
		select e.*,d.id as 'dep.id',d.name as 'dep.name'  from
		employee as e left join department as d on e.d_id=d.id where e.id=#{id}
	</select>
    <select id="searchEmpAndDep2" resultMap="EmpAndDep2">
		select * from
		employee  where id=#{id}
	</select>
    <resultMap id="EmpAndDep2" type="Employee">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <result property="sex" column="sex"></result>
        <result property="age" column="age"></result>
        <association property="dep" javaType="Department" column="d_id" select="com.qr.empboot.dao.DepartmentDao.searchById">
        </association>
    </resultMap>
</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="com.qr.empboot.dao.DepartmentDao">
    <select id="search" resultType="Department">
		select *  from
		department
	</select>
	<select id="searchById" resultType="Department">
		select *  from
		department where id=#{id}
	</select>
</mapper>     

service层没有自己的业务,省略

声明式事务

@Aspect
@Configuration
public class TransactionAdviceConfig {
    private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.***.service.*.*(..))";

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean
    public TransactionInterceptor txAdvice() {

        DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
        txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
        txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        txAttr_REQUIRED_READONLY.setReadOnly(true);

        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        source.addTransactionalMethod("add*", txAttr_REQUIRED);
        source.addTransactionalMethod("save*", txAttr_REQUIRED);
        source.addTransactionalMethod("delete*", txAttr_REQUIRED);
        source.addTransactionalMethod("update*", txAttr_REQUIRED);
        source.addTransactionalMethod("exec*", txAttr_REQUIRED);
        source.addTransactionalMethod("set*", txAttr_REQUIRED);
        source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
        System.out.println("********************88ddd*************");
        return new TransactionInterceptor(transactionManager, source);
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}

Thymeleaf:
emp.html

<!DOCTYPE html>
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
<head >
    <meta charset="UTF-8">
    <title>Title</title>
    <script th:src="@{/jquery-3.1.0.js}"></script>
    <link th:href="@{/bootstrap/css/bootstrap.css}" rel="stylesheet"/>
</head>
<body>
<div style="width:400px;margin:20px auto">
    <table class="table table-bordered">
        <tr>
            <th>id</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
        </tr>

        <tr th:each="emp:${list}">
            <td th:text="${emp.id}"></td>
            <td th:text="${emp.name}"></td>
            <td th:text="${emp.sex}"></td>
            <td th:text="${emp.age}"></td>
        </tr>

    </table>
</div>
</body>
</html>

add.html

<!DOCTYPE html>
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
<head >
    <meta charset="UTF-8">
    <title>Title</title>
    <script th:src="@{/jquery-3.1.0.js}"></script>
    <link th:href="@{/bootstrap/css/bootstrap.css}" rel="stylesheet"/>
</head>
<body>
<
<div style="width:500px;margin: 20px auto">
    
    <form class="form-horizontal" action="add" method="post">

        <div class="form-group">
            <label class="col-sm-2 control-label">名字</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="name" placeholder="请输入名字">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-2 control-label">性别</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="sex" placeholder="请输入性别">
            </div>
        </div>

        <div class="form-group">
            <label class="col-sm-2 control-label">年龄</label>
            <div class="col-sm-10">
                <input type="text" class="form-control" name="age" placeholder="请输入年龄">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-2 control-label">部门</label>
            <div class="col-sm-10">
                <select class="form-control" name="deps" >

                        <option th:each="dep:${deps}" th:value="${dep.id}" th:text="${dep.name}"></option>
                </select>
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-2 control-label">部门</label>
            <div class="col-sm-10">
                <select class="form-control" name="deps" >

                    <option th:each="dep:${deps}" th:value="${dep.id}" th:text="${dep.name}"></option>
                </select>
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-primary">保存</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值