Maven:
Maven生命周期:
1、clean(清理):把打好的包清理掉
2、package(打包):采用编译的代码,进行打包。
3、compile(编译):编译源代码。编译的是src\main\java
4、install(安装):将打包的jar/war安装到本地仓库
5、test(测试):执行src/test/java的测试用例
6、validate(验证):验证项目是否正确,所有必要的信息可用
7、deploy(部署):在构建环境中完成,将最终的包复制到远程存储库和其他的开发人员共享
8、site(站点):生成项目报告,站点,发布站点
每一个依赖(jar包)都一定有它的gav坐标
G:groupid(组名)
A:artifactied(项目名)
V:version(版本)
scope:依赖的生效范围
1、compile:编译范围。此依赖在编译,测试,运行三种状态都有效。默认的范围。
2、runtime:运行范围。只对测试和运行状态生效,不对编译状态生效
3、test:测试范围。只对test模块下生效
4、provided:已提供范围。只对编译和测试有效,不参与运行。
依赖传递:
jar也是别人写的项目,他也会依赖于其他的jar包,传递性让我们可以不用关心我们所依赖的jar包依赖了哪些jar包,统统拿进来。
依赖传递就近原则:(最短路径优先原则)
如果A依赖于B,B依赖于C,A也依赖于C,最终以A依赖的C为准。
mybaits的优点和缺点:
1、sql语句与代码分离。写在xml里
优点:便于维护和管理,不在java代码中找这些语句
缺点:JDBC可以用打断点的方式调试,但是Mybatis不能。
2、用逻辑标签来控制动态SQL
优点:动态拼接SQL语句
缺点:拼接复杂的SQL,没有直接写SQL要灵活
3、查询结果与java对象自动封装
前提:保证名称相同,名称是查询结果的虚拟表的名称。
缺点:对开发人员的SQL依赖很强
写一个查询方法:
第一次使用Mybatis,需要有两个核心文件
1、一个接口类(就是咱们以前写的dao接口),不需要有实现类。UserMapper
2、一个与接口类对应的xml文件,映射文件
3、规范是这个接口和这个映射文件的名字相同
4、框架根据mapper和xml联合,形成代理对象
笔记:
1.通过mybatis返回多条数据:
接口:List<User> userSelectAll();
UserMapper.xml配置:
resultType:返回类型,写实体类的路径
<select id="userSelectAll" resultType="com.crx.entity.User"> select id,sname,age,sex from user </select>
测试执行:
@Test public void userSelectAll(){ List<User> users = mapper.userSelectAll(); for(User use:users){ System.out.println(use); } }
2.mybatis模糊查询:
Mybatis的映射文件中#和$的区别: 1、Statement和PreparedStatement区别是一样 2、#代表使用的底层是PreparedStatement。占位符的写法,预加载 3、$代表使用的底层是Statement。字符串的拼接的写法。SQL注入
SQL注入:可以通过字符串的拼接,拼接出恒成立的sql语句
select id,sname,age,sex from user where sname like '%a%'
%:任意字符 _:占位符
接口:List<User> selectUserByUsername(String sname);
UserMapper.xml:
<select id="selectUserByUsername" resultType="com.crx.entity.User"> select id,sname,age,sex from user where sname like #{sname} </select>
测试运行:
public void selectUserByUsername(){ String sname = "a"; if(sname != null && !"".equals(sname.trim())){ sname = "%" + sname + "%"; }else{ sname = "%%"; } List<User> users = mapper.selectUserByUsername(sname); for(User user : users){ System.out.println(user); } }
3.动态标签
where if 的使用:
接口:List<User> selectUsers(User user);
UserMapper.xml:
<select id="selectUsers" resultType="com.crx.entity.User"> select id,sname,age,sex from user <where> <if test="id != null"> and id = #{id} </if> <if test="sname != null"> and sname = #{sname} </if> <if test="age != null"> and age = #{age} </if> <if test="sex != null"> and sex = #{sex} </if> </where> </select>
测试运行:
@Test public void selectUsers(){ List<User> users = mapper.selectUsers(new User(null, null, null, "男")); for (User user: users) { System.out.println(user); } }
choose when otherwise的使用:
接口:List<User> selectUsers2(User user);
UserMapper.xml:
<select id="selectUsers2" resultType="com.crx.entity.User"> select id,sname,age,sex from user <where> <choose> <when test="id !=null"> and id = #{id} </when> <when test="sname != null"> and sname = #{sname} </when> <when test="age != null"> and age = #{age} </when> <otherwise> and sex = #{sex} </otherwise> </choose> </where> </select>
测试运行:
//choose when otherwise 的使用 @Test public void selectUsers2(){ List<User> users = mapper.selectUsers2(new User(7, "你的名字", 12, "男")); for(User user : users){ System.out.println(user); } }
trim标签的使用:
接口:
List<User> selectTrim(User user);
UserMapper.xml:
<select id="selectTrim" resultType="com.crx.entity.User"> select id,sname,age,sex from user <trim prefix="where" prefixOverrides="and"> <if test="id!=null"> and id = #{id} </if> <if test="sname != null"> and sname = #{sname} </if> <if test="age != null"> and age = #{age} </if> </trim> </select>
测试:
//trim @Test public void selectTrim(){ List<User> users = mapper.selectTrim(new User(4, null, null, null)); for(User user : users){ System.out.println(user); } }
修改标签set的使用:
接口:
int updateUsers(User user);
UserMapper.xml:
<update id="updateUsers" parameterType="com.crx.entity.User"> update user <set> <if test="sname != null"> ,sname = #{sname} </if> <if test="age != null"> ,age = #{age} </if> <if test="sex != null"> ,sex = #{sex} </if> where id = #{id} </set> </update>
测试:
//set public void updateUsers(){ mapper.updateUsers(new User(4,"我",null,"男")); session.commit(); }
in() 查询标签测试:
接口:List<User> selectUsersByIds(@Param("ids") List<Integer> ids);
UserMapper.xml:
<select id="selectUsersByIds" resultType="com.crx.entity.User"> select id,sname,age,sex from user where id in <foreach collection="ids" open="(" close=")" separator="," item="id"> #{id} </foreach> </select>
测试:
@Test //in public void selectUsersByIds(){ List<User> users = mapper.selectUsersByIds(Arrays.asList(4, 6, 7)); for(User user:users){ System.out.println(user); } }
sql片段:
<sql id="usersql"> select id,sname,age,sex from user </sql>
引用:
<include refid="useful"></include>
多个参数:
User selectUsersPar(@Param("sname") String sname , @Param("age") String age);
<select id="selectUsersPar" resultType="com.crx.entity.User"> <include refid="useful"></include> where sname = #{sname} and age = #{age} </select>
@Test public void selectUsersPar(){ User user = mapper.selectUsersPar("我", "122"); System.out.println(user); }
Aliases修改别名:
typeAliases: <typeAliases> <typeAlias type="com.crx.entity.User" alias="user"></typeAlias> <package name="com.crx.entity"/> </typeAliases>
1.更改数据库连接池
ctrl+shift+alt+左键:多行编辑
使用druid连接池的步骤:
1.更改type里面的内容:
2.更改4个基本属性
自己配置druid连接池:
type指向自己的类:
2.数据库及java字段命名规则:
数据库的表名:如果是多个单词,,字段名,如果是多个单词,,例如:create_time。
Java规范:驼峰,变量,如果是多个单词,createTime
在mybatis-config.xml中配置字段自动映射:
mapUnderscoreToCamelCase:
是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
3.日志
用来记录和项目相关的信息。报错信息。
log4j,log4j2。logback-->slf4j
日志级别:从小到大 debug < info < warn < error < off
开启日志:
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
实体类要求:
/**
-
Java实体类的要求
-
entity要求:
-
1、所有的属性私有
-
2、提供共有的set,get方法
-
3、必须有无参构造器,如果有必要的话,提供其余构造器
-
4、实现序列化接口
-
5、添加hashCode和equals方法
-
6、不能有普通的成员方法
-
*/
4.多表查询
一对一:
方法一:------------------------------------------------------------------------------------------
思想步骤:
1.根据需求,判断时一对多查询还是多对多查询,先创建接口
2.编写mapper.xml的文件配置:
先写多表联查语句,确定查询结果,之后编写resultMap文件,进行别名的配置,id为主键,result为剩余字 段名配置,使用association和javaType
创建接口:
//根据主键查询员工信息,并且带有他所在的部门的信息 Employee selectEmployeeById(Integer id);
EmployeeMapper.xml的配置:
<resultMap id="EmployeeResult" type="employee"> <id property="id" column="eid"></id> <result property="name" column="ename"></result> <result property="gender" column="gender"></result> <result property="email" column="email"></result> <association property="dept" javaType="dept"> <id property="id" column="did"></id> <id property="name" column="dname"></id> </association> </resultMap> <select id="selectEmployeeById" resultMap="EmployeeResult"> select e.id eid,e.name ename,e.gender,e.email,e.did,d.name dname from employee e LEFT join dept d on e.did = d.id where e.id = #{id} </select>
进行测试:
@Test public void selectEmployeeById(){ Employee employee = mapper.selectEmployeeById(1); System.out.println(employee); }
方法二:分布式查询------------------------------------------------------------------------------------------
创建接口:
思想步骤:
1.先写主要查询对象的sql语句,编写resultMap,在association里配置新的select,column
2.在编写新的select语句
//根据主键查询员工信息,并且带有他所在的部门的信息 Employee selectEmployeeById(Integer id);
EmployeeMapper.xml的配置:
<resultMap id="EmployeeResult" type="employee"> <id property="id" column="eid"></id> <result property="name" column="ename"></result> <result property="gender" column="gender"></result> <result property="email" column="email"></result> <association property="dept" javaType="dept" select="fidDeptById" column="did"></association> </resultMap> <select id="fidDeptById" resultType="dept"> select id,name from dept where id = #{id} </select> <select id="selectEmployeeById" resultMap="EmployeeResult"> select id eid,name ename,gender,email,did from employee where id = #{id} </select>
进行测试:
@Test public void selectEmployeeById(){ Employee employee = mapper.selectEmployeeById(1); System.out.println(employee); }
一对多:
方法一:------------------------------------------------------------------------------------------
接口:
//查询所有部门对应的员工的所有信息 List<Dept> selectDeptById();
DeptMapper.xml的配置:
<resultMap id="DeptResult" type="dept"> <id property="id" column="id"></id> <result property="name" column="name"></result> <collection property="employees" ofType="employee"> <id column="eid" property="id"></id> <result column="ename" property="name"></result> <result column="gender" property="gender"></result> <result column="email" property="email"></result> </collection> </resultMap> <select id="selectDeptById" resultMap="DeptResult"> select d.id,d.name,e.id eid,e.name ename,e.gender,e.email from dept d left join employee e on d.id = e.did </select>
测试代码:
@Test public void EmployeeResult(){ List<Dept> depts = mapper.selectDeptById(); System.out.println(depts); }
方法二:分布式------------------------------------------------------------------------------------------
接口:
//查询所有部门对应的员工的所有信息 List<Dept> selectDeptById();
DeptMapper.xml的配置:
<resultMap id="DeptResult" type="dept"> <id property="id" column="id"></id> <result property="name" column="name"></result> <collection property="employees" ofType="employee" select="selectEmployeeByDid" column="id"></collection> </resultMap> <select id="selectEmployeeByDid" resultType="employee"> select id,name,gender,email from employee where did = #{id} </select> <select id="selectDeptById" resultMap="DeptResult"> select id,name from dept </select>
测试代码:
@Test public void EmployeeResult(){ List<Dept> depts = mapper.selectDeptById(); System.out.println(depts); }
5.缓存
一级缓存:(sqlSession级别的缓存)
默认就是开启的状态!第一次发起查询操作时,先去一级缓存中看有没有数据,如果没有,会发送sql语句查询数据库,当结果返回成功,会把结果放进一级缓存。快,减轻数据库的压力。
一级缓存的失效的情况: 1、sqlSession不同 2、sqlSession相同,查询的数据不同 3、两次查询之间进行了增删改的操作 4、手动清理缓存
二级缓存:
Mapper级别的缓存(默认关闭)
开启二级缓存:
<settings> <setting name="cacheEnabled" value="true"/> </settings>
之后在对应的mapper.xml中配置开启二级缓存:
<cache eviction="LRU" flushInterval="10000"></cache>
使用时在测试代码中关闭session:
session.close();
之后数据才能进入二级缓存
指定方法是否进入到二级缓存:
useCache="false"
此方法的数据不进入二级缓存
6.延迟加载:
默认关闭,需手动开启:
<settings> <setting name="lazyLoadingEnabled" value="true"/> </settings>
查询时,根据需求,来执行sql语句,可以节约资源