【【maven】】
1、idea自带了一个maven,不用安装。
2、需要把自己定义的xml文件放到.m2目录去,用于指定本地和远程仓库位置。idea的bulid tools-maven下的路径地址重新指定一下即可。
<localRepository> D:\mvnrepo</localRepository>
<mirror>
<id> nexus-aliyun</id>
<mirrorOf> *</mirrorOf>
<name> Nexus aliyun</name>
<url> http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
解决依赖冲突的原则:
0、直接依赖大于传递依赖。
1、都属于直接依赖的情况下,谁在上面谁优先。
2、可以通过<exlusion> 标签显式声明排除哪一个依赖子包。
jar包版本锁定:
<dependencyManagement>
hikaricp:
<dependency>
<groupId> com.zaxxer</groupId>
<artifactId> HikariCP</artifactId>
<version> 3.4.2</version>
<scope> compile</scope>
</dependency>
【【spring】】
maven导包:
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-context</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> junit</groupId>
<artifactId> junit</artifactId>
<version> 4.12</version>
</dependency>
xmlns约束:
<?xml version=“1.0” encoding=“UTF-8”?>
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=“http://www.springframework.org/schema/context”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package=“dao”></context:component-scan>
</beans>
xml配置方式】:
<bean id=“dd” class=“dao.DbDao”> </bean> 普通的以默认构造函数的方式反射创建对象,然后存入ioc容器
<bean id="" factory-bean="" factory-method=""/> 使用类中的某个函数创建对象
<bean id="" class="" factory-method=""/> 使用类的静态方法创建对象
bean标签的scope属性,用于指定bean的作用范围:singleton 默认 prototype多例 request session global-session非集群环境是和session一致
注入方式:
1、构造函数注入:
<constructor-arg name=“db” ref=“dd”> </constructor-arg> 该标签属性如下:
<!–index:参数的位置–>
<!–name:参数的名称–>
<!–value:基本数据类型直接赋值–>
<!–ref:使用已定义的beanid注入容器中对象–>
2、set方法注入:
<property name=“db” ref=“dd”/> 标签属性只有name、value和ref
注入集合类型:
property中还可以使用list或map标签注入集合
list标签下使用value标签写具体的集合内容,map标签使用entry标签注入键值对内容
启动容器和获取容器中存储的对象:
ApplicationContext ac = new ClassPathXmlApplicationContext(“bean.xml”);
DbDao dbDao = (DbDao) ac.getBean(“dbDao”);
annotation注解】:
1、创建对象的注解:
@Component(value = “svDao”) //默认的value是类名首字母小写 同样功能的主角还有表现层controller、业务层service、持久层repository
2、注入对象的注解:(可以写在属性或set方法上,即使属性是私有的)
// @Autowired 只要容器中有唯一的一个bean对象且要注入的变量类型一致,就可以注入成功。
// 如果有没有,报错;如果有多个,则使用变量名为id对容器内对象进行匹配,有则注入,没有报错
// @Qualifier 和autowired配合使用时指定按照名称注入。在給类成员注入时,不能单独使用,在給方法参数注入时可以。
// value属性 可以指定id
// @Resource 直接按照id注入,不匹配数据类型 使用name属性指定id
3、确定作用域的注解:
//@Scope(value = “prototype”)写在类名上
4、创建销毁方法的注解:写在方法上
@PreDestroy 销毁前执行
@PostConstruct 构造后执行
实例:spring整合dbutils进行sql操作:
<bean id=“accountService” class=“htyy.service.impl.AccountServiceImpl”>
<property name=“accountDao” ref=“accountDao”> </property>
</bean>
<bean id=“accountDao” class=“htyy.dao.impl.AccountDaoImpl”>
<property name=“runner” ref=“runner”> </property>
</bean>
<bean id=“runner” class=“org.apache.commons.dbutils.QueryRunner” scope=“prototype”>
<constructor-arg name=“ds” ref=“dataSource”> </constructor-arg>
</bean>
<bean id=“dataSource” class=“com.mchange.v2.c3p0.ComboPooledDataSource”>
<property name=“driverClass” value=“com.mysql.cj.jdbc.Driver”> </property>
<property name=“jdbcUrl” value=“jdbc:mysql://localhost:3306/test”> </property>
<property name=“user” value=“root”> </property>
<property name=“password” value=“JIANGkui1”> </property>
</bean>
runner.query(“select * from account”,new BeanListHandler<Account> (Account.class));
runner.query(“select * from account where id=?”,id,new BeanHandler<Account> (Account.class));
runner.update(“insert into account(name,money) values(?,?)”,account.getName(),account.getMoney());
runner.update(“update account set name=?,money=? where id=?”,account.getName(),account.getMoney(),account.getId());
runner.update(“update account set name=?,money=? where id=?”,account.getName(),account.getMoney(),account.getId());
使用配置类代替配置xml】
1、configuration 指定当前类是一个配置类。
2、componentScan指定扫描的包。使用value/basePackges属性指定包名。写在类上。有多个包,使用,隔开。另外的包也可以是另一个配置类。该注解相当于使用了componet-scan标签,在xml方式启动时,它也可以工作,前提是先被componet-scan扫描到该配置注解。
3、Bean:
把当前方法的返回值作为返回值存入容器,使用name属性指定bean的id。如果方法有参数,spring会自动进行autowired匹配。如果没有匹配的参数,会报错。希望直接根据id指定时,使用@qualifier()标签,写在方法参数前面。
@Bean(name=runner)
public QueryRunner createQueryRunner(@qualifier(“mysqlds”) DataSource dataSouce){
return new QueryRunner(dataSouce));
}
4、被bean修饰的方法就相当于bean标签,也可以使用scope注解来确定作用域。
5、import 参数value需要填写另一个配置类的字节码数组,可以引入没有被configuration 修饰的配置类。
6、PropertySouce(“classpath:xx”) 写在类上,可以通过value属性读取配置文件。然后可使用value标签注入到类的属性中。value写法为@value("$(配置文件的key值)")。
启动容器:
application ac= new annotationconfigapplicationcontext(springconfiguration.class,jdbcconfig.class)
ac.getbean
整合junit】
1、导入spring整合junit的jar包:
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-test</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
2、在测试类上写@RunWith(SpringJUnit4ClassRunner.class)
3、使用@ContextConfiguration()
locations = "classpath:bean.xml"表示配置文件位置。
classes=xx.class 表示注解配置类的位置。
aop】
解析表达式的包
<dependency>
<groupId> org.aspectj</groupId>
<artifactId> aspectjweaver</artifactId>
<version> 1.8.7</version>
</dependency>
<!--开启配置-->
<aop:config>
<!--可以在外层标签下定义共用的切入点表达式,只能定义在切面之前-->
<aop:pointcut id="allSeiviceMethod" expression="execution(* htyy.dao.impl.AccountDaoImpl.*(..))"/>
<!--开启切面配置,切面:指通知类的方法增强被通知类的设置,aspect标签指定选取ioc管理的通知类-->
<aop:aspect id="loggerAdvice" ref="logger">
<!--befor、after、around等标签指定通知类的某个方法增强某个表达式代表的方法的过程
表达式写法:
execution(表达式)注意,需要导入aspectj包,才能解析表达式
访问修饰 返回值 包名.包名.类名.方法名(参数列表)
public void service.impl.AccountDaoImpl.findAll()
可省 * *.*. *.*(..)
可用*.表示当前包及其之包 * *..AccountDaoImpl.findAll()
参数写法:
基本类型int 引用类型全类名java.lang.String
*表示任意类型,但必须有参数
..有无参数均可
实际开发中,通常定位到业务层实现类下的所有方法:
* htyy.utis.*.*(..)
-->
<aop:before method="printLogger" pointcut="execution(* *..AccountDaoImpl.findAll())"/>
<aop:after method="printLogger" pointcut="execution(* htyy.service.impl.AccountServiceImpl.findAcountById(..))"> </aop:after>
<!--几种通知类型:
before 前置通知,切入点方法之前执行
after-returning 后置通知 切入点方法正常return前执行
after-throwing 错误通知 报错时执行
after 最终通知 相当于finally
around 环绕通知 将方法和参数传递給通知方法,通知方法内手动操作。
-->
<aop:around method="aroundAdvice" pointcut-ref="allSeiviceMethod"> </aop:around>
</aop:aspect>
</aop:config>
环绕方法写法:
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
Object proceed=null;
try {
System.out.println(“前置通知”+ pjp.getArgs().toString());
proceed = pjp.proceed(pjp.getArgs());
System.out.println("后置通知");
}catch (Throwable t){
System.out.println("错误通知");
}finally {
System.out.println("最终通知"+ proceed.toString());
}
return proceed;
}
注解aop】:
<aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
@Component
@Aspect//表示当前类是一个切面类
public class Logger {
@Pointcut(“execution(* htyy.dao.impl.AccountDaoImpl.*(…))”)
private void serviceAllMethod(){}
@After("execution(* htyy.dao.impl.AccountDaoImpl.findAll())")
public void printLogger(){
System.out.println("原方法已经被增强!"+new Date().toLocaleString());
}
@Around("serviceAllMethod()")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
Object proceed=null;
try {
System.out.println("前置通知"+ pjp.getArgs().toString());
proceed = pjp.proceed(pjp.getArgs());
System.out.println("后置通知");
}catch (Throwable t){
System.out.println("错误通知");
}finally {
System.out.println("最终通知"+ proceed.toString());
}
return proceed;
}
}
通知方法中可以有一个JoinPoint参数,该参数有以下方法
1、getClass 获取当前被增强的类。
2、getSignature().getName()获取到被增强方法的名字。
3、getArgs() 得到当前方法参数。
使用注解配置会造成固有缺陷,最终通知会在后置、异常之前执行。
xml对同一个方法进行增强,按顺序执行。
注解对同一个方法进行增强,倒叙执行。
【jdbctemplate】
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-jdbc</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-tx</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
//此方法和dbutils有区别,因为重载了多个方法,可以自动根据sql语句决定返回泛型、集合或者void
List<Account> accounts = jt.query(“select * from account where name like ?”, new BeanPropertyRowMapper<Account> (Account.class),name);
jt.update(“update account set name=?,money=? where id=?”,account.getName(),account.getMoney(),account.getId());
使用方法和dbutils基本一致。
【声明式事务管理】
<tx:annotation-driven> </tx:annotation-driven>
<bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager” >
<property name=“dataSource” ref=“dataSource”> </property>
</bean>
注解:
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class AccountServiceImpl implements IAccountService {}
如果方法需要的传播和只读不同,可以在方法上单独配。
xml:
<!-- 配置事务的通知 -->
<tx:advice id=“txAdvice” transaction-manager=“transactionManager”>
<!-- 配置事务的属性
isolation: 用于指定事务的隔离级别。默认是DEFAULT,表示数据库默认隔离级别
propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法为SUPPORTS.
read-only: 用于指定事务是否只读。只有查询方法才能设置为true。默认值是false。表示读写
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
no-rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时事务不回滚。没有默认值。表示任何异常都回滚。
rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
name是业务层下的方法名,可以使用通配符
–>
<tx:attributes>
<tx:method name="" propagation=“REQUIRED” read-only=“false”/>
<tx:method name="find" propagation=“SUPPORTS” read-only=“true”/>
</tx:attributes>
</tx:advice>
<!-- 配置aop -->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut id=“pt1” expression=“execution(* com.zty.service.impl..(…))”> </aop:pointcut>
<!-- 建立切入点表达式和事务通知的对应关系 -->
<aop:advisor advice-ref=“txAdvice” pointcut-ref=“pt1”> </aop:advisor>
</aop:config>
</beans>
【xml整体配置和maven全包】
<?xml version=“1.0” encoding=“UTF-8”?>
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:aop=“http://www.springframework.org/schema/aop”
xmlns:tx=“http://www.springframework.org/schema/tx”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-context</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-test</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-jdbc</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-tx</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-orm</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-aop</artifactId>
<version> 5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId> org.aspectj</groupId>
<artifactId> aspectjweaver</artifactId>
<version> 1.8.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency>
<groupId> commons-dbutils</groupId>
<artifactId> commons-dbutils</artifactId>
<version> 1.4</version>
</dependency>
<dependency>
<groupId> junit</groupId>
<artifactId> junit</artifactId>
<version> 4.12</version>
</dependency>
<dependency>
<groupId> mysql</groupId>
<artifactId> mysql-connector-java</artifactId>
<version> 8.0.13</version>
</dependency>
<dependency>
<groupId> c3p0</groupId>
<artifactId> c3p0</artifactId>
<version> 0.9.1.2</version>
</dependency>
<!–用来做动态代理的–>
<dependency>
<groupId> cglib</groupId>
<artifactId> cglib</artifactId>
<version> 2.1_3</version>
</dependency>
【【spring MVC】】
mavaen项目加载添加值:
add maven property
archetypeCatalog=internal
<spring.version> 5.0.2.RELEASE</spring.version>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-web</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-webmvc</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> javax.servlet</groupId>
<artifactId> servlet-api</artifactId>
<version> 2.5</version>
<scope> provided</scope>
</dependency>
<dependency>
<groupId> javax.servlet.jsp</groupId>
<artifactId> jsp-api</artifactId>
<version> 2.0</version>
<scope> provided</scope>
</dependency>
<dependency>
<groupId> javax.servlet</groupId>
<artifactId> jstl</artifactId>
<version> 1.2</version>
</dependency>
<dependency>
<groupId> taglibs</groupId>
<artifactId> standard</artifactId>
<version> 1.1.2</version>
</dependency>
xmlns:mvc=“http://www.springframework.org/schema/mvc”
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
<context:component-scan base-package=“htyy”> </context:component-scan>
<mvc:annotation-driven> </mvc:annotation-driven>
1、通过web.xml配置前端控制器:
控制器组件随web容器启动,随即读取springmvc.xml,加载spring的ioc容器
<web-app>
<display-name> Archetype Created Web Application</display-name>
<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:springMvc.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>
</web-app>
2、配置视图解析器:
<context:component-scan base-package=“htyy”> </context:component-scan>
<mvc:annotation-driven> </mvc:annotation-driven>
<bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
3、创建url和方法的映射关系:
返回值是jsp的名称,通过视图解析器找到对应的jsp文件,返回给前端。
@Controller
public class HelloController {
@RequestMapping(path = "/hello")
public String sayHello(){
System.out.println("hello word");
return "success";
}
}
RequestMapping(path = “/hello”)该注解还可以写在类上,用于指定多级路径。
参数说明:
1、path和value一样,指定路径。
2、mathod,取值范围为枚举类RequestMethod,post和get。
3、params,参数限制表达式。如:{“username”}要求必须带username参数。{“username=hh”}属性值都必须对应。{“username!hh”}属性值不能等于hh。
4、headers,要求请求必须带有指定请求头。{“Accept”}
【表单参数接收.数据封装】
1、不采用手工从request取的方式,而是可以通过handel方法的参数进行接收。
2、可以自动封装基本数据类型,bean类型、集合和map。要求html参数name名必须和方法的参数名完全一致。
3、bean嵌套bean时,参数写mbean.nbean,如user.account
4、bean嵌套基本类型list或map时,写list[0].name;list[1].name;map[‘key’].name;map[‘key2’].name
5、bean嵌套list<bean> 时,写list[0].name;list[0].age;map[‘key’].name;map[‘key’].age
5、checkbox类型的同名参数接收,使用string时,用,组合接收。使用string[]时,自动封装成list。
6、获取原生request,方法中有httpservletrequest,httpservletresponse两个参数即可。
表单中文乱码问题:
需要配置一个characterEncodingFilter的过滤器。并配置初始化参数encoding=UTF-8
<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>
<init-param>
<param-name> forceEncoding</param-name>
<param-value> true</param-value>
</init-param>
</filter>
【自定义表单接收的类型转换器】
1、写转换器,实现converter接口。
2、在xml进行注册。
<bean id=“conversionService” class=“org.springframework.context.support.ConversionServiceFactoryBean”>
<property name=“converters”>
<set>
<bean class=“MyConverter”/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service=“sc” />
【表单验证】
springmvc使用JSR 303 – Bean Validation 规范
<dependency>
<groupId> org.hibernate</groupId>
<artifactId> hibernate-validator</artifactId>
<version> 4.3.1.Final</version>
</dependency>
<dependency>
<groupId> javax.validation</groupId>
<artifactId> validation-api</artifactId>
<version> 1.0.0.GA</version>
</dependency>
<dependency>
<groupId> org.jboss.logging</groupId>
<artifactId> jboss-logging</artifactId>
<version> 3.1.0.CR2</version>
</dependency>
Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式,可以通过messag参数指定回显文字。
Hibernate Validator 附加的 constraint
Constraint 详细信息
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内
自定义效验规则:
创建校验器并实现Validator接口并重写对应的方法即可,supports方法是用来判定要校验的bean类型,validate方法用来完成校验逻辑。
public class CustomerValidator implements Validator {
/**
* 检验验证对象是不是Customer类,如果是则进行检验
*/
@Override
public boolean supports(Class<?> target) {
return Customer.class.equals(target);
}
/**
* 校验用户名是否已经存在
*/
@Override
public void validate(Object target, Errors errors) {
Customer customer = (Customer) target;
String name = customer.getCusName();
if (name.equals("Administrator")) {
errors.rejectValue("cusName", null, "该账号已被使用!");
}
}
}
在controller中使用验证器:
方法中参数使用@Validated Customer customer ,BindingResult bindingResult。这样就会对该对象进行验证,验证信息会由bindingresult进行接收。
检查是否有错即可:
if(bindingResult.hasErrors()){
model.addAttribute(“allErrors”,allErrors);
return “fail”;
有错将所有错误信息传达給jsp显示:
<c:if test="${allErrors!= null}">
<c:forEach items="${allErrors}" var=“item”>
${item.defaultMessage}
</c:forEach>
</c:if>
加载自己写的验证器:
@InitBinder
public void bindValidator(DataBinder dataBinder) {
dataBinder.setValidator(new CustomerValidator());
}
【常用注解】
@RequestParam
方法参数注解,修饰单一的形参。如@RequestParam(“name”) String username.代表前端的name映射为username。
@PathVariable
方法参数注解,要求url中带有可变参数。用于接收该可变参数。注意,只能用包装类接收!
requestmapping("/test/{sid}")
public string testpath(PathVariable(“sid”)Integer id)
@RequestHeader
方法参数注解,获得请求的请求头信息。
xx(@RequestHeader(“Accept”)String header)
@RequestBody
方法参数注解,使用string获得请求体参数。
@CookieValue
方法参数注解,获取cookie的信息。
@ModelAttribute
方法、方法参数注解。写在方法上时,方法先于所有控制器方法执行。即被@ModelAttribute注解的方法会在Controller每个方法执行之前都执行,因此对于一个Controller中包含多个URL的时候,要谨慎使用。。
注解有返回值方法时,返回值对象会被默认放到隐含的Model(spring封装的request域对象)中,在Model中的key为返回值首字母小写,value为返回的值。
model.addAttribute(“string”, abc);
model.addAttribute(“int”, number);
model.addAttribute(“student”, student);
如果想要指定返回值注入到model对象的名称,可以使用value属性。@ModelAttribute(value = “num”)
注解无返回值方法时:
@ModelAttribute
public void myModel(@RequestParam(required = false) String abc, Model model) {
model.addAttribute(“attributeName”, abc);
}
可以显示将对象注入。
注入到model对象而没有显式指定名称的变量,非基本类型可以通过类型匹配得出。
显式指定了名称的变量,只能通过参数注解@ModelAttribute(“mit”)方式取出。
@SessionAttributes({“a”,“b”})
类注解,表示某个方法使用model对象将a,b两个对象存储进request作用域中时,同样存储到session汇总。
存储后,可以通过ModelMap.get()方法取值。可以通过SessionStatus.setComplete方法清除@SessionAttributes设置的值。
@SessionAttribute
参数注解,表明方法要取的session参数。
【controller和js通信】
1、返回字符串,默认通过视图解析器查找到同名jsp返回前端。通过参数获取model类型的对象,通过model.addAttribute方法传递数据.
2、void方法,默认查找conroller requestmapping url的同名jsp返回前端。
3、返回ModelAndView类型,可以通过new ModelAndView.addObject/setViewName的方式添加变量并设置返回的jsp页面。
4、转发和重定向,返回固定格式的字符串:return “forward:/web-inf/pages/success.jsp”; return “redirect:/index.jsp”
【json通信】
1、配置静态资源不拦截。
<!–配置前端使用的静态资源不拦截–>
<mvc:resources mapping="/css/" location="/css/"/>
<mvc:resources mapping="/images/" location="/images/"/>
<mvc:resources mapping="/js/" location="/js/**"/>
另一种不拦截静态资源的方法:
<mvc:default-servlet-handler />
如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
<mvc:default-servlet-handler default-servlet-name=“所使用的Web服务器默认使用的Servlet名称” />
<!–增加对静态资源的处理,当前的设置必须在Spring的Dispatcher的前面–>
<servlet-mapping>
<servlet-name> default</servlet-name>
<url-pattern> .css</url-pattern>
<url-pattern> /css/</url-pattern>
</servlet-mapping>
2、加载解析json的jar文件:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<jackson.version> 2.9.0</jackson.version>
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-databind</artifactId>
<version> ${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-core</artifactId>
<version> ${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-annotations</artifactId>
<version> ${jackson.version}</version>
</dependency>
3、controller方法通过参数注解@requestBody User user自动读取请求体内容进行封装。通过返回值注解@ResponseBody User testAjax将返回的user再转化为json格式字符串,返回給前端。注意,这样修改后,方法就返回json字符串,而非具体页面了。
【文件上传】
前端】:
1、form表单的enctype取值必须是 multipart/form-data(默认值是application/x-www-form-urlencoded)enctype:是表单请求正文的类型。
2、提供一个文件input控件<input type=“file”/>
后端工具方法】:
原始手动流读取法基本很少用了,基本采用阿帕奇提供的commons-fileupload(依赖commons-io)包。
<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.4</version>
</dependency>
使用fileUpload固定步骤:
创建工厂类:DiskFileItemFactory factory=new DiskFileItemFactory();
创建解析器:ServletFileUpload upload=new ServletFileUpload(factory);
使用解析器解析request对象:List<FileItem> list=upload.parseRequest(request)
一个FileItem对象对应一个表单项。FileItem类有如下方法:
String getFieldName():获取表单项的name的属性值。
String getName():获取文件字段的文件名。如果是普通字段,则返回null
String getString():获取字段的内容。如果是普通字段,则是它的value值;如果是文件字段,则是文件内容。
String getContentType():获取上传的文件类型,例如text/plain、image。如果是普通字段,则返回null。
long getSize():获取字段内容的大小,单位是字节。
boolean isFormField():判断是否是普通表单字段,若是,返回true,否则返回false。
InputStream getInputStream():获得文件内容的输入流。如果是普通字段,则返回value值的输入流。
req.setCharacterEncoding("utf-8");
String path=req.getSession().getServletContext().getRealPath("/uploads");
File uploadFolder = new File(path);
if(!uploadFolder.exists())uploadFolder.mkdirs();
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
List<FileItem> itemList = upload.parseRequest(req);
for (FileItem fileItem : itemList) {
if(fileItem.isFormField()){
System.out.println(new String(fileItem.getFieldName().getBytes("iso-8859-1"),"utf-8")+" value:"+
new String(fileItem.getString().getBytes("iso-8859-1"),"utf-8"));
}else{
String fileName=fileItem.getName();
fileName= UUID.randomUUID().toString().replace("-","")+"_"+fileName;
fileItem.write(new File(uploadFolder,fileName));
fileItem.delete();
System.out.println(fileName+"上传成功");
}
}
注意:使用表单提交multipart/form-data后,springmvc将不能自动识别表单数据并在controller方法参数中进行自动封装。所有封装结果都是null。
springMVC方式】:
1、 <!–配置文件解析器–>
<bean id=“multipartResolver” class=“org.springframework.web.multipart.commons.CommonsMultipartResolver”>
<property name=“maxUploadSize” value=“10485760”/>
</bean>
2、使用同名的MultipartFile对象接收解析后的对象,名称一定要和前端的name一致。使用该方法,其他非文件参数可以正常接收。
@RequestMapping("/fileLoad")
public String fileLoad(HttpServletRequest req,String username, String password, Integer money, String[] from, MultipartFile myFile) throws IOException {
System.out.println(username+password+money);
if (from!=null){
for (String s : from) {
System.out.println(s);
}
}
String path=req.getSession().getServletContext().getRealPath("/uploads");
String fileName= UUID.randomUUID().toString().replace("-","")+"_"+myFile.getOriginalFilename();
myFile.transferTo(new File(path,fileName));
return “success”;
}
【拦截器和异常处理】
1、定义一个类实现handlerExceptionResolver接口,实现ModelAndView resolveException(req,resp,object handler,Exception ex)方法。
2、注册自定义的异常处理器。通过bean标签把自己的处理器交给spring管理即可。
拦截器:
1、实现handlerInterceptor接口,接口中有三个方法可以使用。
// 控制器方法执行之前执行该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
// 控制器方法执行后,jsp返回前执行.这个方法在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
// jsp返回后执行,顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
2、在xml中注册该拦截器,并设置拦截url。
<!–配置自定义拦截器–>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id=“userIntercept” class=“htyy.Intercept.UserIntercept”/>
</mvc:interceptor>
</mvc:interceptors>
<?xml version=“1.0” encoding=“UTF-8”?>
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:mvc=“http://www.springframework.org/schema/mvc”
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="htyy"> </context:component-scan>
<mvc:annotation-driven> </mvc:annotation-driven>
<bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置前端使用的静态资源不拦截-->
<mvc:resources mapping="/css/" location="/css/**"/>
<mvc:resources mapping="/images/" location="/images/**"/>
<mvc:resources mapping="/js/" location="/js/**"/>
<!--配置文件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
<!--配置自定义拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="userIntercept" class="htyy.Intercept.UserIntercept"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
<web-app>
<display-name> Archetype Created Web Application</display-name>
<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>
<init-param>
<param-name> forceEncoding</param-name>
<param-value> true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharacterEncodingFilter</filter-name>
<url-pattern> /*</url-pattern>
</filter-mapping>
<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:springMvc.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>
</web-app>
【【mybatis学习】】
<dependency>
<groupId> org.mybatis</groupId>
<artifactId> mybatis</artifactId>
<version> 3.4.5</version>
</dependency>
<dependency>
<groupId> junit</groupId>
<artifactId> junit</artifactId>
<version> 4.12</version>
</dependency>
<dependency>
<groupId> mysql</groupId>
<artifactId> mysql-connector-java</artifactId>
<version> 8.0.13</version>
</dependency>
<dependency>
<groupId> c3p0</groupId>
<artifactId> c3p0</artifactId>
<version> 0.9.1.2</version>
</dependency>
1、创建实体类和需要的dao接口。
public class Account {
public interface IAccountDao {
2、创建mybatis的主配置文件,指定数据库环境和事务类型。
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE configuration
PUBLIC “-//mybatis.org//DTD Config 3.0//EN”
“http://mybatis.org/dtd/mybatis-3-config.dtd”>
<configuration>
<!–environments是所有环境标签,子标签是单个的数据库环境。可以指定一个默认采用的数据库–>
<environments default=“mysql”>
<!–这里配置的是单个的数据库环境,这里是msql–>
<environment id=“mysql”>
<!–配置事务类型,这里采用jdbc–>
<transactionManager type=“JDBC”> </transactionManager>
<!–配置采用的连接池,这里使用内置的pooled–>
<dataSource type=“POOLED”>
<property name=“driver” value=“com.mysql.cj.jdbc.Driver”/>
<property name=“url” value=“jdbc:mysql://localhost:3306/test”/>
<property name=“username” value=“root”/>
<property name=“password” value=“JIANGkui1”/>
</dataSource>
</environment>
</environments>
<!–指定配置文件的位置,mappers是指一个dao接口所对应的具体实现方式,其存放位置必须在resources的同名包下–>
<mappers>
<mapper resource=“dao/IAccountDao.xml”/>
</mappers>
</configuration>
如果不想将接口和mapper文件分别放到src/main/java和src/main/resources中,而是全部放到src/main/java,那么在构建的时候需要指定maven打包需要包括xml文件,具体配置如下:
<build>
<resources>
<resource>
<directory> src/main/java</directory>
<includes>
<include> **/*.xml</include>
</includes>
<filtering> false</filtering>
</resource>
</resources>
</build>
这样在打包的时候也会将mapper文件打包到/target文件夹中。
3、创建和dao接口相匹配的映射配置文件。
<?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”>
<!–注意:这里的namespace必须是相应dao的全限定类名,否则无法知道匹配的是哪个dao–>
<mapper namespace=“dao.IAccountDao”>
<!–这里的dao里的id是方法名,如果方法有返回值,需要封装的话,需要通过resultType指定返回值类型–>
<select id=“findAll” resultType=“domain.Account”>
select * from account
</select>
</mapper>
3、1 也可以使用注解的方式来配置sql语句。
<!–此处用注解的方式在方法上直接写sql,这里写dao接口的类名即可–>
<mapper class=“dao.IAccountDao”/>
类中写:
@Select(“select * from account”)
Account findAccountByname(String name);
4、读取配置文件生产出代理的dao对象,实现方法。
// 通过mybatis提供的resources工具类得到配置文件的流,然后使用工厂构建器构建使用该配置文件构建出的工厂
InputStream in = Resources.getResourceAsStream(“mybatis.xml”);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 工厂生产session对象,这里我们主要使用的对象,该对象可以生产代理dao,并且一个session是一个事务
SqlSession sqlSession = factory.openSession();
// 使用getmapper方法获得代理dao
IAccountDao accountDao = sqlSession.getMapper(IAccountDao.class);
List<Account> all = accountDao.findAll();
for (Account account : all) {
System.out.println(account);
}
// 释放资源:由于流并不是給包装类使用的,这里注意要关闭流。
// sqlSession.commit();
sqlSession.close();
in.close();
【增删改查】
<select id=“findAll” resultType=“domain.Account”>
select * from account
</select>
<!–占位符使用el表达式方式#{name},el表达式的作用域方法传入的参数parameterType,属性名是get方法.注意ddl都需要commit–>
<!–selectKey三个属性分别表示属性名称,返回值类型,操作顺序,就是把select的结果注入到传入对象的id属性中去–>
<!–非自增随机赋予uuid型逐渐也可以获取,order=“befor” 返回值string 语句写select replace(uuid(), ‘-’, ‘’)即可–>
<insert id=“saveAccount” parameterType=“domain.Account”>
<selectKey keyProperty=“id” resultType=“int” order=“AFTER”>
select last_insert_id()
</selectKey>
insert into account(name,money) values(#{name},#{money})
</insert>
<update id=“updateAccount” parameterType=“domain.Account”>
update account set name=#{name},money=#{money} where id=#{id}
</update>
<!--参数只有一个的情况下,占位符叫id或uid,可以随便取,它将按照类型获取值,类似autowire-->
<delete id="deleteAccount" parameterType="int">
delete from account where id=#{id}
</delete>
<select id="findAccountById" parameterType="int" resultType="domain.Account">
select * from account where id=#{id}
</select>
<!--模糊查询时,可以写${value}的形式,这样可以拼接其他字符串,如%${value}%,这种形式中value的值是固定的,只能写value-->
<select id="findAccountByName" parameterType="string" resultType="domain.Account">
select * from account where name like #{name}
</select>
<select id="findTotal" resultType="int">
select count(id) from account
</select>
【parameterType和resultType】
1、mybatis使用ognl(对象图导航语言)表达式解析对象的值,#/$括号中的域对象即为pojo对象。
2、显然,如果要使用跨关系查询时,只需要把多个对象组成一个查询vo对象或者map,然后在sql中调用即可。需要注意没有传值时的处理方式。
3、parameterType只是用来指定ognl表达式的域对象的,不写它时,可以用指定对象取值的方法来获取参数,如#{user.id}。多参数时,可以位置索引如#{0}来指定参数使用。
4、方法中直接使用注解定义参数别名,如@Param(“id”),xml可以直接使用#{id}。
【返回值封装】
数据库列名如果和entity类set方法名一致,可以自动封装,如果不一样,可以采用如下方法。
1、查询语句起别名。
2、使用resultMap 标签描述列名和实体类的对应关系。然后在select标签中把resultType换成resultMap即可。注意,以后所有使用到resultMap的地方也是一样的,所有实体类与数据列名一致的地方都可以省略。
<resultMap id=“accountMpa” type=“domain.Account”>
<id property=“id” column=“id”/>
<result property=“name” column=“name”/>
<result property=“money” column=“money”/>
</resultMap>
【常用标签】
1、 <properties resource=“mybatis.properties”>
<property name=“url” value=“jdbc:mysql://localhost:3306/test”/>
</properties> 定义一些通用属性,也可以通过resource引用外部的properties配置文件,然后通过${xx}方式取值。
2、 <typeAliases>
<!–type指定类的全限定类名,alias指定其别名,不区分大小写,也就是大小写都可以指定到该类。–>
<!–<typeAlias type=“domain.Account” alias=“account”/> -->
<!–用于指定要配置别名的包,指定后,该包下所有实体类都会注册别名,别名就是类名,而且不区分大小写–>
<package name=“domain”> </package>
</typeAliases>
3、 <mappers>
<!–<mapper resource=“dao/IAccountDao.xml”/> -->
<!–此处用注解的方式在方法上直接写sql,这里写dao接口的类名即可–>
<!–<mapper class=“dao.IAccountDao”/> -->
<!–扫描dao包,自动读取注解或配置文件–>
<package name=“dao”> </package>
</mappers>
4、 <settings>
<setting name=“logImpl” value=“STDOUT_LOGGING” />
<setting name=“jdbcTypeForNull” value=“NULL” />
</settings> 控制台打印sql
【动态查询,带逻辑判断的查询】
1、if标签
<!–if test语句内可以不写#{}取得属性,但需要严格注意大小写,如果test为真,if内语句就会拼接到上面的select语句执行。可以使用!= == and or 等运算符。where子标签可以用于拼接where语句,可以把他看成自动写了一个where 1=1–>
<select id=“findAccountByCondition” parameterType=“domain.Account” resultType=“domain.Account”>
select * from account
<where>
<if test=“id != null”>
and id =#{id}
</if>
<if test=“name != null”>
and name like #{name}
</if>
<if test=“money != null”>
and money = #{money }
</if>
</where>
</select>
2、for each标签,用来遍历集合凭借查询字符串
<select id=“findAccountByIdInIds” parameterType=“queryVo” resultType=“domain.Account”>
select * from account
<where>
<foreach collection=“ids” open=“and id in (” close=")" item=“uid” separator=",">
#{uid}
</foreach>
</where>
</select>
【多表查询】
1、多对一(一对一)
<mapper namespace=“dao.IAccountDao”>
<resultMap id=“accountUserMap” type=“domain.Account”>
<id property=“id” column=“id”/>
<result property=“name” column=“name”/>
<result property=“money” column=“money”/>
<!–一对一的关系映射 property指定封装到内部哪一个对象,javatype指定类名–>
<association property=“user” javaType=“domain.User” >
<id property=“id” column=“user_id”/>
<result property=“userName” column=“userName”/>
<result property=“birthday” column=“birthday”/>
<result property=“sex” column=“sex”/>
<result property=“address” column=“address”/>
</association>
</resultMap>
<select id=“findAll” resultMap=“accountUserMap”>
select a.*,u.id user_id,u.address,u.birthday,u.sex,u.username from account a LEFT JOIN user u on a.userid=u.id
</select>
2、一对多
<mapper namespace=“dao.IUserDao”>
<resultMap id=“userAccountMap” type=“domain.User”>
<id property=“id” column=“id”/>
<result property=“userName” column=“userName”/>
<result property=“birthday” column=“birthday”/>
<result property=“sex” column=“sex”/>
<result property=“address” column=“address”/>
<collection property=“accounts” ofType=“domain.Account”>
<id property=“id” column=“aid”/>
<result property=“name” column=“name”/>
<result property=“money” column=“money”/>
</collection>
</resultMap>
<select id=“findAll” resultMap=“userAccountMap”>
select u.,a.id aid,a.name,a.money from user u LEFT JOIN account a on u.id =a.userid
</select>
3、多对多
<!–返回值映射书写原则全都一样,定义好类属性和子字段的类属性即可,列名必须和sql查询出的一致,要点是sql联合查询能够查询出需要封装的属性–>
<resultMap id=“roleMap” type=“domain.Role”>
<id property=“roleId” column=“roleId”/>
<result property=“roleName” column=“roleName”/>
<result property=“roleDesc” column=“roleDesc”/>
<collection property=“users” ofType=“domain.User”>
<id property=“id” column=“id”/>
<result property=“userName” column=“userName”/>
<result property=“birthday” column=“birthday”/>
<result property=“sex” column=“sex”/>
<result property=“address” column=“address”/>
</collection>
</resultMap>
<select id=“findAll” resultMap=“roleMap”>
select r.,u.* from user
u
RIGHT JOIN user_role ur on u.id=ur.uid
RIGHT JOIN role r on r.roleId=ur.rid
</select>
如果一个对象中需要封装多个集合,resultMap中需要定义多个集合,列名不能重复。sql语句需要多表联合,将所有对象都查出来。如下是User中封装了account和role对象的sql语句:
<select id=“findAll” resultMap=“userAccountMap”>
select u.,r.,a.id aid ,a.name,a.money from user
u
LEFT JOIN user_role ur on u.id=ur.uid
LEFT JOIN role r on r.roleId=ur.rid
LEFT JOIN account a on a.userid=u.id
ORDER BY u.id;
</select>
【延迟加载】
<!–使用到一对一的关联对象时,自动根据select的语句发关联查询,在查询时一起发送1+n条sql语句。如果不配置懒加载,并不会延迟–>
<!–参数,column指外键列的列名,select是byid的语句,相当于select * from user where id=#{userid}。userid可以完全不在resultMap中体现。–>
<resultMap id=“account_user_lazy” type=“account”>
<id property=“id” column=“id”/>
<result property=“name” column=“name”/>
<result property=“money” column=“money”/>
<association property=“user” javaType=“user” column=“userid” select=“dao.IUserDao.findById”/>
</resultMap>
主配置文件:
<settings>
<!–指定 MyBatis 所用日志的具体实现,未指定时将自动查找。–>
<setting name=“logImpl” value=“STDOUT_LOGGING” />
<!–延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态–>
<setting name=“lazyLoadingEnabled” value=“true”/>
<!–当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。–>
<setting name=“aggressiveLazyLoading” value=“false”/>
</settings>
注意:懒加载时,调用tostring方法和getUser方法,都会触发sql语句发送。其他单独get属性时,并不会发送sql语句。
一对多查询时,写法也基本一样,查询user时,通过select属性指定一个accountdao的list<user> findbyuserid(int uid)方法即可。传入的id值通过column参数指定本查询的id。相当于每次遍历一个User时,该配置会自动帮你调用一次findbyuserid方法。
【缓存】
1、sqlsession对象会默认缓存所有查询的结果集,这就是一级缓存。也就是说,在一个session中重复查询是没有意义的。但是,调用sqlsession.clearCache()可以清空缓存,清空后需要重新通过getMapper方法获取代理dao。
2、当调用sqlsession的修改,添加,删除,commit,close方法后,会自动清空一级缓存。
3、二级缓存是sqlsessionfactory级别的缓存,由一个工厂生产出的多个session共享同一个二级缓存。它存储的是数据,而非对象。它并不会发sql语句,但会将存储的数据新new一个对象交给调用方法,因此新建的对象内存地址是不同的。
4、二级缓存使用步骤:
1、在主配置文件中开启二级缓存。cacheEnabled=true
2、在映射文件的mapper标签中写<cache/> 。
3、在select标签中写userCache=“true”。
【注解开发】
1、单表情况下:删增改查的语句写法和xml一致。单参数情况下默认传入该参数作为作用域(基本类型直接按类型匹配),因此可以用#{属性名}的写法。多参数情况下,用@param注解修饰参数起别名,或者使用#{0}位置调用。
2、配置实体类映射的注解:
@Results(id = “accountMap”,
value = {
@Result(id = true,column = “id”,property = “id”),
@Result(property=“name”, column=“name”),
@Result(property=“money”, column=“money”),
@Result(property=“userid”, column=“userid”),
})该注解标在方法上,方法返回值按该映射封装的同时,可以指定一个id名称,給其他方法进行引用。其他方法使用@ResultMap(“accountMap”)注解即可引用,而不用重新写对应关系。
3、多表懒加载
@Select(“select * from account”)
@Results(
value = {
@Result(id = true,column = “id”,property = “id”),
@Result(property=“name”, column=“name”),
@Result(property=“money”, column=“money”),
@Result(property=“userid”, column=“userid”),
@Result(property = “user”,column = “userid”,
one = @One(select = “dao.IUserDao.findById”,fetchType = FetchType.LAZY))
})
一对多情况下使用:many = @Many(fetchType = FetchType.LAZY,select = “dao.IAccountDao.findAccountByUserId”)
4、开启二级缓存,主配置文件开启后,在dao类名上使用@CacheNamespace(blocking=true)即可。
5、注解不支持逻辑判断和join查询,所以,复杂查询请尽量使用xml配置文件。
【【ssm整合】】
spring整合spirngmvc:
1、分成spring+db的配置文件和springmvc一共两个配置文件,把controller注解全部交给mvc管理。
<context:component-scan base-package=“htyy”>
<context:include-filter type=“annotation” expression=“org.springframework.stereotype.Controller”/>
</context:component-scan>
<context:component-scan base-package=“htyy”>
<context:exclude-filter type=“annotation” expression=“org.springframework.stereotype.Controller”/>
</context:component-scan>
2、 web.xml通过监听器启动spring的配置文件:
<context-param>
<param-name> contextConfigLocation</param-name>
<param-value> classpath:applicationContextConfig.xml</param-value>
</context-param>
<!–配置spring监听器,默认只加载web-inf目录下的applicationContext.xml配置文件–>
<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!–配置spring提供的RequestContextListener,获取request对象,在其他方法中调用–>
<listener>
<listener-class> org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
3、整合mybatis
<!–spring整合mybatis对象–>
<bean id=“factoryBean” class=“org.mybatis.spring.SqlSessionFactoryBean”>
<property name=“dataSource” ref=“dataSource”/>
<property name=“typeAliasesPackage” value=“htyy.domain”/>
<!–所有settings的内容都可以写在这里–>
<property name=“configuration”>
<bean class=“org.apache.ibatis.session.Configuration”>
<property name=“lazyLoadingEnabled” value=“true”/>
<property name=“aggressiveLazyLoading” value=“false”/>
<setting name=“jdbcTypeForNull” value=“NULL”/>
</bean>
</property>
<!–引入原始的配置文件–>
<!–<property name=“configLocation” value=“mybatis.xml”/> -->
<!-- 当mybatis的xml文件和mapper接口不在相同包下时,需要用mapperLocations属性指定xml文件的路径。
是个通配符,代表所有的文件,代表所有目录下 -->
<!–<property name=“mapperLocations” value="classpath:htyy/dao//.xml"/> -->
</bean>
<!–4 自动扫描对象关系映射 -->
<bean id=“mapperScannerConfigurer” class=“org.mybatis.spring.mapper.MapperScannerConfigurer”>
<!–指定会话工厂,如果当前上下文中只定义了一个则该属性可省去 -->
<!-- <property name=“sqlSessionFactoryBeanName” value=“sqlSessionFactory”> </property> -->
<!-- basePackage 属性是让你为映射器接口文件设置基本的包路径。 你可以使用分号或逗号 作为分隔符设置多于一个的包路径 -->
<property name=“basePackage” value=“htyy.dao”/>
</bean>
所有包统计:
<properties>
<project.build.sourceEncoding> UTF-8</project.build.sourceEncoding>
<maven.compiler.source> 1.8</maven.compiler.source>
<maven.compiler.target> 1.8</maven.compiler.target>
<spring.version> 5.0.2.RELEASE</spring.version>
<log4j.version> 1.2.12</log4j.version>
<slf4j.version> 1.6.6</slf4j.version>
<jackson.version> 2.9.0</jackson.version>
<mybatis.version> 3.4.5</mybatis.version>
</properties>
<dependencies>
<dependency>
<groupId> junit</groupId>
<artifactId> junit</artifactId>
<version> 4.12</version>
<scope> test</scope>
</dependency>
<dependency>
<groupId> log4j</groupId>
<artifactId> log4j</artifactId>
<version> ${log4j.version}</version>
</dependency>
<dependency>
<groupId> org.slf4j</groupId>
<artifactId> slf4j-api</artifactId>
<version> 1.6.6</version>
</dependency>
<dependency>
<groupId> org.slf4j</groupId>
<artifactId> slf4j-log4j12</artifactId>
<version> 1.6.6</version>
</dependency>
<!–数据库–>
<dependency>
<groupId> mysql</groupId>
<artifactId> mysql-connector-java</artifactId>
<version> 8.0.13</version>
</dependency>
<dependency>
<groupId> c3p0</groupId>
<artifactId> c3p0</artifactId>
<version> 0.9.1.2</version>
</dependency>
<!–spring–>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-context</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-test</artifactId>
<version> ${spring.version}</version>
<scope> provided</scope>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-jdbc</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-tx</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-orm</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> org.aspectj</groupId>
<artifactId> aspectjweaver</artifactId>
<version> 1.8.7</version>
</dependency>
<!--springmvc-->
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-web</artifactId>
<version> ${spring.version}</version>
</dependency>
<dependency>
<groupId> org.springframework</groupId>
<artifactId> spring-webmvc</artifactId>
<version> ${spring.version}</version>
</dependency>
<!--servlet、jsp-->
<dependency>
<groupId> javax.servlet</groupId>
<artifactId> servlet-api</artifactId>
<version> 2.5</version>
<scope> provided</scope>
</dependency>
<dependency>
<groupId> javax.servlet.jsp</groupId>
<artifactId> jsp-api</artifactId>
<version> 2.0</version>
<scope> provided</scope>
</dependency>
<dependency>
<groupId> javax.servlet</groupId>
<artifactId> jstl</artifactId>
<version> 1.2</version>
<scope> runtime</scope>
</dependency>
<dependency>
<groupId> taglibs</groupId>
<artifactId> standard</artifactId>
<version> 1.1.2</version>
<scope> runtime</scope>
</dependency>
<!--配置springmvc自动处理jason需要的jar-->
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-databind</artifactId>
<version> ${jackson.version}</version>
</dependency>
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-core</artifactId>
<version> ${jackson.version}</version>
</dependency>
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-annotations</artifactId>
<version> ${jackson.version}</version>
</dependency>
<!--mybatis的包-->
<dependency>
<groupId> org.mybatis</groupId>
<artifactId> mybatis</artifactId>
<version> ${mybatis.version}</version>
</dependency>
<dependency>
<groupId> org.mybatis</groupId>
<artifactId> mybatis-spring</artifactId>
<version> 1.3.0</version>
</dependency>
<dependency>
<groupId> commons-fileupload</groupId>
<artifactId> commons-fileupload</artifactId>
<version> 1.3.1</version>
</dependency>
</dependencies>
【【spring boot】】
idea 快速创建过程
1、spring initializr-》next
2、输入arfict和groupid,注意默认package
3、选择各个启动器,如web、mybatis/jpa、mysql、thymeleaf等
4、修改项目名称,finish
一、依赖说明】
<parent>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-starter-parent</artifactId>
<version> 2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
父工程,骨架管理,spring的核心依赖都在该工程中。
<dependencies>
<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.1</version>
</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>
<exclusions>
<exclusion>
<groupId> org.junit.vintage</groupId>
<artifactId> junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
各个启动器,分模块的各个依赖,每个启动器都是一块独立的功能,会引入一堆依赖。
二、程序入口说明】
spring boot内置了web容器,和django一样,直接通过入口启动即可。
@SpringBootApplication//该注解相当于@EnableAutoConfiguration+@ComponentScan+@Configration,自动使用默认配置和包扫描,扫描的路径默认是该注解类所在的包。当然也可以手写覆盖。默认情况下,该启动类应该在最外层包的一级目录下。
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
三、自动配置说明】
springboot的默认配置加载过程是根据读取依赖jar包进行的,导入了什么样的启动器,就需要去覆盖什么配置,比如导入了数据库的包,就必需提供url、username、password的配置,否则springboot会报错,提示没有匹配的必需配置。导入了连接池的包,虽然不要求任何必需配置,但程序已经会默认使用连接池创建链接。注意:导入包之后,idea也会根据导入的包提供application.properties的提示。
spring有application.properties/application.yml/application.yaml三种配置文件,都可以覆盖默认配置,加载顺序是yml-yaml-properties,后加载的会覆盖前面的。
properties:
spring.datasource.url=localhost:///test
spring.datasource.data-username=root
spring.datasource.password=JIANGkui1
server.port=8080
yml(注意,写value值时要先空一格,否则无效):
spring:
datasource:
url: localhost:///test
data-username: root
data-password: JIANGkui1
server:
port: 8080
yml文件还可以配置数组、集合、对象等,类似json:
#行内对象配置
person:{name: zhangsan,age: 18}
#配置数组
city:
- chongqin
- shanghai
- guiyang
#city: [chongqing,shanghai,guiyang]
#配置对象数组
student:
- name: tom
age: 18
city: guiyang - name: tony
age: 21
city: shanghai
#student: [{name: tom,age: 18,addr: guiyang}]
#配置map
mymap:
key1: value1
key2: value2
四、热部署】
<dependency>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-devtools</artifactId>
</dependency>
勾选settings-compiler-Build project automatically
c+a+s+/- registry 勾选compiler.automake.allow.when.app.running
五、自动注入配置文件中配置的数据】
回顾:在之前基于全注解的spring配置中,讲过一种@PropertySource(“classpath:xxx”),读取资源文件,再使用@Value(“name”)注解注入到类属性的方法。在springboot中,程序会默认读取properties、yml配置文件,所以可以使用一个注解,将配置文件中定义的数据自动注入到类属性或方法中,这个注解就是@ConfigurationProperties。
两种注入方法:
1、value注入,此方法是基于value,不要求配置@ConfigurationProperties,可以执行类型转换
public class HelloController {
@Value("
p
e
r
s
o
n
.
n
a
m
e
"
)
p
r
i
v
a
t
e
S
t
r
i
n
g
n
a
m
e
;
@
V
a
l
u
e
(
"
{person.name}") private String name; @Value("
person.name")privateStringname;@Value("{person.city}")
private String city;
@Value("${person.age}")
private Integer age;
2、@ConfigurationProperties+get方法注入,要求都必须具有get方法:
@ConfigurationProperties(“person”)
public class HelloController {
private String name;
private String city;
private Integer age;
运用这两种方式,可以很方便的在使用注解实例化和注入bean时,注入配置文件的信息:
1、使用ConfigurationProperties注解,将需要读取的数据封装到一个类中。
@ConfigurationProperties(“spring.datasource”)
public class JdbcProperties {
private String url;
private String data_username;
private String data_password;
private String driver_class_name;
2、使用@EnableConfigurationProperties({JdbcProperties.class})和@Autowired自动注入,将该包装类注入到配置类中。
@Configuration
@EnableConfigurationProperties({JdbcProperties.class})//设置读取的自动注入类
public class JdbcConfiguration {
@Autowired
private JdbcProperties jdbcProperties;
@Bean//这里只是为了演示,实际上应该用该类构造一个连接池DataSource对象返回
public JdbcProperties jdbcProperties(){
return this.jdbcProperties;
}
}
第二种注入数据信息的方式,构造方法注入:
除了@EnableConfigurationProperties({JdbcProperties.class})+@Autowired,如果配置类提供一个方法参数为信息类的构造方法,也能够自动将信息类注入进来。
@Configuration
@EnableConfigurationProperties({JdbcProperties.class})//设置读取的自动注入类
public class JdbcConfiguration {
private JdbcProperties jdbcProperties;
public JdbcConfiguration(JdbcProperties jdbcProperties) {
this.jdbcProperties = jdbcProperties;
}
第三种注入方法,直接通过@bean方法的形参,也可以根据类型完成注入:
@Bean
public JdbcProperties jdbcProperties(JdbcProperties jdbcProperties){
return jdbcProperties;
}
注意,最常用,最简单的直接注入法:】
以上做法都是先读取一个数据类到配置中,实例化自己所需要的bean时,注入进去。实际上,springboot还提供一种方法,直接在bean方法上写注解@ConfigurationProperties(“spring.datasource”),实例化bean后,自动调用该bean的set方法进行注入。
这种方法最简单,但要求该bean具有set方法,如果该bean只能通过构造方法进行属性注入,建议采用第三种方式。
【各个模块配置和整合】
servlet配置】
server.port=8080
server.servlet.context-path=/mybatis
日志配置】
logging.level.org.springframework=error
springMVC配置】
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ # Locations of static resources
静态资源默认位置:META/resources;resources;static;public
spring.mvc.view.prefix= # Spring MVC view prefix.
spring.mvc.view.suffix= # Spring MVC view suffix.
视图解析器,使用模版时,模版thymeleaf会默认提供
/templates/;.html
使用jsp时,需要手动提供:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
<!-- 使用jsp引擎,springboot内置tomcat没有此依赖 -->
<dependency>
<groupId> org.apache.tomcat.embed</groupId>
<artifactId> tomcat-embed-jasper</artifactId>
<scope> provided</scope>
</dependency>
配置拦截器、转换器等:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
//添加自定义过滤器
public void addInterceptors(InterceptorRegistry registry) {
}
@Override
//添加自定义类型转换器
public void addFormatters(FormatterRegistry registry) {
}
}
数据库配置】
spring.datasource.url=jdbc:mysql:///test
spring.datasource.username=root
spring.datasource.password=JIANGkui1
注意,如果启动器中有spring-boot-starter-jdbc,就会使用hikari的连接池。
junit测试】
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SbMybatisApplication.class)
新版2.2.4直接使用@SpringBootTest一个注解,不需要写属性classes=和runwith也可以执行。
【整合mybatis】
maven:
<dependencies>
<dependency>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-starter-jdbc</artifactId>
</dependency>
<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.1</version>
</dependency>
<!–通用mapper–>
<dependency>
<groupId> tk.mybatis</groupId>
<artifactId> mapper-spring-boot-starter</artifactId>
<version> 2.1.5</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-configuration-processor</artifactId>
<optional> true</optional>
</dependency>
<dependency>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-starter-test</artifactId>
<scope> test</scope>
<exclusions>
<exclusion>
<groupId> org.junit.vintage</groupId>
<artifactId> junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
二、配置文件
mybatis.type-aliases-package=htyy/sb_mybatis.domain
mybatis.mapper-locations=classpath:htyy/sb_mybatis/dao/**/*.xml
三、接口需要使用注解说明,不需要再配置接口扫描,此处使用了通用mapper
@Mapper
@Repository
public interface IAccountDao extends tk.mybatis.mapper.common.Mapper<Account>
四、实体类 通用mapper的实体类需要使用jpa的注解进行id说明,否则不能识别主键,懒加载的属性需要在json中排除。
@Table
@JsonIgnoreProperties(value = {“handler”})
public class Account implements Serializable {
private static final long serialVersionUID = -179971926684471361L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
五、继续编写service和controller接口即可。
【集成springdatajpa】
1、依赖
<dependency>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-starter-data-jpa</artifactId>
</dependency>
2、配置文件
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=validate
因为spring默认使用了启动类的全包扫描,所以会自动扫描entity包和接口,这里需要注意的是,接口extends JpaRepository<> 的过程中,就会默认实例化放到容器中的,所以这里也会被启动类自动扫描到。
剩下的接口和实体类的配置都和普通jpa工程一样的。
【【jsp继承】】
<dependency>
<groupId> com.googlecode.rapid-framework</groupId>
<artifactId> rapid-core</artifactId>
<version> 4.0.5</version>
</dependency>
<%@ taglib prefix=“rapid” uri=“http://www.rapid-framework.org.cn/rapid” %>
父页面:
<rapid:block name=“content”> </rapid:block>
<rapid:block name=“foot”> </rapid:block>
子页面:
<rapid:override name=“content”>
这是内容
</rapid:override>
<%@ include file=“base.jsp”%>
【【maven配置tomocat】】
<build>
<resources>
<resource>
<directory> src/main/java</directory>
<includes>
<include> **/.xml</include>
</includes>
</resource>
<resource>
<directory> src/main/resources</directory>
<includes>
<include> **/.xml</include>
<include> **/*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-compiler-plugin</artifactId>
<version> 3.1</version>
<configuration>
<source> 1.8</source>
<target> 1.8</target>
<encoding> UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId> org.apache.tomcat.maven</groupId>
<artifactId> tomcat7-maven-plugin</artifactId>
<version> 2.2</version>
<configuration>
<server> tomcat7</server>
<port> 8080</port>
<uriEncoding> utf-8</uriEncoding>
<path> /AttendanceSystem</path>
</configuration>
</plugin>
</plugins>
</build>
【【svn】】
1、打分支
checkout之后,在当前文件夹右键创建分支,topath中写分支路径和名称。
分支的定义规则:projectname+日期时间+功能点
tag的规则:projectname+版本号。版本号为三段数字xx.xx.xx,第一个为主版本号,第二个新功能版号,第三个修正bug。
2、idea操作
1、上传文件后,在settings-editor-file types中增加*.idea;*.iml;
2、version control-ignore files中增加 test文件夹位置。
3、检出文件时,文件是不带项目外层目录的,无论是主干还是分支,请都在外层新建一个统一名称的目录。
【【pagehelper】】
<dependency>
<groupId> com.github.pagehelper</groupId>
<artifactId> pagehelper</artifactId>
<version> 5.1.2</version>
</dependency>
使用注册:
1、mybatis主配置文件:
<plugins>
<plugin interceptor=“com.github.pagehelper.PageInterceptor”>
<property name=“helperDialect” value=“mysql”/>
<property name=“reasonable” value=“true”> </property>
</plugin>
</plugins>
2、spring整合mybatis
<property name=“plugins”>
<array>
<bean class=“com.github.pagehelper.PageInterceptor”>
<property name=“properties”>
<props>
<prop key=“helperDialect”> mysql</prop>
<prop key=“reasonable”> true</prop>
</props>
</property>
</bean>
</array>
</property>
3、分页插件参数介绍
helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012,否则会使用 SqlServer2005 的方式进行分页。
你也可以实现 AbstractHelperDialect,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。
offsetAsPageNum:默认值为 false,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为 true 时,会将 RowBounds 中的 offset 参数当成 pageNum 使用,可以用页码和页面大小两个参数进行分页。
rowBoundsWithCount:默认值为false,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为true时,使用 RowBounds 分页会进行 count 查询。
pageSizeZero:默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。
reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum> pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。
supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。
autoRuntimeDialect:默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页 (不支持自动选择sqlserver2012,只能使用sqlserver),用法和注意事项参考下面的场景五。
closeConn:默认值为 true。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,设置为 false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。
4、代码调用
pageHelper.startPage(pageNum:1,pageSize:5)
List<User> users=UserDao.findAll();
两句话写在一起即可。
PageInfo pageInfo=new PageInfo(users);
该bean的一些属性如下:
1、size 当前页数量
2、total 总记录数
3、pages 总页数
4、list 结果集
5、prepage 前一页
6、nextpage
注意,pageinfo.list并不是list<bean> 类型,而是一个page类型的lsit,因此print它并不会打印list信息。但遍历它可以获取存储的子条目。
【【mybatis自动生成代码插件】】
<plugin>
<groupId> org.mybatis.generator</groupId>
<artifactId> mybatis-generator-maven-plugin</artifactId>
<version> 1.3.2</version>
<dependencies>
<dependency>
<groupId> mysql</groupId>
<artifactId> mysql-connector-java</artifactId>
<version> 8.0.13</version>
</dependency>
</dependencies>
<configuration>
<configurationFile> src/main/resources/generatorConfig.xml </configurationFile>
<verbose> true</verbose>
<overwrite> true</overwrite>
</configuration>
</plugin>
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE generatorConfiguration
PUBLIC “-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN”
“http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd”>
<generatorConfiguration>
<context id=“mysqlgenerator” targetRuntime=“MyBatis3”>
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name=“suppressAllComments” value=“true” />
<property name=“enableSubPackages” value=“false”/>
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test"
userId="root"
password="JIANGkui1" >
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="htyy.vo" targetProject="src/main/java" >
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 targetPackage/targetProject:同javaModelGenerator
type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中;
3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER -->
<sqlMapGenerator targetPackage="htyy.dao" targetProject="src/main/java" />
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="MIXEDMAPPER" targetPackage="htyy.dao" targetProject="src/main/java" />
<!-- 指定数据库表 -->
<table tableName="account"
enableCountByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
enableUpdateByExample="false">
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>