0%

Java Web项目实战-三

DataBaseUtils 数据库工具类(续上)

使用完数据库后要关闭连接,释放资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 关闭资源
* @param connection
* @param statement
* @param rs
*/
public static void closeConnection(Connection connection,PreparedStatement statement,ResultSet rs){
try {
if(rs!=null)rs.close();
if(statement!=null)statement.close();
if(connection!=null)connection.close();
} catch (Exception e) {
e.fillInStackTrace();
}
}
数据库操作(查改增删)

把各种操作的语句串封装为一个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* DML操作
* @param sql
* @param objects
*/
public static void update(String sql,Object...objects){
Connection connection = getConnection();
PreparedStatement statement = null;
try {
statement = (PreparedStatement) connection.prepareStatement(sql);
for (int i = 0; i < objects.length; i++) {
statement.setObject(i+1, objects[i]);
}
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
closeConnection(connection, statement, null);
}
}

测试
修改DatabaseUtil.java的Main方法

1
2
3
4
String id = UUID.randomUUID() + "";
String createTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
update("INSERT INTO t_user(id,username,password) "
+ "VALUES (?, ?, ?)", id,"张三",123456);

mysql> select * from t_user; 显示表中所有数据

然后 发现数据是有了,但是乱码啊,why?
mysql> show variables like “%char%”; 查一下数据库编码也全是utf8没错啊
打开MySQL根目录下的my.ini文件里面的配置也是utf8
算了,先不管它,毕竟理论上取出来的数据还会是原来的样子
研究了一下,估计是控制台不支持utf8编码,改起来可能比较麻烦,后面暂时就不用中文数据了

几种查询返回方法

queryForList&&queryForMap

理论上讲这两个东西常见的框架里面是有的,只是我还不太会用框架,关于框架的东西之后会再单独拿出来写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* 查询出数据,并且list返回
* @param sql
* @param objects
* @return
* @throws SQLException
*/
public static List<Map<String,Object>> queryForList(String sql,Object...objects){
List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
Connection connection = getConnection();
PreparedStatement statement = null;
ResultSet rs = null;
try {
statement = connection.prepareStatement(sql);
for (int i = 0; i < objects.length; i++) {
statement.setObject(i+1, objects[i]);
}

rs = statement.executeQuery();
while(rs.next()){
ResultSetMetaData resultSetMetaData = rs.getMetaData();
int count = resultSetMetaData.getColumnCount(); //获取列数
Map<String,Object> map = new HashMap<String, Object>();
for (int i = 0; i < count; i++) {
map.put(resultSetMetaData.getColumnName(i+1), rs.getObject(resultSetMetaData.getColumnName(i+1)));
}
result.add(map);
};
} catch (SQLException e) {
e.printStackTrace();
}finally{
closeConnection(connection, statement, rs);
}

return result;
}

/**
* 查询出数据,并且map返回
* @param sql
* @param objects
* @return
* @throws SQLException
*/
public static Map<String,Object> queryForMap(String sql,Object...objects) throws SQLException{
Map<String,Object> result = new HashMap<String,Object>();
List<Map<String,Object>> list = queryForList(sql, objects);
if(list.size() != 1){
return null;
}
result = list.get(0);
return result;
}

测试

1
2
3
DataBaseUtils.config("jdbc.properties");
List list = DataBaseUtils.queryForList("select * from t_user");
System.out.println(list);

queryForBean

