哎,学不下去了,明天再来吧
于2018-10-29-19:22 …
第二天
打开工程一看,东西有点多哦
添加依赖
数据源配置
在src/main/resources/application.properties中
spring.datasource.url = jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
url属性中,spring?useUnicode=true&characterEncoding=utf-8意思我是明白,格式记住吧,底层又是啥机制哦?
还可以自定义数据源呢
spring-boot-starter-jdbc默认tomcat-jdbc数据源,听说还有$(BABA)的数据源?还有该数据池管理的依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.19</version>
</dependency>
然后要用这个数据库连接池,还要在修改入口类Application.java。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private Environment env;
//destroy-method="close"的作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名
dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setInitialSize(2);//初始化时建立物理连接的个数
dataSource.setMaxActive(20);//最大连接池数量
dataSource.setMinIdle(0);//最小连接池数量
dataSource.setMaxWait(60000);//获取连接时最大等待时间,单位毫秒。
dataSource.setValidationQuery("SELECT 1");//用来检测连接是否有效的sql
dataSource.setTestOnBorrow(false);//申请连接时执行validationQuery检测连接是否有效
dataSource.setTestWhileIdle(true);//建议配置为true,不影响性能,并且保证安全性。
dataSource.setPoolPreparedStatements(false);//是否缓存preparedStatement,也就是PSCache
return dataSource;
}
}
可以看到,要调用application.properties里的参数时,
首先:注入一个环境变量,
@Autowired
private Environment env;
然后调用env的getProperty(“参数名称”)方法即可。
然后Spring Boot就会自动配置一个DataSource实例。
脚步初始化
所以什么叫脚步初始化 ,我只看到创建数据库,创建数据表,创建记录,这就叫脚本初始化了吗???然后把这个文件命名为了xx.sql,所以可能对于数据库的脚本初始化就是这样的?这样就不用手动到命令行敲键盘了。
正式开始使用Jdbc
现在都不用jdbc了吧,诶…
1、domain层就不用说了吧
2、dao层
这个要和service层一起看。
为了实现dao和service的隔离,所以在两个层新建了同样的接口;
然后在serviceImpl实现类实现时,注入dao接口,里面的实现类方法其实只是调用了dao接口里的方法。像下面这样:
@Autowired
LearnDao learnDao;
@Override
public int add(LearnResouce learnResouce) {
return this.learnDao.add(learnResouce);
}
然后这里我的理解是:Spring会因为这个serviceImpl实现类的后缀,识别为实现类,所以里面虽然注入的是dao接口,但是会自动匹配到接口的实现:daoImpl实现类的方法。
所以高潮就来了,下面上daoImpl.java类实现JdbcTemplate的代码:
@Repository
public class LearnDaoImpl implements LearnDao{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public int add(LearnResouce learnResouce) {
return jdbcTemplate.update("insert into learn_resource(author, title,url) values(?, ?, ?)",learnResouce.getAuthor(),learnResouce.getTitle(),learnResouce.getUrl());
}
@Override
public int update(LearnResouce learnResouce) {
return jdbcTemplate.update("update learn_resource set author=?,title=?,url=? where id = ?",new Object[]{learnResouce.getAuthor(),learnResouce.getTitle(),learnResouce.getUrl(),learnResouce.getId()});
}
@Override
public int deleteByIds(String ids){
return jdbcTemplate.update("delete from learn_resource where id in("+ids+")");
}
@Override
public LearnResouce queryLearnResouceById(Long id) {
List<LearnResouce> list = jdbcTemplate.query("select * from learn_resource where id = ?", new Object[]{id}, new BeanPropertyRowMapper(LearnResouce.class));
if(null != list && list.size()>0){
LearnResouce learnResouce = list.get(0);
return learnResouce;
}else{
return null;
}
}
@Override
public Page queryLearnResouceList(Map<String,Object> params) {
StringBuffer sql =new StringBuffer();
sql.append("select * from learn_resource where 1=1");
if(!StringUtil.isNull((String)params.get("author"))){
sql.append(" and author like '%").append((String)params.get("author")).append("%'");
}
if(!StringUtil.isNull((String)params.get("title"))){
sql.append(" and title like '%").append((String)params.get("title")).append("%'");
}
Page page = new Page(sql.toString(), Integer.parseInt(params.get("page").toString()), Integer.parseInt(params.get("rows").toString()), jdbcTemplate);
return page;
}
}
这里两个问题注意下:
1、@Repository是啥?
2、因为Spring的JdbcTemplate是自动配置的,所以只要@Autowired就可以了。
上面标亮的问题已解决:
@Repository用于持久层,@Controller用于控制层,@Service用于业务层;然后都是在类上标注,接口是没有见过标注的。标注之后,这些类,或者说Bean都会在ApplicationContext中注册。
然后@Component可以用在所有层。
那么现在在回顾入口类的@SpringBootApplication注解,其包含的注解@ComponentScan就会把上面四个注解标记的类(Bean)统统注入Spring的Ioc容器?,并注册到ApplicationContext上下文,就可以随时调用了。
那么问题又来了,@Bean又是干嘛的,在哪里用呢?
首先,@Bean是用在方法上的,并且方法所在的类在要是被上面四种注解标记了的,然后被标记的方法的id默认就是方法名称,当然也可以改,但是一般谁吃多了谁改吧。
因为是标记在方法上的,所以方法调用时,才会生成一个Bean对象,这样就可以动态获取Bean对象了,爽翻。
然后指定bean的@Scope。
然后看到这句话作何感想:@Configuration 中所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。
所以问题又来了,@Configuration和@Component又什么区别和联系呢?
掀开盖子一看,发现@Configuration本质上还是@Component:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
String value() default "";
}
所以也能被@ComponentScan扫描到,好了,盖子盖好,多的不想再挖了,头大。
什么同一个不同一个实例,下次遇到再研究研究吧。
3、Controller层
好咯,最恶心的来了。
首先,在Controller层注入service层的对象;跟service层注入dao层一样,也是注入service层的接口,而不是实现类。
@Autowired
private LearnService learnService;
private Logger logger = LoggerFactory.getLogger(this.getClass());
看了下,答大概明白了,跑一跑,哦了。
Reference:
[1]:http://tengj.top/2017/04/13/springboot8/