把从数据库取到的数据转化为一个Java bean也即Java对象
具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* 查询出数据,并且返回一个JavaBean
* @param sql
* @param clazz
* @param objects
* @return
* @throws NoSuchFieldException
* @throws SecurityException
*/
public static <T>T queryForBean(String sql,Class clazz,Object...objects){
T obj = null;
Map<String,Object> map = null;
Field field = null;
try {
obj = (T) clazz.newInstance(); //创建一个新的Bean实例
map = queryForMap(sql, objects); //先将结果集放在一个Map中
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
if(map == null){
return null;
}
//遍历Map
for (String columnName : map.keySet()) {
Method method = null;
String propertyName = StringUtils.columnToProperty(columnName); //属性名称

try {
field = clazz.getDeclaredField(propertyName);
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
}
//获取JavaBean中的字段
String fieldType = field.toString().split(" ")[1]; //获取该字段的类型
//System.out.println(fieldType);
Object value = map.get(columnName);
if(value == null){
continue;
}
/**获取set方法的名字* */
String setMethodName = "set" + StringUtils.upperCaseFirstCharacter(propertyName);
//System.out.println(setMethodName);
try {
/**获取值的类型* */
String valueType = value.getClass().getName();

/**查看类型是否匹配* */
if(!fieldType.equalsIgnoreCase(valueType)){
//System.out.println("类型不匹配");
if(fieldType.equalsIgnoreCase("java.lang.Integer")){
value = Integer.parseInt(String.valueOf(value));
}else if(fieldType.equalsIgnoreCase("java.lang.String")){
value = String.valueOf(value);
}else if(fieldType.equalsIgnoreCase("java.util.Date")){
valueType = "java.util.Date";
//将value转换成java.util.Date
String dateStr = String.valueOf(value);
Timestamp ts = Timestamp.valueOf(dateStr);
Date date = new Date(ts.getTime());
value = date;
}
}

/**获取set方法* */
//System.out.println(valueType);
method = clazz.getDeclaredMethod(setMethodName,Class.forName(fieldType));
/**执行set方法* */
method.invoke(obj, value);
}catch(Exception e){
e.printStackTrace();
/**如果报错,基本上是因为类型不匹配* */
}
}
//System.out.println(obj);
return obj;
}

代码有点复杂,主要运用了Java的反射机制和泛型,通过反射来得到set方法,具体参考 @剽悍一小兔 的博客http://www.cnblogs.com/skyblue-li/p/5933571.html

controller和service

DataBaseUtil工具类就暂时告一段落,有需要再增加其他的方法
接下来完善一下loginController
导入对应的包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<%@ page language="java" import="java.util.*,service.LoginService,util.StringUtils,bean.*" pageEncoding="UTF-8"%>


<%
//设置请求的编码
//request.setCharacterEncoding("UTF-8");
//获取客户端传递过来参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//System.out.println(username);
//System.out.println(password);
//如果用户名和密码不为空
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
out.print("-1");//错误码-1 : 用户名和密码不能为空!
}else{
//初始化LoginService
LoginService loginService = new LoginService();
//接下来判断用户名是否存在
User user = loginService.getUser(username);
if(user == null){
out.print("-2");//错误码-2 : 用户名不存在!
}else
//如果用户名存在,那么验证用户名和密码是否匹配
if(!username.equals(user.getUsername()) || !password.equals(user.getPassword())){
out.print("-3");//错误码-3 : 用户名或密码错误!
}else{
//如果能到这一步,就说明用户的确存在,而且账号密码也正确。那么就把user放在session中
out.print("1");
session.setAttribute("user", user);
session.setAttribute("username", user.getUsername());
}
}

%>

其中StringUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package util;
public class StringUtils {
/**
* 判断字符串是否为空
* @param str
* @return
*/
public static boolean isEmpty(String str) {
return null == str || str.equals("")
|| str.matches("\\s*");
}
/**
* 给输入的字符串设置默认值
* @param content
* @param defaultValue
* @return
*/
public static String defaultValue(String content,String defaultValue){
if(isEmpty(content)){
return defaultValue;
}
return content;
}

/**
* 把数据库字段名改为驼峰方式
* @param column
* @return
*/
public static String columnToProperty(String column) {
/**如果字段名为空,就返回空字符串* */
if(isEmpty(column)) return "";
/**获取字段的长度,一般来说字段长度不可能有几百个字节的,所以用Byte就行了* */
Byte length = (byte) column.length();

StringBuilder sb = new StringBuilder(length);
int i = 0;
/**遍历字段的每一个字符* */
for (int j = 0; j < length; j++) {
/**匹配到第一个_* */
if (column.charAt(j) == '_') {
/**如果后面还有_,也就是连续的_,那么j就需要自增一个单位,直到后面不是_为止* */
while (column.charAt(j + 1) == '_') {
j += 1;
}
sb.append(("" + column.charAt(++j)).toUpperCase());

} else {
/**如果循环到的字符不是_,那么就保存下来* */
sb.append(column.charAt(j));
}
}

return sb.toString();
}

/**
* 将一个字符串的首字母改成大写
* @param str
* @return
*/
public static String upperCaseFirstCharacter(String str){
StringBuilder sb = new StringBuilder();
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
if(i==0) sb.append((arr[i] + "").toUpperCase());
else sb.append((arr[i]+""));
}
return sb.toString();
}

}

LoginService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package service;
import bean.User;
import util.DataBaseUtils;
/**
* 用户登录的服务类
* @author lenovo
*
*/
public class LoginService {

public User getUser(String username){
String sql = "select * from t_user where username = ?";
User user = DataBaseUtils.queryForBean(sql, User.class, username);
if(user == null){
return null;
}
//System.out.println(user);
return user;
}

}

login.jsp逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<script>

function login(){
var username = $('#username').val();
var password = $('#password').val();
$.ajax({
type:"post",//请求方式
url:"${basePath}/controller/loginController.jsp",//请求地址
data:{"username":username,"password":password},//传递给controller的json数据
error:function(){//如果出错了,将事件重新绑定
alert("登陆出错!");
},
success:function(data){ //返回成功执行回调函数。
if(data == -1){
alert('用户名和密码不能为空!');
}else if(data == -2){
alert('用户名不存在!');
}else if(data == -3){
alert('用户名或密码错误!');
}else{
//登录成功后返回首页
window.location.href = "${basePath}";
}
}
});


}

</script>

测试一下又出了问题,无论用户密码正确与否,都回调error
具体原因我研究研究